Skip to content

Commit bdff658

Browse files
authored
Merge pull request #2618 from KatKiker/main
New Service: NEODyS website
2 parents af87c33 + a363552 commit bdff658

File tree

11 files changed

+328
-0
lines changed

11 files changed

+328
-0
lines changed

CHANGES.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ esa.hubble
2323
- Status and maintenance messages from eHST TAP when the module is instantiated. get_status_messages method to retrieve them. [#2597]
2424
- Optional parameters in all methods are kwargs keyword only. [#2597]
2525

26+
solarsystem.neodys
27+
^^^^^^^^^^^^^^^^^^
28+
29+
- New module to access the NEODyS web interface.
30+
2631
solarsystem.pds
2732
^^^^^^^^^^^^^^^
2833

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
NEODyS Query Tool
3+
-----------------
4+
5+
:Author: B612 Foundation
6+
7+
This package is for querying NEODys website
8+
9+
"""
10+
11+
from astropy import config as _config
12+
13+
14+
class Conf(_config.ConfigNamespace):
15+
"""
16+
Configuration parameters for `astroquery.solarsystem.neodys`.
17+
"""
18+
server = _config.ConfigItem(
19+
['https://newton.spacedys.com/~neodys2/epoch/'],
20+
'Base name of the NEODyS server to use.')
21+
timeout = _config.ConfigItem(
22+
60,
23+
'Time limit for connecting to NEODyS server.')
24+
25+
26+
conf = Conf()
27+
28+
from .core import NEODyS, NEODySClass
29+
30+
__all__ = ['NEODyS', 'NEODySClass',
31+
'Conf', 'conf',
32+
]

astroquery/solarsystem/neodys/core.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from . import conf
2+
from astroquery.query import BaseQuery
3+
4+
5+
__all__ = ['NEODyS', 'NEODySClass']
6+
7+
8+
class NEODySClass(BaseQuery):
9+
10+
NEODYS_URL = conf.server
11+
TIMEOUT = conf.timeout
12+
13+
def query_object(self, object_id, *, orbital_element_type="eq", epoch_near_present=0):
14+
"""
15+
Parameters
16+
----------
17+
object_id : str
18+
Name of objects to be searched in NEODyS website
19+
20+
orbital_element_type : str
21+
Sets coordinate system for results.
22+
eq - Equinoctial
23+
ke - Keplerian
24+
Defaults to Equinoctial which is given in higher
25+
precision.
26+
27+
epoch_near_present : bool
28+
Sets the epoch to near present day. Otherwise
29+
defaults to near middle of the arc.
30+
31+
Returns
32+
-------
33+
34+
Returns a dictionary with the following entries:
35+
36+
KEP : float array
37+
The state vector in Keplerian elements.
38+
Units in au and deg.
39+
40+
EQU : float array
41+
The state vector in Equinoctial elements.
42+
43+
COV : float array
44+
The covariance matrix.
45+
46+
COR : float array
47+
The correlation matrix for Keplerian.
48+
49+
MJD : str array
50+
The Mean Julian date, and the time scale
51+
used.
52+
53+
MAG : float array
54+
The absolute magnitude (H) and slope
55+
parameter (G)
56+
57+
Raises
58+
------
59+
ValueError
60+
If input parameters are invalid.
61+
62+
RuntimeError
63+
If connection to website fails.
64+
65+
"""
66+
67+
COV = []
68+
COR = []
69+
70+
if orbital_element_type != 'ke' and orbital_element_type != 'eq':
71+
raise ValueError("OrbitElementType must be ke or eq")
72+
73+
object_url = f'{self.NEODYS_URL}/{object_id}.{orbital_element_type}{epoch_near_present}'
74+
75+
response = self._request('GET', object_url, timeout=self.TIMEOUT)
76+
response.raise_for_status()
77+
78+
ascii_text = (response.text).split('\n')
79+
80+
results = {}
81+
82+
for line in ascii_text:
83+
if 'KEP' in line:
84+
results["Keplerian State Vector"] = [float(x) for x in line.split()[1:]]
85+
if 'EQU' in line:
86+
results["Equinoctial State Vector"] = [float(x) for x in line.split()[1:]]
87+
if 'MJD' in line:
88+
results["Mean Julian Date"] = line.split()[1:]
89+
if 'MAG' in line:
90+
results["Magnitude"] = [float(x) for x in line.split()[1:]]
91+
if 'COV' in line:
92+
COV.extend([float(x) for x in line.split()[1:]])
93+
if 'COR' in line:
94+
COR.extend([float(x) for x in line.split()[1:]])
95+
results["Covariance Matrix"] = COV
96+
results["Keplerian Correlation Matrix"] = COR
97+
results["URL"] = object_url
98+
99+
return results
100+
101+
102+
NEODyS = NEODySClass()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Licensed under a 3-clause BSD style license - see LICENSE.rst
2+
import os
3+
4+
5+
def get_package_data():
6+
paths_test = [os.path.join('data', '2018vp1_eq0.txt')]
7+
8+
return {'astroquery.solarsystem.neodys.tests': paths_test}

astroquery/solarsystem/neodys/tests/__init__.py

Whitespace-only changes.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
format = 'OEF2.0' ! file format
2+
rectype = 'ML' ! record type (1L/ML)
3+
refsys = ECLM J2000 ! default reference system
4+
END_OF_HEADER
5+
2018VP1
6+
! Equinoctial elements: a, e*sin(LP), e*cos(LP), tan(i/2)*sin(LN), tan(i/2)*cos(LN), mean long.
7+
EQU 1.5881497559207589E+00 -0.037761493287417 0.428349632624671 0.018136658554010 0.021742631955843 14.9386830433169
8+
MJD 58430.299591399 TDT
9+
MAG 30.865 0.150
10+
! Non-grav parameters: model used, actual number in use, dimension
11+
LSP 0 0 6
12+
! RMS 5.66778E-04 3.33640E-05 2.25727E-04 7.59772E-06 9.13987E-06 1.37733E-02
13+
! EIG 8.38066E-10 1.69716E-09 1.28167E-08 5.23083E-08 6.36449E-07 6.56682E-04
14+
! WEA 0.86309 -0.05080 0.34374 0.01157 0.01392 -0.36607
15+
COV 3.212371896218492E-07 -1.890888042046556E-08 1.279370251095811E-07
16+
COV 4.306149504229515E-09 5.180213121398058E-09 -7.806384186128134E-06
17+
COV 1.113155399718790E-09 -7.530754184805629E-09 -2.534799484940481E-10
18+
COV -3.049291243327506E-10 4.595165457614499E-07 5.095265031366585E-08
19+
COV 1.714984526300696E-09 2.063091894983725E-09 -3.109000937048165E-06
20+
COV 5.772527813193308E-11 6.944207925149469E-11 -1.046445200258212E-07
21+
COV 8.353717813304041E-11 -1.258850849123837E-07 1.897040272478581E-04
22+
NOR 2.792906501841200E+15 1.091214279085640E+16 -1.547061570068868E+16
23+
NOR 1.761621586690132E+16 -1.570584941749150E+16 -1.657511435714105E+14
24+
NOR 6.985168079071240E+17 -4.787110160483813E+17 -3.804184995389532E+16
25+
NOR 3.494747873155191E+16 -9.086207494297492E+15 3.524435742182211E+17
26+
NOR -2.874629116079826E+16 2.496178291549370E+16 6.299748386561305E+15
27+
NOR 1.852710904000144E+17 -1.661603209855957E+17 3.378845532988509E+14
28+
NOR 1.496956716339183E+17 -3.141838806716318E+14 1.184111705066130E+14
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import pytest
2+
import os
3+
4+
import numpy as np
5+
6+
from astroquery.utils.mocks import MockResponse
7+
from astroquery.solarsystem.neodys import NEODySClass, NEODyS
8+
9+
DATA_FILE = '2018vp1_eq0.txt'
10+
11+
12+
def data_path(filename):
13+
data_dir = os.path.join(os.path.dirname(__file__), 'data')
14+
return os.path.join(data_dir, filename)
15+
16+
17+
# monkeypatch replacement request function
18+
def nonremote_request(self, request_type, url, **kwargs):
19+
with open(data_path(DATA_FILE), 'rb') as f:
20+
response = MockResponse(content=f.read(), url=url)
21+
return response
22+
23+
24+
# use a pytest fixture to create a dummy 'requests.get' function,
25+
# that mocks(monkeypatches) the actual 'requests.get' function:
26+
@pytest.fixture
27+
def patch_request(request):
28+
mp = request.getfixturevalue("monkeypatch")
29+
mp.setattr(NEODySClass, '_request', nonremote_request)
30+
return mp
31+
32+
33+
def test_neodys_query(patch_request):
34+
res = NEODyS.query_object(
35+
object_id="2018VP1", orbital_element_type='eq', epoch_near_present=0)
36+
np.testing.assert_allclose(res['Equinoctial State Vector'],
37+
[1.5881497559198392, -0.037761493287362, 0.428349632624304, 0.018136658553998,
38+
0.021742631955829, 14.9386830433394])
39+
assert res['Mean Julian Date'] == ['58430.299591399', 'TDT']
40+
assert res['Magnitude'] == [30.865, 0.15]
41+
np.testing.assert_allclose(
42+
res['Covariance Matrix'],
43+
[3.212371896244936e-07, -1.890888042008199e-08, 1.279370251108077e-07, 4.306149504243656e-09,
44+
5.180213121424896e-09, -7.806384186165599e-06, 1.113155399664521e-09, -7.5307541846631e-09,
45+
-2.534799484876558e-10, -3.049291243256377e-10, 4.595165457505564e-07, 5.095265031422349e-08,
46+
1.714984526308656e-09, 2.063091894997213e-09, -3.109000937067305e-06, 5.772527813183736e-11,
47+
6.944207925151111e-11, -1.04644520025806e-07, 8.353717813321847e-11, -1.258850849126041e-07,
48+
0.0001897040272481179])
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import pytest
2+
3+
from astroquery.solarsystem.neodys import NEODyS
4+
5+
6+
@pytest.mark.remote_data
7+
def test_neodys_query():
8+
9+
test_object = "2018VP1"
10+
11+
res_kep_0 = NEODyS.query_object(test_object, orbital_element_type="ke", epoch_near_present=0)
12+
res_kep_1 = NEODyS.query_object(test_object, orbital_element_type="ke", epoch_near_present=1)
13+
res_eq_0 = NEODyS.query_object(test_object, orbital_element_type="eq", epoch_near_present=0)
14+
res_eq_1 = NEODyS.query_object(test_object, orbital_element_type="eq", epoch_near_present=1)
15+
16+
assert len(res_kep_0['Keplerian State Vector']) == 6
17+
assert len(res_kep_0['Covariance Matrix']) == 21
18+
assert res_kep_0['Mean Julian Date'][0] != res_kep_1['Mean Julian Date'][0]
19+
assert len(res_eq_0['Equinoctial State Vector']) == 6
20+
assert len(res_eq_0['Covariance Matrix']) == 21
21+
assert len(res_eq_0['Keplerian Correlation Matrix']) == 0
22+
assert res_eq_0['Mean Julian Date'][0] != res_eq_1['Mean Julian Date'][0]

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ above categories. Those services are here:
401401
jplhorizons/jplhorizons.rst
402402
jplsbdb/jplsbdb.rst
403403
nasa_ads/nasa_ads.rst
404+
solarsystem/neodys/neodys.rst
404405
utils/tap.rst
405406

406407

docs/solarsystem/neodys/neodys.rst

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
.. _astroquery.neodys:
2+
3+
************************************************
4+
NEODyS Queries (`astroquery.solarsystem.neodys`)
5+
************************************************
6+
7+
Getting started
8+
===============
9+
10+
This module supports retrieving the orbital information of an object from the
11+
NEODyS website (https://newton.spacedys.com/neodys/). The state vector,
12+
covariance matrix, epoch, absolute magnitude, slope parameter, and correlation
13+
matrix are given in dictionary form. The results can be given in either
14+
Keplerian or Equinoctial. The only required argument is the identifier of the
15+
object to be retrieved. Here is a basic example:
16+
17+
.. doctest-remote-data::
18+
19+
>>> from astroquery.solarsystem.neodys import NEODyS
20+
>>> result = NEODyS.query_object("1982YA")
21+
>>> print(result)
22+
{'Equinoctial State Vector': [3.6501814973859177, 0.55510840531515, 0.412442615432626, -0.316403600209491, -0.005615261288851, 7.4974723045741],
23+
'Mean Julian Date': ['57672.370442276', 'TDT'],
24+
'Magnitude': [17.478, 0.15],
25+
'Covariance Matrix': [2.983481961445874e-14, 1.319692615237118e-13, -3.466482497808619e-13,
26+
-5.179294501167426e-15, 4.40306644125416e-15, 2.841155344781695e-11,
27+
7.248099966950092e-13, -1.55363923471562e-12, -4.018099391315557e-14,
28+
-1.400231787484278e-14, 1.210874090734312e-10, 4.091233073364273e-12,
29+
4.62498475268648e-15, -1.406987981569261e-14, -3.37147537859451e-10,
30+
6.527443331995206e-13, -4.021096836415107e-13, -3.876453730470366e-12,
31+
3.584924689571663e-13, 8.057672786144392e-12, 2.841126641896583e-08],
32+
'Keplerian Correlation Matrix': [],
33+
'URL': 'https://newton.spacedys.com/~neodys2/epoch//1982YA.eq0'}
34+
35+
36+
More detailed parameters
37+
------------------------
38+
39+
There are two other optional parameters that can be specified. These
40+
are ``orbital_element_type`` which specifies whether the results will
41+
be in Keplerian or Equinoctial. Valid values are 'ke' for Keplerian
42+
and 'eq' for Equinoctial. The other is ``epoch_near_present``, a flag
43+
which sets the epoc to near present instead of near middle of the arc.
44+
Valid values are '0' for near middle of the arc, and '1' for near
45+
present. The default values are 'eq' and '0'. Note: Keplerian elements
46+
are given to a lower precision on the NEODyS website.
47+
48+
Here's an example with these optional parameters:
49+
50+
.. doctest-remote-data::
51+
52+
>>> from astroquery.solarsystem.neodys import NEODyS
53+
>>> results = NEODyS.query_object("1982YA", orbital_element_type="ke", epoch_near_present=1)
54+
>>> print(results)
55+
{'Keplerian State Vector': [3.64669, 0.691945, 35.165, 268.935, 144.408, 283.498],
56+
'Mean Julian Date': ['60000.0000', 'TDT'],
57+
'Magnitude': [17.478, 0.15],
58+
'Covariance Matrix': [3.92261704e-14, -1.16359258e-13, 3.11585918e-13,
59+
5.00974344e-13, 3.35974943e-11, -6.24946297e-12,
60+
4.44803944e-13, 3.19086108e-12, -3.60667109e-12,
61+
-9.43905769e-11, 6.70717262e-12, 6.92715199e-09,
62+
7.66896347e-09, -7.46695141e-09, 1.41600249e-10,
63+
1.22064798e-08, -1.21318576e-08, 1.39344281e-09,
64+
4.21853471e-08, -7.19870851e-09, 2.62151264e-09],
65+
'Keplerian Correlation Matrix': [1.0, -0.88090418, 0.01890221,
66+
0.02289456, 0.82592026, -0.61628098,
67+
1.0, 0.0574839, -0.0489471,
68+
-0.68907027, 0.19641705, 1.0,
69+
0.83399624, -0.43680254, 0.0332285,
70+
1.0, -0.53462747, 0.24633037,
71+
1.0, -0.68453837, 1.0],
72+
'URL': 'https://newton.spacedys.com/~neodys2/epoch//1982YA.ke1'}
73+
74+
75+
Reference/API
76+
=============
77+
78+
.. automodapi:: astroquery.solarsystem.neodys
79+
:no-inheritance-diagram:

0 commit comments

Comments
 (0)