Python API для JPL Horizons?

Я нашел пакет python HorizonJPL в индексе пакетов Python , но похоже, что он ограничен активностью в 2013 году . довольно редко, и две ссылки ведут в тупик на японском языке (ниже).

Есть ли способ получить доступ к JPL Horizons для таблиц данных (как я делаю здесь ) из скрипта Python? Другими словами, я хочу построить URL-запрос и получить json текста с векторами состояния в ответ, используя urllibили urllib2.


Обновление: это типичный пример того, что я хочу сделать:

введите описание изображения здесь


Это то, что отображается на сайте pypi - кажется, есть имена/дескрипторы, но я не знаю, как их запросить.

Документация API

https://docs.google.com/document/d/1g9q3ln9LVAATOZ15986HLTCaqcAj_Jd8e_jOGS3YWrE/pub

Ресурсы

Планетарная система данных: http://pds.nasa.gov/

Лаборатория реактивного движения: http://www.jpl.nasa.gov/

Руководство пользователя HORIZON: http://ssd.jpl.nasa.gov/?horizons_doc

Авторы


Мэтью Михок (@mattmattmatt)

Декстер Джагула (@djagula)

Сиддарт Калра (@SiddarthKalra)

Тьяго Морейра (@Kamots)

Вот что происходит, когда я пробую ссылки в документе Google :

введите описание изображения здесь

введите описание изображения здесь

Если это не привлечет никакой помощи, скажем, через неделю, то, возможно, это хороший кандидат для перехода на stackoverflow в то время. Тег pythonтам критичен.
Вы пытались использовать telnetlibдля доступа к интерфейсу telnet?
@2012rcampion Хорошо, я посмотрю сегодня! Если я правильно понимаю, мне пришлось бы написать скрипт на Python, который в основном эмулирует человека, набирающего команды и получающего подсказки. Возможно, кто-то хорошо поработал над этим и написал хорошую оболочку интерфейса — моя конечная цель — посмотреть, сделал ли кто-нибудь что-то подобное общедоступным. А пока обязательно попробую то, что вы предложили. Спасибо!!
Если вы не собираетесь использовать скрипт в течение длительного времени, вам вообще не нужно обрабатывать подсказки. Что я сделал, так это получил один набор данных вручную, а затем заставил мой скрипт воспроизвести тот же сеанс с одним настраиваемым параметром.
@ 2012rcampion Хорошо понял. Руководство полезно , но я ищу примеры сессий, которые мне легче усвоить. Я добавил пример того, что я хочу сделать в вопросе. Если я заставлю его работать, я опубликую его как ответ - если кто-то еще сначала опубликует аналогичный пример сеанса telnet или скрипт, черт возьми, я буду вынужден принять его ! :)
@uhoh Я действительно пытался начать с Java API для этого после того, как вы познакомили меня с ним. Самый простой способ создать API — использовать сниффер форм и выполнять запросы к форме на странице. Вы можете перехватить отправленные данные и реплицировать их с помощью POST-запроса к серверному файлу .cgi. Сейчас я в отпуске, но если вы хотите, чтобы я опубликовал пример того, как это сделать в python, я был бы рад помочь. Даже если нет API, МНОГОЕ можно сделать с помощью форм и простых HTTP-запросов. Даже telnet мог бы очень хорошо работать, чтобы что-то автоматизировать.

Ответы (3)

callhorizons теперь устарел и относится к библиотеке python, astroqueryкоторая теперь кажется подходящей.

astroquery ( GitHub , readthedocs ) — это «связанный с astropy пакет, который содержит набор инструментов для доступа к онлайн-астрономическим данным. Каждый веб-сервис имеет свой собственный подпакет», где выполнение запросов Horizons — лишь один из многих вариантов. Это часть более крупного проекта Astropy Project , который представляет собой «усилия сообщества по разработке общего базового пакета для астрономии на Python и развитию экосистемы совместимых астрономических пакетов».

