diff --git a/.appveyor.yml b/.appveyor.yml
index 6aa44f7a6..ceff95cf4 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -1,21 +1,24 @@
build: off
environment:
- PYTHON_VERSION: 3.7
+ PYTHON_VERSION: 3.8
MINICONDA: C:\\Miniconda37-x64
matrix:
+ - TEST_FILES: tests\test_orbit.py tests\test_orbits.py
+ ADDL_CONDA_PKGS: astropy astroquery
+ COMPILE_NOOPENMP:
+ BUILD_WHEELS: "true"
+
- TEST_FILES: "tests\\ --ignore=tests\\test_actionAngleTorus.py --ignore=tests\\test_snapshotpotential.py --ignore=tests\\test_qdf.py --ignore=tests\\test_pv2qdf.py --ignore=tests\\test_diskdf.py --ignore=tests\\test_orbit.py --ignore=tests\\test_orbits.py --ignore=tests\\test_streamdf.py --ignore=tests\\test_streamgapdf.py --ignore=tests\\test_evolveddiskdf.py --ignore=tests\\test_quantity.py --ignore=tests\\test_nemo.py --ignore=tests\\test_amuse.py --ignore=tests\\test_coords.py"
ADDL_CONDA_PKGS:
COMPILE_NOOPENMP:
-
- - TEST_FILES: tests\test_orbit.py tests\test_orbits.py
- ADDL_CONDA_PKGS: astropy astroquery
- COMPILE_NOOPENMP: "--no-openmp"
+ BUILD_WHEELS: "false"
- TEST_FILES: tests\test_quantity.py tests\test_coords.py
ADDL_CONDA_PKGS: astropy
COMPILE_NOOPENMP: "--no-openmp"
+ BUILD_WHEELS: "false"
platform:
- x64
@@ -42,3 +45,46 @@ install:
test_script:
- pytest -v %TEST_FILES% --cov galpy --cov-config .coveragerc_travis --disable-pytest-warnings
+
+after_test:
+ # Build wheels for different python versions of BUILD_WHEELS, otherwise done
+ - ps: |
+ if ($env:BUILD_WHEELS -eq "false") {
+ Exit-AppVeyorBuild
+ }
+ - conda deactivate
+ - conda remove --name test-environment --all
+ # Python 3.8
+ - conda create -n py38 python=3.8 numpy scipy matplotlib setuptools pip pytest gsl
+ - conda activate py38
+ - pip install wheel
+ - set INCLUDE=%CONDA_PREFIX%\Library\include;%INCLUDE%
+ - set LIB=%CONDA_PREFIX%\Library\lib;%LIB%
+ - set LIBPATH=%CONDA_PREFIX%\Library\lib;%LIBPATH%
+ - python setup.py bdist_wheel
+ - conda deactivate
+ # Python 3.7
+ - conda create -n py37 python=3.7 numpy scipy matplotlib setuptools pip pytest gsl
+ - conda activate py37
+ - conda remove --name py38 --all
+ - pip install wheel
+ - set INCLUDE=%CONDA_PREFIX%\Library\include;%INCLUDE%
+ - set LIB=%CONDA_PREFIX%\Library\lib;%LIB%
+ - set LIBPATH=%CONDA_PREFIX%\Library\lib;%LIBPATH%
+ - python setup.py bdist_wheel
+ - conda deactivate
+ # Python 3.6
+ - conda create -n py36 python=3.6 numpy scipy matplotlib setuptools pip pytest gsl
+ - conda activate py36
+ - conda remove --name py37 --all
+ - pip install wheel
+ - set INCLUDE=%CONDA_PREFIX%\Library\include;%INCLUDE%
+ - set LIB=%CONDA_PREFIX%\Library\lib;%LIB%
+ - set LIBPATH=%CONDA_PREFIX%\Library\lib;%LIBPATH%
+ - python setup.py bdist_wheel
+ - conda deactivate
+ # Upload as artifacts
+ - ps: |
+ if ($env:BUILD_WHEELS -eq "true") {
+ Get-ChildItem dist\*.whl | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
+ }
\ No newline at end of file
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 000000000..b8e0e862a
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,18 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 60
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 7
+# Issues with these labels will never be considered stale
+exemptLabels:
+ - pinned
+ - security
+# Label to use when marking an issue as stale
+staleLabel: wontfix
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. If the
+ issue has been resolved since the last activity, please close the issue.
+ Thank you for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 3e44f1268..91712e6f5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,15 @@
-dist: xenial
+dist: bionic
sudo: false
language: python
# Working towards support https://numpy.org/neps/nep-0029-deprecation_policy.html
python:
- - "3.7"
+ - "3.8"
env: #split tests
global:
- REQUIRES_PYNBODY=false
- REQUIRES_ASTROPY=false
- REQUIRES_ASTROQUERY=false
- - PYTHON_COVREPORTS_VERSION=3.7 # Version for which reports are uploaded
+ - PYTHON_COVREPORTS_VERSION=3.8 # Version for which reports are uploaded
matrix:
- TEST_FILES='tests/ --ignore=tests/test_qdf.py --ignore=tests/test_pv2qdf.py --ignore=tests/test_diskdf.py --ignore=tests/test_orbit.py --ignore=tests/test_streamdf.py --ignore=tests/test_streamgapdf.py --ignore=tests/test_evolveddiskdf.py --ignore=tests/test_quantity.py --ignore=tests/test_nemo.py --ignore=tests/test_amuse.py --ignore=tests/test_coords.py --ignore=tests/test_jeans.py --ignore=tests/test_orbits.py' REQUIRES_PYNBODY=true
- TEST_FILES='tests/test_quantity.py tests/test_coords.py' REQUIRES_ASTROPY=true # needs to be separate for different config
@@ -18,12 +18,14 @@ env: #split tests
- TEST_FILES='tests/test_diskdf.py'
- TEST_FILES='tests/test_qdf.py tests/test_pv2qdf.py tests/test_streamgapdf.py'
- TEST_FILES='tests/test_streamdf.py'
-matrix: # only run crucial tests for python 2.7, 3.6
+matrix: # only run crucial tests for python 2.7, 3.6, 3.7
include:
- python: "2.7"
env: TEST_FILES='tests/test_orbit.py tests/test_orbits.py' REQUIRES_PYNBODY=true REQUIRES_ASTROPY=true REQUIRES_ASTROQUERY=true
- python: "3.6"
env: TEST_FILES='tests/test_orbit.py tests/test_orbits.py' REQUIRES_PYNBODY=true REQUIRES_ASTROPY=true REQUIRES_ASTROQUERY=true
+ - python: "3.7"
+ env: TEST_FILES='tests/test_orbit.py tests/test_orbits.py' REQUIRES_PYNBODY=true REQUIRES_ASTROPY=true REQUIRES_ASTROQUERY=true
addons:
apt:
packages:
@@ -49,7 +51,9 @@ before_install:
- conda config --set always_yes yes --set changeps1 no
- conda update conda
- conda config --add channels conda-forge
- - conda create -n test-environment python=$TRAVIS_PYTHON_VERSION "numpy>=1.16" scipy matplotlib numexpr setuptools pip "cython>=0.20" pytest
+# setuptools >= 45 no longer supports Python 2
+ - if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then SETUPTOOLS_VERSION="<45"; else SETUPTOOLS_VERSION=""; fi
+ - conda create -n test-environment python=$TRAVIS_PYTHON_VERSION "numpy>=1.16" scipy matplotlib numexpr "setuptools$SETUPTOOLS_VERSION" pip "cython>=0.20" pytest
- source activate test-environment
#Switch to conda defaults python, because conda-forge python has issues with gcc compiler similar to https://github.com/conda/conda/issues/6030
- conda install python=$TRAVIS_PYTHON_VERSION -c defaults
diff --git a/MANIFEST.in b/MANIFEST.in
index 1f4065e14..64f70a5b9 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
-include README.rst README.dev README.nemo LICENSE HISTORY.txt AUTHORS.txt
+include README.md README.dev README.nemo LICENSE HISTORY.txt AUTHORS.txt
include gsl-config.bat
include galpy/df/data/*.sav
include galpy/orbit/named_objects.json
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..5c362b587
--- /dev/null
+++ b/README.md
@@ -0,0 +1,99 @@
+
+
+ Galactic Dynamics in python
+
+
+[galpy](http://www.galpy.org) is a Python 2 and 3 package for galactic dynamics. It supports orbit integration in a variety of potentials, evaluating and sampling various distribution functions, and the calculation of action-angle coordinates for all static potentials. `galpy` is an [astropy](http://www.astropy.org/) [affiliated package](http://www.astropy.org/affiliated/) and provides full support for astropy’s [Quantity](http://docs.astropy.org/en/stable/api/astropy.units.Quantity.html) framework for variables with units.
+
+[![image](https://travis-ci.org/jobovy/galpy.svg?branch=master)](http://travis-ci.org/jobovy/galpy) [![image](https://ci.appveyor.com/api/projects/status/wmgs1sq3i7tbtap2/branch/master?svg=true)](https://ci.appveyor.com/project/jobovy/galpy) [![image](https://img.shields.io/coveralls/jobovy/galpy.svg)](https://coveralls.io/r/jobovy/galpy?branch=master) [![image](http://codecov.io/github/jobovy/galpy/coverage.svg?branch=master)](http://codecov.io/github/jobovy/galpy?branch=master) [![image](https://readthedocs.org/projects/galpy/badge/?version=latest)](http://docs.galpy.org/en/latest/) [![image](http://img.shields.io/pypi/v/galpy.svg)](https://pypi.python.org/pypi/galpy/) [![image](https://anaconda.org/conda-forge/galpy/badges/installer/conda.svg)](https://anaconda.org/conda-forge/galpy) [![image](http://img.shields.io/badge/license-New%20BSD-brightgreen.svg)](https://github.com/jobovy/galpy/blob/master/LICENSE) [![image](http://img.shields.io/badge/DOI-10.1088/0067%2D%2D0049/216/2/29-blue.svg)](http://dx.doi.org/10.1088/0067-0049/216/2/29) [![image](http://img.shields.io/badge/powered%20by-AstroPy-orange.svg?style=flat)](http://www.astropy.org/) [![image](https://slackin-galpy.herokuapp.com/badge.svg)](https://galpy.slack.com/) [![image](https://img.shields.io/badge/join-slack-E01563.svg?style=flat&logo=slack&logoWidth=10)](https://slackin-galpy.herokuapp.com)
+
+AUTHOR
+======
+
+Jo Bovy - bovy at astro dot utoronto dot ca
+
+See
+[AUTHORS.txt](https://github.com/jobovy/galpy/blob/master/AUTHORS.txt)
+for a full list of contributors.
+
+If you find this code useful in your research, please let me know. **If
+you use galpy in a publication, please cite** [Bovy
+(2015)](http://adsabs.harvard.edu/abs/2015ApJS..216...29B) **and link to
+http://github.com/jobovy/galpy**. See [the acknowledgement documentation
+section](http://docs.galpy.org/en/latest/index.html#acknowledging-galpy)
+for a more detailed guide to citing parts of the code. Please also send
+me a reference to the paper or send a pull request including your paper
+in the list of galpy papers on [this
+page](http://docs.galpy.org/en/latest/) (this page is at
+doc/source/index.rst). Thanks!
+
+LOOKING FOR HELP?
+=================
+
+The latest documentation can be found
+[here](http://docs.galpy.org/en/latest/). You can also join the
+[galpy slack community](https://galpy.slack.com/) for any questions
+related to `galpy`; join
+[here](https://slackin-galpy.herokuapp.com).
+
+If you find *any* bug in the code, please report these using the [Issue
+Tracker](http://github.com/jobovy/galpy/issues) or by joining the [galpy
+slack community](https://galpy.slack.com/).
+
+If you are having issues with the installation of `galpy`, please first
+consult the [Installation
+FAQ](http://docs.galpy.org/en/latest/installation.html#installation-faq).
+
+PYTHON VERSIONS AND DEPENDENCIES
+================================
+
+`galpy` supports both Python 2 and 3. Specifically, galpy supports
+Python 2.7 and Python 3.6 and 3.7. It should also work on earlier Python
+3.\* versions, but this is not extensively tested on an ongoing basis.
+Travis CI builds regularly check support for Python 2.7 and 3.7 (and of
+3.6 using a more limited, core set of tests) and Appveyor builds
+regularly check support for Python 3.7 on Windows.
+
+This package requires [Numpy](https://numpy.org/),
+[Scipy](http://www.scipy.org/), and
+[Matplotlib](http://matplotlib.sourceforge.net/). Certain advanced
+features require the GNU Scientific Library
+([GSL](http://www.gnu.org/software/gsl/)), with action calculations
+requiring version 1.14 or higher. Use of `SnapshotRZPotential` and
+`InterpSnapshotRZPotential` requires
+[pynbody](https://github.com/pynbody/pynbody). Support for providing
+inputs and getting outputs as Quantities with units is provided through
+[astropy](http://www.astropy.org/).
+
+CONTRIBUTING TO GALPY
+=====================
+
+If you are interested in contributing to galpy\'s development, take a
+look at [this brief
+guide](https://github.com/jobovy/galpy/wiki/Guide-for-new-contributors)
+on the wiki. This will hopefully help you get started!
+
+Some further development notes can be found on the
+[wiki](http://github.com/jobovy/galpy/wiki/). This includes a list of
+small and larger extensions of galpy that would be useful
+[here](http://github.com/jobovy/galpy/wiki/Possible-galpy-extensions) as
+well as a longer-term roadmap
+[here](http://github.com/jobovy/galpy/wiki/Roadmap). Please let the main
+developer know if you need any help contributing!
+
+DISK DF CORRECTIONS
+===================
+
+The dehnendf and shudf disk distribution functions can be corrected to
+follow the desired surface-mass density and radial-velocity-dispersion
+profiles more closely (see
+[1999AJ\....118.1201D](http://adsabs.harvard.edu/abs/1999AJ....118.1201D)).
+Calculating these corrections is expensive, and a large set of
+precalculated corrections can be found
+[here](http://github.com/downloads/jobovy/galpy/galpy-dfcorrections.tar.gz)
+\[tar.gz archive\]. Install these by downloading them and unpacking them
+into the galpy/df/data directory before running the setup.py
+installation. E.g.:
+
+ curl -O https://github.s3.amazonaws.com/downloads/jobovy/galpy/galpy-dfcorrections.tar.gz
+ tar xvzf galpy-dfcorrections.tar.gz -C ./galpy/df/data/
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 47cc0b6cb..000000000
--- a/README.rst
+++ /dev/null
@@ -1,151 +0,0 @@
-galpy
-======
-
-**Galactic Dynamics in python**
-
-.. image:: https://travis-ci.org/jobovy/galpy.svg?branch=master
- :target: http://travis-ci.org/jobovy/galpy
-
-.. image:: https://ci.appveyor.com/api/projects/status/wmgs1sq3i7tbtap2/branch/master?svg=true
- :target: https://ci.appveyor.com/project/jobovy/galpy
-
-.. image:: https://img.shields.io/coveralls/jobovy/galpy.svg
- :target: https://coveralls.io/r/jobovy/galpy?branch=master
-
-.. image:: http://codecov.io/github/jobovy/galpy/coverage.svg?branch=master
- :target: http://codecov.io/github/jobovy/galpy?branch=master
-
-.. image:: https://readthedocs.org/projects/galpy/badge/?version=latest
- :target: http://galpy.readthedocs.io/en/latest/
-
-.. image:: http://img.shields.io/pypi/v/galpy.svg
- :target: https://pypi.python.org/pypi/galpy/
-
-.. image:: https://anaconda.org/conda-forge/galpy/badges/installer/conda.svg
- :target: https://anaconda.org/conda-forge/galpy
-
-.. image:: http://img.shields.io/badge/license-New%20BSD-brightgreen.svg
- :target: https://github.com/jobovy/galpy/blob/master/LICENSE
-
-.. image:: http://img.shields.io/badge/DOI-10.1088/0067%2D%2D0049/216/2/29-blue.svg
- :target: http://dx.doi.org/10.1088/0067-0049/216/2/29
-
-.. image:: http://img.shields.io/badge/powered%20by-AstroPy-orange.svg?style=flat
- :target: http://www.astropy.org/
-
-.. image:: https://slackin-galpy.herokuapp.com/badge.svg
- :target: https://galpy.slack.com/
-
-.. image:: https://img.shields.io/badge/join-slack-E01563.svg?style=flat&logo=slack&logoWidth=10
- :target: https://slackin-galpy.herokuapp.com
-
-AUTHOR
--------
-
-Jo Bovy - bovy at astro dot utoronto dot ca
-
-See `AUTHORS.txt
-`__ for a
-full list of contributors.
-
-If you find this code useful in your research, please let me
-know. **If you use galpy in a publication, please cite** `Bovy (2015)
-`__ **and link to
-http://github.com/jobovy/galpy**. See `the acknowledgement documentation section
-`__
-for a more detailed guide to citing parts of the code. Please also
-send me a reference to the paper or send a pull request including your
-paper in the list of galpy papers on `this page
-`__ (this page is at
-doc/source/index.rst). Thanks!
-
-
-LOOKING FOR HELP?
------------------
-
-The latest documentation can be found `here `__. You can also join the `galpy slack community `__ for any questions related to `galpy`; join `here `__.
-
-If you find *any* bug in the code, please report these using the `Issue Tracker `__ or by joining the `galpy slack community `__.
-
-If you are having issues with the installation of ``galpy``, please first consult the `Installation FAQ `__.
-
-PYTHON VERSIONS AND DEPENDENCIES
----------------------------------
-
-``galpy`` supports both Python 2 and 3. Specifically, galpy supports
-Python 2.7 and Python 3.6 and 3.7. It should also work on earlier
-Python 3.* versions, but this is not extensively tested on an ongoing
-basis. Travis CI builds regularly check support for Python 2.7 and 3.7
-(and of 3.6 using a more limited, core set of tests) and Appveyor
-builds regularly check support for Python 3.7 on Windows.
-
-This package requires `Numpy `__, `Scipy
-`__, and `Matplotlib
-`__. Certain advanced features
-require the GNU Scientific Library (`GSL
-`__), with action calculations
-requiring version 1.14 or higher. Use of ``SnapshotRZPotential`` and
-``InterpSnapshotRZPotential`` requires `pynbody
-`__. Support for providing inputs
-and getting outputs as Quantities with units is provided through
-`astropy `__.
-
-CONTRIBUTING TO GALPY
-----------------------
-
-If you are interested in contributing to galpy's development, take a look at `this brief guide `__ on the wiki. This will hopefully help you get started!
-
-Some further development notes can be found on the `wiki
-`__. This includes a list of
-small and larger extensions of galpy that would be useful `here
-`__ as
-well as a longer-term roadmap `here
-`__. Please let the main
-developer know if you need any help contributing!
-
-DETAILED BUILD, COVERAGE, AND DOCUMENTATION STATUS
----------------------------------------------------
-
-**master**:
-
-.. image:: https://travis-ci.org/jobovy/galpy.svg?branch=master
- :target: http://travis-ci.org/jobovy/galpy
-
-.. image:: https://img.shields.io/coveralls/jobovy/galpy.svg
- :target: https://coveralls.io/r/jobovy/galpy?branch=master
-
-.. image:: http://codecov.io/github/jobovy/galpy/coverage.svg?branch=master
- :target: http://codecov.io/github/jobovy/galpy?branch=master
-
-.. image:: https://readthedocs.org/projects/galpy/badge/?branch=master?version=latest
- :target: http://galpy.readthedocs.io/en/master/
-
-
-**development branch** (if it exists):
-
-.. image:: https://travis-ci.org/jobovy/galpy.svg?branch=dev
- :target: http://travis-ci.org/jobovy/galpy/branches
-
-.. image:: https://img.shields.io/coveralls/jobovy/galpy.svg?branch=dev
- :target: https://coveralls.io/r/jobovy/galpy?branch=dev
-
-.. image:: http://codecov.io/github/jobovy/galpy/coverage.svg?branch=dev
- :target: http://codecov.io/github/jobovy/galpy?branch=dev
-
-.. image:: https://readthedocs.org/projects/galpy/badge/?branch=master?version=latest
- :target: http://galpy.readthedocs.io/en/dev/
-
-DISK DF CORRECTIONS
---------------------
-
-The dehnendf and shudf disk distribution functions can be corrected to
-follow the desired surface-mass density and radial-velocity-dispersion
-profiles more closely (see `1999AJ....118.1201D
-`__). Calculating
-these corrections is expensive, and a large set of precalculated
-corrections can be found `here
-`__
-\[tar.gz archive\]. Install these by downloading them and unpacking them into the galpy/df/data directory before running the setup.py installation. E.g.::
-
- curl -O https://github.s3.amazonaws.com/downloads/jobovy/galpy/galpy-dfcorrections.tar.gz
- tar xvzf galpy-dfcorrections.tar.gz -C ./galpy/df/data/
diff --git a/RELEASE_CHECKLIST.md b/RELEASE_CHECKLIST.md
index 1cbd217eb..1c96cab40 100644
--- a/RELEASE_CHECKLIST.md
+++ b/RELEASE_CHECKLIST.md
@@ -24,11 +24,11 @@
- [ ] Push to testpypi: ``twine upload -r pypitest dist/*`` and can test with ``pip install -i https://testpypi.python.org/pypi galpy``
-- [ ] Push to pypi: ``twine upload -r pypi dist/*``
+- [ ] Download Windows wheels from AppVeyor from tagged build and put in ``dist/``.
-- [ ] Build wheels for different python versions: ``python setup.py bdist_wheel`` and upload with ``twine upload -r pypi dist/*.whl``
+- [ ] Build Mac wheels for different python versions and put in ``dist/``. (note that Linux wheels are not supported)
-- [ ] Create wheels for different python versions on other platforms and upload with ``twine upload dist/*.whl`` (note that Linux wheels are not supported)
+- [ ] Push to pypi: ``twine upload -r pypi dist/*``
- [ ] Create the new conda builds at conda-forge —> now done automatically by bot, but still need to check that builds run correctly (should start within about half an hour from pushing the new release to PyPI)
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 2781fe902..7a1ee7d3a 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -12,6 +12,7 @@
# serve to show the default.
import sys, os
+import datetime
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
@@ -22,7 +23,8 @@
# 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.mathjax','sphinx.ext.ifconfig']
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.mathjax','sphinx.ext.ifconfig',
+ 'sphinx.ext.viewcode']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -38,16 +40,16 @@
# General information about the project.
project = u'galpy'
-copyright = u'2010 - 2019, Jo Bovy'
+copyright = u'2010 - {}, Jo Bovy'.format(datetime.datetime.now().year)
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = '2.0'
+version = '1.6.0'
# The full version, including alpha/beta/rc tags.
-release = '2.0.dev'
+release = '1.6.0.dev'
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if on_rtd:
version= 'v'+version
@@ -120,7 +122,7 @@ def setup(app):
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
-html_logo = 'images/logo-small.png'
+html_logo = 'images/galpy-logo-small.gif'
# 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
diff --git a/doc/source/images/galpy-logo-small.gif b/doc/source/images/galpy-logo-small.gif
new file mode 100644
index 000000000..ea23b7c0d
Binary files /dev/null and b/doc/source/images/galpy-logo-small.gif differ
diff --git a/doc/source/images/galpy-logo-small.png b/doc/source/images/galpy-logo-small.png
new file mode 100644
index 000000000..82593b10f
Binary files /dev/null and b/doc/source/images/galpy-logo-small.png differ
diff --git a/doc/source/images/orbit-fromname-mwglobsorbits.png b/doc/source/images/orbit-fromname-mwglobsorbits.png
new file mode 100644
index 000000000..fa981d3f9
Binary files /dev/null and b/doc/source/images/orbit-fromname-mwglobsorbits.png differ
diff --git a/doc/source/images/orbit-fromname-mwsatsorbits.png b/doc/source/images/orbit-fromname-mwsatsorbits.png
new file mode 100644
index 000000000..80f652a0f
Binary files /dev/null and b/doc/source/images/orbit-fromname-mwsatsorbits.png differ
diff --git a/doc/source/images/orbit-fromname-solarsyst.png b/doc/source/images/orbit-fromname-solarsyst.png
new file mode 100644
index 000000000..3046cec20
Binary files /dev/null and b/doc/source/images/orbit-fromname-solarsyst.png differ
diff --git a/doc/source/index.rst b/doc/source/index.rst
index fb03786af..feb39bfac 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -10,13 +10,13 @@
Welcome to galpy's documentation
=================================
-galpy is a Python 2 and 3 package for galactic dynamics. It supports
-orbit integration in a variety of potentials, evaluating and sampling
-various distribution functions, and the calculation of action-angle
-coordinates for all static potentials. galpy is an `astropy
-`_ `affiliated package
-`_ and provides full support for
-astropy's `Quantity
+`galpy `__ is a Python 2 and 3 package for
+galactic dynamics. It supports orbit integration in a variety of
+potentials, evaluating and sampling various distribution functions,
+and the calculation of action-angle coordinates for all static
+potentials. galpy is an `astropy `_
+`affiliated package `_ and
+provides full support for astropy's `Quantity
`_
framework for variables with units.
@@ -547,6 +547,12 @@ The following is a list of publications using ``galpy``; please let me (bovy at
#. *Vilnius Photometry and Gaia Astrometry of Melotte 105*, Timothy Banks, Talar Yontan, Selcuk Bilir, & Remziye Canbay (2019) *J. Astron. Astrophys.*, in press (`arXiv/1912.08760 `_)
+#. *Evidence for Galactic disc RR~Lyrae stars in the Solar neighbourhood*, Z. Prudil, I. Dékány, E. K. Grebel, & A. Kunder (2020) *Mon. Not. Roy. Astron. Soc.*, in press (`arXiv/2001.02486 `_)
+
+#. *The Chemical Compositions of Accreted and in situ Galactic Globular Clusters According to SDSS/APOGEE*, Danny Horta, Ricardo P. Schiavon, J. Ted Mackereth, et al. (2020) *Mon. Not. Roy. Astron. Soc.*, submitted (`arXiv/2001.03177 `_)
+
+#. *Age dating of an early Milky Way merger via asteroseismology of the naked-eye star ν Indi*, William J. Chaplin, Aldo M. Serenelli, Andrea Miglio, et al. (2020) *Nature Astron.*, in press (`arXiv/2001.04653 `_)
+
Indices and tables
==================
diff --git a/doc/source/installation.rst b/doc/source/installation.rst
index 595bed6aa..01651bb32 100644
--- a/doc/source/installation.rst
+++ b/doc/source/installation.rst
@@ -88,6 +88,9 @@ to, for example, install the ``dev`` branch.
Installing from source on Windows
---------------------------------
+.. TIP::
+ You can install a pre-compiled Windows "wheel" of the latest ``master`` version that is automatically built on ``AppVeyor`` for all recent Python versions. Navigate to `the latest master build `__, click on the first job and then on "Artifacts", download the wheel for your version of Python, and install with ``pip install WHEEL_FILE.whl``.
+
Versions >1.3 should be able to be compiled on Windows systems using the Microsoft Visual Studio C compiler (>= 2015). For this you need to first install the GNU Scientific Library (GSL), for example using Anaconda (:ref:`see below `). Similar to on a UNIX system, you need to set paths to the header and library files where the GSL is located. On Windows, using the CDM commandline, this is done as::
set INCLUDE=%CONDA_PREFIX%\Library\include;%INCLUDE%
diff --git a/doc/source/orbit.rst b/doc/source/orbit.rst
index 84af37a80..10f1e2d37 100644
--- a/doc/source/orbit.rst
+++ b/doc/source/orbit.rst
@@ -305,7 +305,7 @@ orbits from the name of an object. For example, for the star `Lacaille 8760 >> [o.ra(), o.dec(), o.dist(), o.pmra(), o.pmdec(), o.vlos()]
# [319.31362023999276, -38.86736390000036, 0.003970940656277758, -3258.5529999996584, -1145.3959999996205, 20.560000000006063]
-but this also works for some globular clusters, e.g., to obtain `Omega Cen `__'s orbit and current location in the Milky Way do:
+but this also works for globular clusters, e.g., to obtain `Omega Cen `__'s orbit and current location in the Milky Way do:
>>> o= Orbit.from_name('Omega Cen')
>>> from galpy.potential import MWPotential2014
@@ -317,7 +317,7 @@ but this also works for some globular clusters, e.g., to obtain `Omega Cen `__ catalog):
+
+>>> o= Orbit.from_name('MW globular clusters')
+>>> print(len(o))
+# 150
+>>> print(o.name)
+# ['NGC5286', 'Terzan12', 'Arp2', 'NGC5024', ... ]
+>>> print(o.r())
+# [ 8.86999028 3.33270877 21.42173795 18.41411889, ...]
+
+It is then easy to, for example, integrate the orbits of all Milky-Way globular clusters in ``MWPotential2014`` and plot them in 3D:
+
+>>> ts= numpy.linspace(0.,300.,1001)
+>>> o.integrate(ts,MWPotential2014)
+>>> o.plot3d(alpha=0.4)
+>>> xlim(-100.,100.)
+>>> ylim(-100.,100)
+>>> gca().set_zlim3d(-100.,100);
+
+.. image:: images/orbit-fromname-mwglobsorbits.png
+ :scale: 65 %
+
+Similarly, 'MW satellite galaxies' loads all of the Milky-Way satellite galaxies from `Fritz et al. (2018) `__:
+
+>>> o= Orbit.from_name('MW satellite galaxies')
+>>> print(len(o))
+# 40
+>>> print(o.name)
+# ['AquariusII', 'BootesI', 'BootesII', 'CanesVenaticiI', 'CanesVenaticiII', 'Carina',
+ 'CarinaII', 'CarinaIII', 'ComaBerenices', 'CraterII', 'Draco', 'DracoII', 'EridanusII',
+ 'Fornax', 'GrusI', 'Hercules', 'HorologiumI', 'HydraII', 'HydrusI', 'LeoI', 'LeoII',
+ 'LeoIV', 'LeoV', 'LMC', 'PhoenixI', 'PiscesII', 'ReticulumII', 'Sgr', 'Sculptor',
+ 'Segue1', 'Segue2', 'SMC', 'Sextans', 'TriangulumII', 'TucanaII', 'TucanaIII',
+ 'UrsaMajorI', 'UrsaMajorII', 'UrsaMinor', 'Willman1']
+>>> print(o.r())
+# [105.11517882 64.02897066 39.72074174 210.66938806 160.60529059
+ 105.36807259 37.01725917 28.92738515 43.43084545 111.15279646
+ 79.06498854 23.70062857 364.87901007 141.29780146 116.28700298
+ 128.81345239 83.47228672 147.90512269 25.68800918 272.93146472
+ 227.39435987 154.7574384 173.77516411 49.60813235 418.76813979
+ 181.9540996 32.92030664 19.06561359 84.81046251 27.67609888
+ 42.13122436 60.28760354 88.86197382 34.58139798 53.79147743
+ 21.05413655 101.85224099 40.70060809 77.72601419 42.65853777] kpc
+
+and we can integrate and plot them in 3D as above:
+
+>>> o.plot3d(alpha=0.4)
+>>> xlim(-400.,400.)
+>>> ylim(-400.,400)
+>>> gca().set_zlim3d(-400.,400)
+
+.. image:: images/orbit-fromname-mwsatsorbits.png
+ :scale: 65 %
+
+Because ``MWPotential2014`` has a relatively low-mass dark-matter halo, a bunch of the satellites are unbound (to make them bound, you can increase the mass of the halo by, for example, multiplying it by 1.5, as in ``MWPotential2014[2]*= 1.5``).
+
+Finally, for illustrative purposes, the solar system is included as a
+collection as well. The solar system is set up such that the center of
+what is normally the Galactocentric coordinate frame in ``galpy`` is
+now the solar system barycenter and the coordinate frame is a
+heliocentric one. The solar system data are taken from `Bovy et
+al. (2010) `__
+and they represent the positions and planets on April 1, 2009. To load
+the solar system do:
+
+>>> o= Orbit.from_name('solar system')
+
+Giving for example:
+
+>>> print(o.name)
+# ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
+
+You can then, for example, integrate the solar system for 10 years as follows
+
+>>> import astropy.units as u
+>>> from galpy.potential import KeplerPotential
+>>> from galpy.util.bovy_conversion import get_physical
+>>> kp= KeplerPotential(amp=1.*u.Msun,**get_physical(o)) # Need to use **get_physical to get the ro= and vo= parameters, which differ from the default for the solar system
+>>> ts= numpy.linspace(0.,10.,1001)*u.yr
+>>> o.integrate(ts,kp)
+>>> o.plot(d1='x',d2='y')
+
+which gives
+
+.. image:: images/orbit-fromname-solarsyst.png
+ :scale: 75 %
+
+Note that, as usual, physical outputs are in kpc, leading to very small numbers!
+
.. TIP::
Setting up an ``Orbit`` instance *without* arguments will return an Orbit instance representing the Sun: ``o= Orbit()``. This instance has physical units *turned on by default*, so methods will return outputs in physical units unless you ``o.turn_physical_off()``.
diff --git a/galpy/__init__.py b/galpy/__init__.py
index ce21d1df9..54dbb3180 100644
--- a/galpy/__init__.py
+++ b/galpy/__init__.py
@@ -1 +1 @@
-__version__ = "2.0.dev"
+__version__ = "1.6.0.dev"
diff --git a/galpy/actionAngle/actionAngleAdiabatic_c.py b/galpy/actionAngle/actionAngleAdiabatic_c.py
index 48dd6fe0d..8dcff9fd4 100644
--- a/galpy/actionAngle/actionAngleAdiabatic_c.py
+++ b/galpy/actionAngle/actionAngleAdiabatic_c.py
@@ -16,8 +16,13 @@
else: #pragma: no cover
_ext_suffix= '.so'
for path in sys.path:
+ if not os.path.isdir(path): continue
try:
- _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
+ if sys.platform == 'win32' and sys.version_info >= (3,8): # pragma: no cover
+ # winmode=0x008 is easy-going way to call LoadLibraryExA
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix),winmode=0x008)
+ else:
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
except OSError as e:
if os.path.exists(os.path.join(path,'libgalpy%s' % _ext_suffix)): #pragma: no cover
outerr= e
diff --git a/galpy/actionAngle/actionAngleStaeckel_c.py b/galpy/actionAngle/actionAngleStaeckel_c.py
index 7099576e0..5b6c7f9bd 100644
--- a/galpy/actionAngle/actionAngleStaeckel_c.py
+++ b/galpy/actionAngle/actionAngleStaeckel_c.py
@@ -17,8 +17,13 @@
else: #pragma: no cover
_ext_suffix= '.so'
for path in sys.path:
+ if not os.path.isdir(path): continue
try:
- _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
+ if sys.platform == 'win32' and sys.version_info >= (3,8): # pragma: no cover
+ # winmode=0x008 is easy-going way to call LoadLibraryExA
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix),winmode=0x008)
+ else:
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
except OSError as e:
if os.path.exists(os.path.join(path,'libgalpy%s' % _ext_suffix)): #pragma: no cover
outerr= e
diff --git a/galpy/actionAngle/actionAngleTorus_c.py b/galpy/actionAngle/actionAngleTorus_c.py
index da09c7604..761ecf398 100644
--- a/galpy/actionAngle/actionAngleTorus_c.py
+++ b/galpy/actionAngle/actionAngleTorus_c.py
@@ -16,8 +16,13 @@
else: #pragma: no cover
_ext_suffix= '.so'
for path in sys.path:
+ if not os.path.isdir(path): continue
try:
- _lib = ctypes.CDLL(os.path.join(path,'libgalpy_actionAngleTorus%s' % _ext_suffix))
+ if sys.platform == 'win32' and sys.version_info >= (3,8): # pragma: no cover
+ # winmode=0x008 is easy-going way to call LoadLibraryExA
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy_actionAngleTorus%s' % _ext_suffix),winmode=0x008)
+ else:
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy_actionAngleTorus%s' % _ext_suffix))
except OSError as e:
if os.path.exists(os.path.join(path,'libgalpy_actionAngleTorus%s' % _ext_suffix)): #pragma: no cover
outerr= e
diff --git a/galpy/df/streamgapdf.py b/galpy/df/streamgapdf.py
index 6f6c28e70..baf2ab05d 100644
--- a/galpy/df/streamgapdf.py
+++ b/galpy/df/streamgapdf.py
@@ -833,7 +833,7 @@ def _determine_impact_coordtransform(self,deltaAngleTrackImpact,
0.) #angle = 0
auxiliaryTrack= Orbit(prog_stream_offset[3])
if dt < 0.:
- self._gap_trackts= numpy.linspace(0.,-2.*dt,2.*self._nTrackChunksImpact-1)
+ self._gap_trackts= numpy.linspace(0.,-2.*dt,2*self._nTrackChunksImpact-1)
#Flip velocities before integrating
auxiliaryTrack= auxiliaryTrack.flip()
auxiliaryTrack.integrate(self._gap_trackts,self._pot)
diff --git a/galpy/orbit/Orbits.py b/galpy/orbit/Orbits.py
index 4f0a3395d..900a94e6e 100644
--- a/galpy/orbit/Orbits.py
+++ b/galpy/orbit/Orbits.py
@@ -4233,7 +4233,11 @@ def _call_internal(self,*args,**kwargs):
t= args[0]
# Parse t, first check whether we are dealing with the common case
# where one wants all integrated times
+ # 2nd line: scalar Quantities have __len__, but raise TypeError
+ # for scalars
t_exact_integration_times= hasattr(t,'__len__') \
+ and not (_APY_LOADED and isinstance(t,units.Quantity)
+ and t.isscalar) \
and (len(t) == len(self.t)) \
and numpy.all(t == self.t)
if _APY_LOADED and isinstance(t,units.Quantity):
@@ -4250,11 +4254,11 @@ def _call_internal(self,*args,**kwargs):
warnings.warn("You specified integration times as a Quantity, but are evaluating at times not specified as a Quantity; assuming that time given is in natural (internal) units (multiply time by unit to get output at physical time)",galpyWarning)
if t_exact_integration_times: # Common case where one wants all integrated times
return self.orbit.T
- elif isinstance(t,(int,float)) and hasattr(self,'t') \
+ elif isinstance(t,(int,float,numpy.number)) and hasattr(self,'t') \
and t in list(self.t):
return numpy.array(self.orbit[:,list(self.t).index(t),:]).T
else:
- if isinstance(t,(int,float)):
+ if isinstance(t,(int,float,numpy.number)):
nt= 1
t= numpy.atleast_1d(t)
else:
@@ -4586,15 +4590,21 @@ def plot(self,*args,**kwargs):
kwargs.pop('pot',None)
kwargs.pop('OmegaP',None)
kwargs.pop('quantity',None)
+ auto_scale= not 'xrange' in kwargs and not 'yrange' in kwargs \
+ and not kwargs.get('overplot',False)
+ labels= kwargs.pop('label',['Orbit {}'.format(ii+1)
+ for ii in range(self.size)])
+ if self.size == 1 and isinstance(labels,str): labels= [labels]
#Plot
if not 'xlabel' in kwargs:
kwargs['xlabel']= labeldict.get(d1,r'${}$'.format(d1))
if not 'ylabel' in kwargs:
kwargs['ylabel']= labeldict.get(d2,r'${}$'.format(d2))
- for tx,ty in zip(x,y):
+ for ii,(tx,ty) in enumerate(zip(x,y)):
+ kwargs['label']= labels[ii]
line2d= plot.bovy_plot(tx,ty,*args,**kwargs)[0]
kwargs['overplot']= True
- line2d.axes.autoscale(enable=True)
+ if auto_scale: line2d.axes.autoscale(enable=True)
plot._add_ticks()
return [line2d]
@@ -4717,6 +4727,8 @@ def plot3d(self,*args,**kwargs):
kwargs.pop('obs',None)
kwargs.pop('use_physical',None)
kwargs.pop('quantity',None)
+ auto_scale= not 'xrange' in kwargs and not 'yrange' in kwargs \
+ and not 'zrange' in kwargs and not kwargs.get('overplot',False)
#Plot
if not 'xlabel' in kwargs:
kwargs['xlabel']= labeldict.get(d1,r'${}$'.format(d1))
@@ -4727,7 +4739,7 @@ def plot3d(self,*args,**kwargs):
for tx,ty,tz in zip(x,y,z):
line3d= plot.bovy_plot3d(tx,ty,tz,*args,**kwargs)[0]
kwargs['overplot']= True
- line3d.axes.autoscale(enable=True)
+ if auto_scale: line3d.axes.autoscale(enable=True)
plot._add_ticks()
return [line3d]
@@ -4757,6 +4769,8 @@ def animate(self,*args,**kwargs): #pragma: no cover
json_filename= (None) if set, save the data necessary for the figure in this filename (e.g., json_filename= 'orbit_data/orbit.json'); this path is also used in the output HTML, so needs to be accessible
+ staticPlot= (False) if True, create a static plot that doesn't allow zooming, panning, etc.
+
ro= (Object-wide default) physical scale for distances to use to convert (can be Quantity)
vo= (Object-wide default) physical scale for velocities to use to convert (can be Quantity)
@@ -4894,10 +4908,9 @@ def animate(self,*args,**kwargs): #pragma: no cover
height= kwargs.pop('height',400)
load_jslibs= kwargs.pop('load_jslibs',True)
if load_jslibs:
- load_jslibs_code= """
+ load_jslibs_code= """
-
+
+""".format(json_code=json_code,close_json_code=close_json_code,
divid=self.divid,width=width,height=height,
- button_margin_left=button_margin_left,
+ button_margin_left=button_margin_left,config=config,
layout=layout,load_jslibs_code=load_jslibs_code,
+ x_data_list=x_data_list, y_data_list=y_data_list,
+ trace_num_10_list=trace_num_10_list, trace_num_20_list=trace_num_20_list,
setup_trace1=setup_trace1,setup_trace2=setup_trace2,
- setup_trace3=setup_trace3,delete_trace2=delete_trace2,
- delete_trace4=delete_trace4,delete_trace6=delete_trace6,
- delete_trace1=delete_trace1,delete_trace3=delete_trace3,
- delete_trace5=delete_trace5,
- update_trace12=update_trace12,
- update_trace34=update_trace34,
- update_trace56=update_trace56))
+ setup_trace3=setup_trace3, trace_num_list= [ii for ii in range(self.size * len(d1s))]))
class _1DInterp(object):
"""Class to simulate 2D interpolation when using a single orbit"""
diff --git a/galpy/orbit/integrateFullOrbit.py b/galpy/orbit/integrateFullOrbit.py
index fb674423b..f5c546a14 100644
--- a/galpy/orbit/integrateFullOrbit.py
+++ b/galpy/orbit/integrateFullOrbit.py
@@ -24,8 +24,13 @@
else: #pragma: no cover
_ext_suffix= '.so'
for path in sys.path:
+ if not os.path.isdir(path): continue
try:
- _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
+ if sys.platform == 'win32' and sys.version_info >= (3,8): # pragma: no cover
+ # winmode=0x008 is easy-going way to call LoadLibraryExA
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix),winmode=0x008)
+ else:
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
except OSError as e:
if os.path.exists(os.path.join(path,'libgalpy%s' % _ext_suffix)): #pragma: no cover
outerr= e
diff --git a/galpy/orbit/integrateLinearOrbit.py b/galpy/orbit/integrateLinearOrbit.py
index 4fa80c43a..0031325b2 100644
--- a/galpy/orbit/integrateLinearOrbit.py
+++ b/galpy/orbit/integrateLinearOrbit.py
@@ -25,8 +25,13 @@
else: #pragma: no cover
_ext_suffix= '.so'
for path in sys.path:
+ if not os.path.isdir(path): continue
try:
- _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
+ if sys.platform == 'win32' and sys.version_info >= (3,8): # pragma: no cover
+ # winmode=0x008 is easy-going way to call LoadLibraryExA
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix),winmode=0x008)
+ else:
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
except OSError as e:
if os.path.exists(os.path.join(path,'libgalpy%s' % _ext_suffix)): #pragma: no cover
outerr= e
diff --git a/galpy/orbit/integratePlanarOrbit.py b/galpy/orbit/integratePlanarOrbit.py
index 6c85e349b..93d88ead2 100644
--- a/galpy/orbit/integratePlanarOrbit.py
+++ b/galpy/orbit/integratePlanarOrbit.py
@@ -26,8 +26,13 @@
else: #pragma: no cover
_ext_suffix= '.so'
for path in sys.path:
+ if not os.path.isdir(path): continue
try:
- _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
+ if sys.platform == 'win32' and sys.version_info >= (3,8): # pragma: no cover
+ # winmode=0x008 is easy-going way to call LoadLibraryExA
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix),winmode=0x8)
+ else:
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
except OSError as e:
if os.path.exists(os.path.join(path,'libgalpy%s' % _ext_suffix)): #pragma: no cover
outerr= e
diff --git a/galpy/orbit/named_objects.json b/galpy/orbit/named_objects.json
index ad18a68c1..33219b3da 100644
--- a/galpy/orbit/named_objects.json
+++ b/galpy/orbit/named_objects.json
@@ -1,7 +1,8 @@
{
"_collections":
{ "MWglobularclusters": ["NGC5286","Terzan12","Arp2","NGC5024","NGC6638","Crater","BH261","NGC6553","NGC6749","NGC6528","NGC4372","NGC2808","IC4499","BH229","NGC6642","NGC6779","NGC6541","NGC6441","Pal4","NGC6341","NGC5694","NGC2298","Ton2","NGC6637","NGC6325","NGC4147","NGC6366","Pal7","NGC5986","NGC5927","Terzan1","NGC4833","Pal8","NGC7078","NGC6517","NGC6284","Pal14","NGC6539","NGC7089","NGC5272","NGC362","NGC6144","NGC6287","E3","NGC6205","NGC6402","FSR1735","Pal3","NGC6256","NGC6342","Djorg2","NGC6093","NGC5139","Terzan5","NGC6333","NGC6934","NGC6101","NGC6171","NGC5466","Pal5","ESO45211","NGC6266","Pal15","Pal13","Terzan2","NGC6540","Terzan4","BH184","NGC5053","NGC6723","FSR1716","BH176","NGC6809","NGC5897","NGC6496","NGC6715","NGC6388","Pal2","NGC1261","NGC6362","Whiting1","NGC6522","NGC6254","NGC6535","NGC6440","NGC6316","NGC5634","NGC7492","Terzan9","NGC6352","Terzan7","Terzan6","NGC6235","NGC5904","NGC6626","IC1257","NGC5946","NGC6717","NGC288","NGC2419","Terzan10","NGC6218","Pal6","NGC6426","NGC6304","NGC6273","NGC6544","NGC6624","NGC6356","Pal12","Djorg1","NGC6293","NGC7006","NGC104","Pal11","NGC5824","Terzan3","NGC6584","NGC3201","Rup106","NGC6838","NGC7099","NGC6229","NGC6139","Pyxis","NGC6121","NGC6681","NGC6652","NGC1904","NGC1851","NGC6397","Terzan8","NGC6569","NGC6981","NGC6401","NGC6760","NGC6380","NGC6355","NGC4590","Pal1","NGC6656","ESO28006","NGC6558","Pal10","E1","NGC6712","NGC6752","NGC6453","NGC6864","Eridanus"],
- "MWsatellitegalaxies": ["AquariusII", "BootesI", "BootesII", "CanesVenaticiI", "CanesVenaticiII", "Carina", "CarinaII", "CarinaIII", "ComaBerenices", "CraterII", "Draco", "DracoII", "EridanusII", "Fornax", "GrusI", "Hercules", "HorologiumI", "HydraII", "HydrusI", "LeoI", "LeoII", "LeoIV", "LeoV", "LMC", "PhoenixI", "PiscesII", "ReticulumII", "Sgr", "Sculptor", "Segue1", "Segue2", "SMC", "Sextans", "TriangulumII", "TucanaII", "TucanaIII", "UrsaMajorI", "UrsaMajorII", "UrsaMinor", "Willman1"]
+ "MWsatellitegalaxies": ["AquariusII", "BootesI", "BootesII", "CanesVenaticiI", "CanesVenaticiII", "Carina", "CarinaII", "CarinaIII", "ComaBerenices", "CraterII", "Draco", "DracoII", "EridanusII", "Fornax", "GrusI", "Hercules", "HorologiumI", "HydraII", "HydrusI", "LeoI", "LeoII", "LeoIV", "LeoV", "LMC", "PhoenixI", "PiscesII", "ReticulumII", "Sgr", "Sculptor", "Segue1", "Segue2", "SMC", "Sextans", "TriangulumII", "TucanaII", "TucanaIII", "UrsaMajorI", "UrsaMajorII", "UrsaMinor", "Willman1"],
+ "solarsystem": ["Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"]
},
"_synonyms":
{ "OmegaCen": "NGC5139",
@@ -1779,5 +1780,109 @@
"pmdec": -2.273000,
"vlos": -176.700000,
"source": "arXiv:1807.09775"
+ },
+ "Mercury":
+ { "ra": 272.53694669839313746706,
+ "dec": -23.26470710760313309606,
+ "distance": 0.00000000330782629431,
+ "pmra": 114048573.5889339447021484,
+ "pmdec": 1113250730.9213943481445312,
+ "vlos": 24.09379083329670834246,
+ "ro": 0.00000000484813681113,
+ "vo": 30.0,
+ "zo": 0.0,
+ "solarmotion": [0.0,0.0,0.0],
+ "source": "arXiv:0903.5308"
+ },
+ "Venus":
+ { "ra": 261.59112990672980458839,
+ "dec": -33.02216800854332490189,
+ "distance": 0.00000000829181155636,
+ "pmra": -899463102.5785070657730103,
+ "pmdec": -1377271614.5834431648254395,
+ "vlos": -1.82400772039945135994,
+ "ro": 0.00000000484813681113,
+ "vo": 30.0,
+ "zo": 0.0,
+ "solarmotion": [0.0,0.0,0.0],
+ "source": "arXiv:0903.5308"
+ },
+ "Earth":
+ { "ra": 262.96412147067331943617,
+ "dec": -33.59314845931364601483,
+ "distance": 0.00000000965631218281,
+ "pmra": -712425950.9163029193878174,
+ "pmdec": -1089092311.4748961925506592,
+ "vlos": 0.37735889881938400325,
+ "ro": 0.00000000484813681113,
+ "vo": 30.0,
+ "zo": 0.0,
+ "solarmotion": [0.0,0.0,0.0],
+ "source": "arXiv:0903.5308"
+ },
+ "Mars":
+ { "ra": 127.89885319623307680104,
+ "dec": -44.74750104086731994357,
+ "distance": 0.00000000404254311334,
+ "pmra": -412616788.4622230529785156,
+ "pmdec": 620326241.2420622110366821,
+ "vlos": 10.39932018289293402802,
+ "ro": 0.00000000484813681113,
+ "vo": 30.0,
+ "zo": 0.0,
+ "solarmotion": [0.0,0.0,0.0],
+ "source": "arXiv:0903.5308"
+ },
+ "Jupiter":
+ { "ra": 115.15711593351926467221,
+ "dec": -24.04306151473348052150,
+ "distance": 0.00000002182038447526,
+ "pmra": 10122386.4076392110437155,
+ "pmdec": -17153149.6331202201545238,
+ "vlos": 23.07793974607058729021,
+ "ro": 0.00000000484813681113,
+ "vo": 30.0,
+ "zo": 0.0,
+ "solarmotion": [0.0,0.0,0.0],
+ "source": "arXiv:0903.5308"
+ },
+ "Saturn":
+ { "ra": 270.18477455320834224040,
+ "dec": -19.44459530285559978324,
+ "distance": 0.00000005032138429360,
+ "pmra": -83101997.5844055265188217,
+ "pmdec": -142355056.1714278459548950,
+ "vlos": -4.48093156668851833047,
+ "ro": 0.00000000484813681113,
+ "vo": 30.0,
+ "zo": 0.0,
+ "solarmotion": [0.0,0.0,0.0],
+ "source": "arXiv:0903.5308"
+ },
+ "Uranus":
+ { "ra": 89.97246477323895419431,
+ "dec": 21.90938146499203753592,
+ "distance": 0.00000009262040283203,
+ "pmra": 26453654.0211135037243366,
+ "pmdec": -45851111.8113014400005341,
+ "vlos": 3.96038409978304484227,
+ "ro": 0.00000000484813681113,
+ "vo": 30.0,
+ "zo": 0.0,
+ "solarmotion": [0.0,0.0,0.0],
+ "source": "arXiv:0903.5308"
+ },
+ "Neptune":
+ { "ra": 104.39324539298492311445,
+ "dec": -3.84039762053889033311,
+ "distance": 0.00000014167718752406,
+ "pmra": 12522815.9167627468705177,
+ "pmdec": -24543456.2938976883888245,
+ "vlos": 17.91906269190807421410,
+ "ro": 0.00000000484813681113,
+ "vo": 30.0,
+ "zo": 0.0,
+ "solarmotion": [0.0,0.0,0.0],
+ "source": "arXiv:0903.5308"
}
}
diff --git a/galpy/potential/interpRZPotential.py b/galpy/potential/interpRZPotential.py
index 182124800..ee6d165d5 100644
--- a/galpy/potential/interpRZPotential.py
+++ b/galpy/potential/interpRZPotential.py
@@ -22,8 +22,13 @@
else: #pragma: no cover
_ext_suffix= '.so'
for path in sys.path:
+ if not os.path.isdir(path): continue
try:
- _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
+ if sys.platform == 'win32' and sys.version_info >= (3,8): # pragma: no cover
+ # winmode=0x008 is easy-going way to call LoadLibraryExA
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix),winmode=0x008)
+ else:
+ _lib = ctypes.CDLL(os.path.join(path,'libgalpy%s' % _ext_suffix))
except OSError as e:
if os.path.exists(os.path.join(path,'libgalpy%s' % _ext_suffix)): #pragma: no cover
outerr= e
diff --git a/galpy/util/bovy_rk.c b/galpy/util/bovy_rk.c
index d635286d1..180d30623 100644
--- a/galpy/util/bovy_rk.c
+++ b/galpy/util/bovy_rk.c
@@ -104,7 +104,12 @@ void bovy_rk4(void (*func)(double t, double *q, double *a,
if ( interrupted ) {
*err= -10;
interrupted= 0; // need to reset, bc library and vars stay in memory
+#ifdef USING_COVERAGE;
+ __gcov_flush();
+#endif
+// LCOV_EXCL_START
break;
+// LCOV_EXCL_STOP
}
for (jj=0; jj < (ndt-1); jj++) {
bovy_rk4_onestep(func,dim,yn,yn1,to,dt,nargs,potentialArgs,ynk,a);
@@ -208,7 +213,12 @@ void bovy_rk6(void (*func)(double t, double *q, double *a,
if ( interrupted ) {
*err= -10;
interrupted= 0; // need to reset, bc library and vars stay in memory
+#ifdef USING_COVERAGE;
+ __gcov_flush();
+#endif
+// LCOV_EXCL_START
break;
+// LCOV_EXCL_STOP
}
for (jj=0; jj < (ndt-1); jj++) {
bovy_rk6_onestep(func,dim,yn,yn1,to,dt,nargs,potentialArgs,ynk,a,
@@ -534,7 +544,12 @@ void bovy_dopr54(void (*func)(double t, double *q, double *a,
if ( interrupted ) {
*err= -10;
interrupted= 0; // need to reset, bc library and vars stay in memory
+#ifdef USING_COVERAGE;
+ __gcov_flush();
+#endif
+// LCOV_EXCL_START
break;
+// LCOV_EXCL_STOP
}
bovy_dopr54_onestep(func,dim,yn,dt,&to,&dt_one,
nargs,potentialArgs,rtol,atol,
diff --git a/galpy/util/bovy_symplecticode.c b/galpy/util/bovy_symplecticode.c
index e781c2c9a..75a7ac2ba 100644
--- a/galpy/util/bovy_symplecticode.c
+++ b/galpy/util/bovy_symplecticode.c
@@ -146,7 +146,12 @@ void leapfrog(void (*func)(double t, double *q, double *a,
if ( interrupted ) {
*err= -10;
interrupted= 0; // need to reset, bc library and vars stay in memory
+#ifdef USING_COVERAGE;
+ __gcov_flush();
+#endif
+// LCOV_EXCL_START
break;
+// LCOV_EXCL_STOP
}
//drift half
leapfrog_leapq(dim,qo,po,dt/2.,q12);
@@ -266,7 +271,12 @@ void symplec4(void (*func)(double t, double *q, double *a,
if ( interrupted ) {
*err= -10;
interrupted= 0; // need to reset, bc library and vars stay in memory
+#ifdef USING_COVERAGE;
+ __gcov_flush();
+#endif
+// LCOV_EXCL_START
break;
+// LCOV_EXCL_STOP
}
//drift for c1*dt
leapfrog_leapq(dim,qo,po,c1*dt,q12);
@@ -421,7 +431,12 @@ void symplec6(void (*func)(double t, double *q, double *a,
if ( interrupted ) {
*err= -10;
interrupted= 0; // need to reset, bc library and vars stay in memory
+#ifdef USING_COVERAGE;
+ __gcov_flush();
+#endif
+// LCOV_EXCL_START
break;
+// LCOV_EXCL_STOP
}
//drift for c1*dt
leapfrog_leapq(dim,qo,po,c1*dt,q12);
diff --git a/galpy/util/leung_dop853.c b/galpy/util/leung_dop853.c
index 0fca859ce..02caa9a3e 100644
--- a/galpy/util/leung_dop853.c
+++ b/galpy/util/leung_dop853.c
@@ -337,7 +337,12 @@ void dop853(void(*func)(double t, double *q, double *a, int nargs, struct potent
if (interrupted) {
*err_ = -10;
interrupted = 0; // need to reset, bc library and vars stay in memory
+#ifdef USING_COVERAGE;
+ __gcov_flush();
+#endif
+// LCOV_EXCL_START
break;
+// LCOV_EXCL_STOP
}
h = pos_neg * max(fabs(h), 1e3 * uround); // keep time step not too small
@@ -508,4 +513,4 @@ void dop853(void(*func)(double t, double *q, double *a, int nargs, struct potent
free(rcont2);
free(rcont1);
//We're done
-}
\ No newline at end of file
+}
diff --git a/setup.py b/setup.py
index 11d235253..72bf01a6f 100644
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@
long_description= ''
previous_line= ''
-with open('README.rst') as dfile:
+with open('README.md') as dfile:
for line in dfile:
if not 'image' in line and not 'target' in line \
and not 'DETAILED' in line and not '**master**' in line \
@@ -57,7 +57,7 @@
extra_link_args= []
else:
del sys.argv[coverage_pos]
- extra_compile_args.extend(["-O0","--coverage"])
+ extra_compile_args.extend(["-O0","--coverage","-D USING_COVERAGE"])
extra_link_args= ["--coverage"]
#Option to compile everything into a single extension
@@ -207,12 +207,13 @@
actionAngleTorus_c_incl= False
setup(name='galpy',
- version='2.0.dev',
+ version='1.6.0.dev',
description='Galactic Dynamics in python',
author='Jo Bovy',
author_email='bovy@astro.utoronto.ca',
license='New BSD',
long_description=long_description,
+ long_description_content_type='text/markdown',
url='http://github.com/jobovy/galpy',
package_dir = {'galpy/': ''},
packages=['galpy','galpy/orbit','galpy/potential',
@@ -220,7 +221,7 @@
'galpy/actionAngle'],
package_data={'galpy/orbit':['named_objects.json'],
'galpy/df':['data/*.sav'],
- "": ["README.rst","README.dev","LICENSE","AUTHORS.rst"]},
+ "": ["README.md","README.dev","LICENSE","AUTHORS.rst"]},
include_package_data=True,
install_requires=['numpy>=1.7','scipy','matplotlib','pytest','six',
'future','setuptools'],
diff --git a/tests/orbitint4sigint.py b/tests/orbitint4sigint.py
index a50e3a71e..a106b94c3 100644
--- a/tests/orbitint4sigint.py
+++ b/tests/orbitint4sigint.py
@@ -12,8 +12,12 @@
o= Orbit([1.,0.1,1.1,0.1,0.1,0.])
elif sys.argv[2] == 'planar':
o= Orbit([1.,0.1,1.1,0.1])
+ print("Starting long C integration ...")
+ sys.stdout.flush()
o.integrate(ts,mp,method=sys.argv[1])
elif sys.argv[2] == 'planardxdv':
o= Orbit([1.,0.1,1.1,0.1])
+ print("Starting long C integration ...")
+ sys.stdout.flush()
o.integrate_dxdv([0.1,0.1,0.1,0.1],ts,mp,method=sys.argv[1])
sys.exit(0)
diff --git a/tests/test_coords.py b/tests/test_coords.py
index 8599b91c8..eee250759 100644
--- a/tests/test_coords.py
+++ b/tests/test_coords.py
@@ -474,7 +474,7 @@ def test_lbd_to_galcenrect_galpyvsastropy():
# galpy is left-handed, astropy right-handed
assert numpy.fabs(gcXYZ[0]+c.x.to(u.kpc).value) < 10.**-10., "lbd to galcenrect conversion using galpy's methods does not agree with astropy"
assert numpy.fabs(gcXYZ[1]-c.y.to(u.kpc).value) < 10.**-10., "lbd to galcenrect conversion using galpy's methods does not agree with astropy"
- assert numpy.fabs(gcXYZ[2]-c.z.to(u.kpc).value) < 10.**-10., "lbd to galcenrect conversion using galpy's methods does not agree with astropy"
+ assert numpy.fabs(gcXYZ[2]-c.z.to(u.kpc).value) < 10.**-9.5, "lbd to galcenrect conversion using galpy's methods does not agree with astropy"
# Also with negative Xsun
l,b,d= 32., -12., 3.
Zsun= 0.025
@@ -489,7 +489,7 @@ def test_lbd_to_galcenrect_galpyvsastropy():
# galpy is now right-handed, astropy right-handed
assert numpy.fabs(gcXYZ[0]-c.x.to(u.kpc).value) < 10.**-10., "lbd to galcenrect conversion using galpy's methods does not agree with astropy"
assert numpy.fabs(gcXYZ[1]-c.y.to(u.kpc).value) < 10.**-10., "lbd to galcenrect conversion using galpy's methods does not agree with astropy"
- assert numpy.fabs(gcXYZ[2]-c.z.to(u.kpc).value) < 10.**-10., "lbd to galcenrect conversion using galpy's methods does not agree with astropy"
+ assert numpy.fabs(gcXYZ[2]-c.z.to(u.kpc).value) < 10.**-9.5, "lbd to galcenrect conversion using galpy's methods does not agree with astropy"
_turn_on_apy()
return None
@@ -512,7 +512,7 @@ def test_lbd_to_galcencyl_galpyvsastropy():
# galpy is left-handed, astropy right-handed
assert numpy.fabs(gcRpZ[0]-c.rho.to(u.kpc).value) < 10.**-10., "lbd to galcencyl conversion using galpy's methods does not agree with astropy"
assert numpy.fabs(gcRpZ[1]-numpy.pi+c.phi.to(u.rad).value) < 10.**-10., "lbd to galcencyl conversion using galpy's methods does not agree with astropy"
- assert numpy.fabs(gcRpZ[2]-c.z.to(u.kpc).value) < 10.**-10., "lbd to galcencyl conversion using galpy's methods does not agree with astropy"
+ assert numpy.fabs(gcRpZ[2]-c.z.to(u.kpc).value) < 10.**-9.5, "lbd to galcencyl conversion using galpy's methods does not agree with astropy"
# Also with negative Xsun
l,b,d= 32., -12., 3.
Zsun= 0.025
@@ -528,7 +528,7 @@ def test_lbd_to_galcencyl_galpyvsastropy():
# galpy is now right-handed, astropy right-handed
assert numpy.fabs(gcRpZ[0]-c.rho.to(u.kpc).value) < 10.**-10., "lbd to galcencyl conversion using galpy's methods does not agree with astropy"
assert numpy.fabs(gcRpZ[1]-c.phi.to(u.rad).value) < 10.**-10., "lbd to galcencyl conversion using galpy's methods does not agree with astropy"
- assert numpy.fabs(gcRpZ[2]-c.z.to(u.kpc).value) < 10.**-10., "lbd to galcencyl conversion using galpy's methods does not agree with astropy"
+ assert numpy.fabs(gcRpZ[2]-c.z.to(u.kpc).value) < 10.**-9.5, "lbd to galcencyl conversion using galpy's methods does not agree with astropy"
_turn_on_apy()
return None
diff --git a/tests/test_orbit.py b/tests/test_orbit.py
index b4a3ac72a..fb3d73586 100644
--- a/tests/test_orbit.py
+++ b/tests/test_orbit.py
@@ -3900,9 +3900,12 @@ def test_orbit_c_sigint_full():
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
- time.sleep(4)
+ for line in iter(p.stdout.readline, b''):
+ if line.startswith(b"Starting long C integration ..."):
+ break
+ time.sleep(2)
os.kill(p.pid,signal.SIGINT)
- time.sleep(4)
+ time.sleep(1)
cnt= 0
while p.poll() is None and cnt < ntries: # wait a little longer
time.sleep(4)
@@ -3910,7 +3913,7 @@ def test_orbit_c_sigint_full():
if p.poll() == 2 and WIN32: break
- if p.poll() is None or p.poll() != 1:
+ if p.poll() is None or (p.poll() != 1 and p.poll() != -2):
if p.poll() is None: msg= -100
else: msg= p.poll()
raise AssertionError("Full orbit integration using %s should have been interrupted by SIGINT (CTRL-C), but was not because p.poll() == %i" % (integrator,msg))
@@ -3935,9 +3938,12 @@ def test_orbit_c_sigint_planar():
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
- time.sleep(4)
+ for line in iter(p.stdout.readline, b''):
+ if line.startswith(b"Starting long C integration ..."):
+ break
+ time.sleep(2)
os.kill(p.pid,signal.SIGINT)
- time.sleep(4)
+ time.sleep(1)
cnt= 0
while p.poll() is None and cnt < ntries: # wait a little longer
time.sleep(4)
@@ -3945,7 +3951,7 @@ def test_orbit_c_sigint_planar():
if p.poll() == 2 and WIN32: break
- if p.poll() is None or p.poll() != 1:
+ if p.poll() is None or (p.poll() != 1 and p.poll() != -2):
if p.poll() is None: msg= -100
else: msg= p.poll()
raise AssertionError("Full orbit integration using %s should have been interrupted by SIGINT (CTRL-C), but was not because p.poll() == %i" % (integrator,msg))
@@ -3966,9 +3972,12 @@ def test_orbit_c_sigint_planardxdv():
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
- time.sleep(4)
+ for line in iter(p.stdout.readline, b''):
+ if line.startswith(b"Starting long C integration ..."):
+ break
+ time.sleep(2)
os.kill(p.pid,signal.SIGINT)
- time.sleep(4)
+ time.sleep(1)
cnt= 0
while p.poll() is None and cnt < ntries: # wait a little longer
time.sleep(4)
@@ -3976,7 +3985,7 @@ def test_orbit_c_sigint_planardxdv():
if p.poll() == 2 and WIN32: break
- if p.poll() is None or p.poll() != 1:
+ if p.poll() is None or (p.poll() != 1 and p.poll() != -2):
if p.poll() is None: msg= -100
else: msg= p.poll()
raise AssertionError("Full orbit integration using %s should have been interrupted by SIGINT (CTRL-C), but was not because p.poll() == %i" % (integrator,msg))
@@ -4779,6 +4788,29 @@ def test_from_name_collections():
named_data[individual_obj][attr])
return None
+def test_from_name_solarsystem():
+ # Test that the solar system matches Bovy et al. (2010)'s input data
+ from astropy import units
+ from galpy.orbit import Orbit
+ correct_xyz= numpy.array(
+ [[0.324190175,0.090955208,-0.022920510,-4.627851589,10.390063716,1.273504997],
+ [-0.701534590,-0.168809218,0.037947785,1.725066954,-7.205747212,-0.198268558],
+ [-0.982564148,-0.191145980,-0.000014724,1.126784520,-6.187988860,0.000330572],
+ [1.104185888,-0.826097003,-0.044595990,3.260215854,4.524583075,0.014760239],
+ [3.266443877,-3.888055863,-0.057015321,2.076140727,1.904040630,-0.054374153],
+ [-9.218802228,1.788299816,0.335737817,-0.496457364,-2.005021061,0.054667082],
+ [19.930781147,-2.555241579,-0.267710968,0.172224285,1.357933443,0.002836325],
+ [24.323085642,-17.606227355,-0.197974999,0.664855006,0.935497207,-0.034716967]])
+ os= Orbit.from_name('solar system')
+ for (ii,o) in enumerate(os):
+ assert numpy.fabs((o.x()*units.kpc).to(units.AU).value-correct_xyz[ii,0]) < 1e-8, "Orbit.from_name('solar system') does not agree with Bovy et al. (2010) data"
+ assert numpy.fabs((o.y()*units.kpc).to(units.AU).value-correct_xyz[ii,1]) < 1e-8, "Orbit.from_name('solar system') does not agree with Bovy et al. (2010) data"
+ assert numpy.fabs((o.z()*units.kpc).to(units.AU).value-correct_xyz[ii,2]) < 1e-8, "Orbit.from_name('solar system') does not agree with Bovy et al. (2010) data"
+ assert numpy.fabs((o.vx()*units.km/units.s).to(units.AU/units.yr).value-correct_xyz[ii,3]) < 1e-8, "Orbit.from_name('solar system') does not agree with Bovy et al. (2010) data"
+ assert numpy.fabs((o.vy()*units.km/units.s).to(units.AU/units.yr).value-correct_xyz[ii,4]) < 1e-8, "Orbit.from_name('solar system') does not agree with Bovy et al. (2010) data"
+ assert numpy.fabs((o.vz()*units.km/units.s).to(units.AU/units.yr).value-correct_xyz[ii,5]) < 1e-8, "Orbit.from_name('solar system') does not agree with Bovy et al. (2010) data"
+ return None
+
def test_rguiding_errors():
from galpy.potential import TriaxialNFWPotential
from galpy.orbit import Orbit
@@ -4906,6 +4938,43 @@ def test_SkyCoord_init_with_radecisTrue():
assert numpy.fabs(o_sky.vlos()-o_radec.vlos()) < 1e-8, 'Orbit setup with SkyCoord and lb=True does not agree with Orbit setup directly with lb'
return None
+# Test related to issue #415: calling an Orbit with a single int time does not
+# work properly
+# Test from @jamesmlane
+def test_orbit_call_single_time_as_int():
+ from galpy import potential, orbit
+ pot = potential.MWPotential2014
+ o= orbit.Orbit()
+ times = numpy.array([0,1,2])
+ o.integrate(times,pot)
+ # Make sure this does not raise TypeErrpr
+ try:
+ o.x(times[0])
+ except TypeError:
+ raise
+ # Test that the value makes sense
+ assert numpy.fabs(o.x(times[0])-o.x()) < 1e-10
+ return None
+
+# Test related to issue #415: calling an Orbit with a single Quantity time
+# does not work properly
+# Test from @jamesmlane
+def test_orbit_call_single_time_as_Quantity():
+ from galpy import potential, orbit
+ from astropy import units as u
+ pot = potential.MWPotential2014
+ o= orbit.Orbit()
+ times = numpy.array([0,1,2])*u.Gyr
+ o.integrate(times,pot)
+ # Make sure this does not raise TypeErrpr
+ try:
+ o.x(times[0])
+ except TypeError:
+ raise
+ # Test that the value makes sense
+ assert numpy.fabs(o.x(times[0])-o.x()) < 1e-10
+ return None
+
# Setup the orbit for the energy test
def setup_orbit_energy(tp,axi=False,henon=False):
# Need to treat Henon sep. here, bc cannot be scaled to be reasonable