Я рекомендую прочитать страницу документации для запросов JPL Horizons для astroquery, которую можно найти здесь: https://astroquery.readthedocs.io/en/latest/jplhorizons/jplhorizons.html В нем перечислены несколько хороших примеров, например:

from astroquery.jplhorizons import Horizons
obj = Horizons(id='Ceres', location='568',
                epochs={'start':'2010-01-01', 'stop':'2010-03-01', 'step':'10d'})
eph = obj.ephemerides()
print(eph)

targetname    datetime_str   datetime_jd ...   GlxLat  RA_3sigma DEC_3sigma
   ---            ---             d      ...    deg      arcsec    arcsec
---------- ----------------- ----------- ... --------- --------- ----------
   1 Ceres 2010-Jan-01 00:00   2455197.5 ... 24.120057       0.0        0.0
   1 Ceres 2010-Jan-11 00:00   2455207.5 ... 20.621496       0.0        0.0
   1 Ceres 2010-Jan-21 00:00   2455217.5 ... 17.229529       0.0        0.0
   1 Ceres 2010-Jan-31 00:00   2455227.5 ...  13.97264       0.0        0.0
   1 Ceres 2010-Feb-10 00:00   2455237.5 ... 10.877201       0.0        0.0
   1 Ceres 2010-Feb-20 00:00   2455247.5 ...  7.976737       0.0        0.0

Я также рекомендую просмотреть документы HorizonsClass . В частности, сначала меня смутило то, что установка цели id=399не нацелена на Землю, но это было потому, что класс также принимает id-typeаргумент, который по умолчанию smallbodyравен (астероиды и т. п.), и его нужно было изменить на majorbody.

Это кажется очень простым в использовании, и это явно правильный путь сейчас.

PS: я упомяну, что получил ошибку KeyError: 'Obsrv-lon'для моего конкретного запроса, но проблема исследуется.

Это кажется потенциально очень хорошей новостью! Я только что спросил , как именно использовать astroquery.jplhorizons для получения векторов состояния Меркурия и солнечного зонда Parker?
Это хорошая информация, но было бы лучше, если бы в посте было немного больше пояснений, а не просто ссылка. Может быть, у проекта astroquery есть readme или заявление о миссии, которое вы могли бы здесь процитировать?
Хорошо, я добавил немного больше информации :)

Есть один сейчас! Я только что наткнулся на callhorizons пакетов python в github и Python Package Index .

На readthedocis.io есть дополнительная информация, которая помогает объяснить, как делать запросы, если вы ищете астероиды/малые тела, для которых есть миллионы, и имена могут быть именами людей или буквенно-цифровыми.

Я постараюсь протестировать его дальше и обновить здесь. Похоже, здесь много возможностей, но я пока не могу сказать наверняка. Есть запись в блоге астронома, но она датирована январем 2016 года.

Это была однострочная установка, а именно pip install callhorizons. Затем я набрал простую демонстрацию в верхней части страницы PyPI и получил ответ!

>>> import callhorizons
>>> eros = callhorizons.query('Eros')
>>> eros.set_discreteepochs([2457446.177083, 2457446.182343])
>>> eros.get_ephemerides(568)
2
>>> print(eros['RA'], eros['DEC'])
(array([ 292.46003,  292.46332]), array([-27.44392, -27.44335]))
>>>

Ай питон!

Текущая версия представляет собой чистый скрипт Python и содержит комментарий:

CALLHORIZONS - a Python interface to access JPL HORIZONS
ephemerides and orbital elements.

This module provides a convenient python interface to the JPL
HORIZONS system by directly accessing and parsing the HORIZONS
website. Ephemerides can be obtained through get_ephemerides,
orbital elements through get_elements. Function
export2pyephem provides an interface to the PyEphem module.

michael.mommert (at) nau.edu, latest version: v1.0.5, 2017-05-05.
This code is inspired by code created by Alex Hagen.

В настоящее время он генерирует только URL-адрес запроса для таблицы наблюдателя, а не векторы состояния, но, безусловно, его можно легко настроить для получения векторов состояния. Вот небольшой фрагмент, дополнительные параметры добавляются в строку URL перед ее использованием.

### construct URL for HORIZONS query
url = "http://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=l" \
      + "&TABLE_TYPE='OBSERVER'" \
      + "&QUANTITIES='" + str(quantities) + "'" \
      + "&CSV_FORMAT='YES'" \
      + "&ANG_FORMAT='DEG'" \
      + "&CAL_FORMAT='BOTH'" \
      + "&SOLAR_ELONG='" + str(solar_elongation[0]) + "," \
      + str(solar_elongation[1]) + "'" \
      + "&CENTER='"+str(observatory_code)+"'"

ОК, попробуйте космический корабль, также вид с Мауна-Кеа. Из JPL Horizons со следующей настройкой:

введите описание изображения здесь

дает (прокручивает горизонтально):

**********************************************************************************************************************************
Date_________JDUT, , ,R.A._(ICRF/J2000.0), DEC_(ICRF/J2000.0),  APmag, S-brt,            delta,     deldot,    S-O-T,/r,    S-T-O,
**********************************************************************************************************************************
$$SOE
2457754.500000000,*,m,20 01 24.54,-56 59 28.4,   n.a.,  n.a., 1.7047550022E+10, 18.9796569,  36.6514,/T,   0.2976,
2457784.500000000,*,m,20 03 22.69,-56 58 00.2,   n.a.,  n.a., 1.7080283550E+10,  6.5439542,  40.6419,/L,   0.3218,
2457814.500000000,*,m,20 05 08.36,-57 01 24.2,   n.a.,  n.a., 1.7082950019E+10, -3.4910462,  59.2751,/L,   0.4270,
2457844.500000000,*,m,20 06 16.02,-57 09 10.1,   n.a.,  n.a., 1.7065586218E+10, -8.4792450,  82.4692,/L,   0.4975,
2457874.500000000,*,m,20 06 30.25,-57 19 39.5,   n.a.,  n.a., 1.7043227392E+10, -7.3046878, 106.0860,/L,   0.4870,
2457904.500000000,*,m,20 05 49.21,-57 30 32.2,   n.a.,  n.a., 1.7031649793E+10, -0.4854246, 127.5819,/L,   0.4048,
2457934.500000000,*,m,20 04 24.98,-57 39 21.6,   n.a.,  n.a., 1.7043463848E+10, 10.1577911, 141.9907,/L,   0.3144,
$$EOE
**********************************************************************************************************************************

Сравните с этим скриптом:

import callhorizons
import numpy as np

JDs = [2457754.5 + 30*i for i in range(7)] # 01-Jan-2017 00:00 UTC + n*30 days

V2  = callhorizons.query(-32, smallbody=False)     # -32 for Voyager 2

V2.set_discreteepochs(JDs)

V2.get_ephemerides(568)    # 568 for Mauna Kea 

radecs = np.vstack((V2['RA'], V2['DEC']))

for JD, radec in zip(JDs, radecs.T):
    print JD, radec

Выборочная проверка показывает, что это одно и то же, отлично! К вашему сведению, очень большое видимое движение происходит из-за параллакса — Земля меняет свою перспективу каждый месяц. По прошествии одного года положение на самом деле меняется лишь на несколько десятых градуса.

2457754.5 [ 300.35226  -56.99121]
2457784.5 [ 300.84454  -56.96671]
2457814.5 [ 301.28482  -57.0234 ]
2457844.5 [ 301.56676  -57.1528 ]
2457874.5 [ 301.62605  -57.32765]
2457904.5 [ 301.45504  -57.50895]
2457934.5 [ 301.10407  -57.65601]
Похоже, довольно крутая библиотека! Я бы порекомендовал SpiceyPy, который является интерфейсом для SPICE, а SPICE запускает JPL Horizons. Но тогда придется переписывать всю логику.
@ChrisR Я посмотрю. Не могли бы вы оставить короткий ответ с упоминанием SpiceyPy? Комментарии по определению являются временными, и даже если они могут не идеально соответствовать «Python API для JPL Horizons?» он делает что-то достаточно похожее, о чем будущим читателям может быть полезно узнать. Не обязательно должен быть длинный ответ, просто ссылка и объяснение того, что когда кто-то хочет получить доступ к Horizons автоматически, он на самом деле просто получает доступ к SPICE, и поэтому следует знать, что посредник Horizons не всегда необходим.

Выберите входные параметры в Horizons, затем щелкните эту ссылку (ссылка «показать пакетные данные» на странице Horizons): https://ssd.jpl.nasa.gov/horizons.cgi?show=1#results

Вы получите что-то вроде этого:

!$$СОФ

КОМАНДА = '-64'

ЦЕНТР= '500@0'

MAKE_EPHEM= 'ДА'

TABLE_TYPE= 'ВЕКТОРЫ'

START_TIME= '2018-10-1'

STOP_TIME= '2018-10-30'

STEP_SIZE= '1 день'

OUT_UNITS='AU-D'

REF_PLANE = 'ЭКЛИПТИКА'

REF_SYSTEM = 'J2000'

VECT_CORR= 'НЕТ'

VEC_LABELS= 'ДА'

VEC_DELTA_T= 'НЕТ'

CSV_FORMAT= 'НЕТ'

OBJ_DATA = 'ДА'

VEC_TABLE = '3'

!$$EOF

Удалить строки, начинающиеся с "!".

Скопируйте оставшийся текст в свой любимый текстовый + шестнадцатеричный редактор и сделайте следующие замены:

0d0a --> & (возврат каретки к "&") ' --> %27 пробел --> %20

Вы получите одну строку для добавления к этому частичному URL-адресу:

https://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=1&

Результат в формате "смешанный CSV" (т.е. CSV с мусором...)

Этот источник javascript преобразует выходные данные Horizons в действительный URL-адрес и откроет его:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <title>NASA Horizons URL generator</title>
  </head>
  <script src="js/jquery.js"></script>
  <script>
  $( document ).ready(function() { // After page load is complete...
		$("#btnGo" ).click(function() { // Associate function to the button to monitor clicking.
			commandsText = $('textarea#commands').val(); // Upon clicking, assign textarea content to variable.		  
			commandsText = commandsText.replace(/\r/g,'&'); // Replace carriage returns
			commandsText = commandsText.replace(/\n/g,'&');	 // Replace carriage returns	  
			commandsText = commandsText.replace(/ /g,"%20"); // Replace spaces			  
			commandsText = commandsText.replace(/\'/g,'%27'); // Replace quotes	  
			var fullURL = 	"https://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=1&" + commandsText; //* Prepend URL base
			$('textarea#URL').val(fullURL)           
            window.open(fullURL); // Open Url
            });     
      });
  </script>
  <body>
  <a href="https://ssd.jpl.nasa.gov/horizons.cgi">Source</a>:<br>
    <textarea id="commands" name="commands" rows = "30" cols = "50"></textarea><br>
    <br>
    Resulting URL:<br>
    <textarea id="URL" name="URL" rows = "30" cols = "50"></textarea><br>
    <button id="btnGo" name="btnGo">Go</button>
    </body>
</html>
добавлен источник Javascript (вы также спросили: «Я хочу построить URL-запрос и получить взамен json текста с векторами состояния»). К сожалению, я не вижу возможности вывода JSON в Horizons.
о, ты прав, я сделал! Это было 2,5 года назад, когда я только начинал. У меня аллергия на фигурные скобки, поэтому я могу использовать только Python. Я думаю, что ваш ответ полезен, и я проголосовал, но теперь есть несколько пакетов Python, которые делают это. Я бы больше не использовал JSON. Еще раз спасибо!