From 7e578e58dac9afbb9af62a7eff31b081a033851c Mon Sep 17 00:00:00 2001 From: hhsieh00 Date: Tue, 4 Feb 2025 09:48:25 -1000 Subject: [PATCH 1/4] draft astroquery code for Lowell astorbdb AstInfo functionality query code only for now; tests not written yet --- astroquery/astorbdb/__init__.py | 39 + astroquery/astorbdb/core.py | 746 ++++++++++++++++++ astroquery/astorbdb/tests/__init__.py | 0 astroquery/astorbdb/tests/data/dummy.dat | 2 + astroquery/astorbdb/tests/setup_package.py | 15 + astroquery/astorbdb/tests/test_module.py | 80 ++ .../astorbdb/tests/test_module_remote.py | 16 + 7 files changed, 898 insertions(+) create mode 100644 astroquery/astorbdb/__init__.py create mode 100644 astroquery/astorbdb/core.py create mode 100644 astroquery/astorbdb/tests/__init__.py create mode 100644 astroquery/astorbdb/tests/data/dummy.dat create mode 100644 astroquery/astorbdb/tests/setup_package.py create mode 100644 astroquery/astorbdb/tests/test_module.py create mode 100644 astroquery/astorbdb/tests/test_module_remote.py diff --git a/astroquery/astorbdb/__init__.py b/astroquery/astorbdb/__init__.py new file mode 100644 index 0000000000..e5a2b0ee69 --- /dev/null +++ b/astroquery/astorbdb/__init__.py @@ -0,0 +1,39 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst + +""" +ASTORBDB +------------------------- + +:author: Henry Hsieh (hhsieh@gmail.com) +""" + +# Make the URL of the server, timeout and other items configurable +# See +# for docs and examples on how to do this +# Below is a common use case + +from astropy import config as _config + + +class Conf(_config.ConfigNamespace): + """ + Configuration parameters for `astroquery.astorbdb`. + """ + server = _config.ConfigItem( + ['https://asteroid.lowell.edu/api/asteroids/'], + 'AstorbDB') + + timeout = _config.ConfigItem( + 30, + 'Time limit for connecting to template_module server.') + + +conf = Conf() + +# Now import your public class +# Should probably have the same name as your module +from .core import AstInfo, AstInfoClass + +__all__ = ['AstInfo', 'AstInfoClass', + 'Conf', 'conf', + ] diff --git a/astroquery/astorbdb/core.py b/astroquery/astorbdb/core.py new file mode 100644 index 0000000000..d713d69ef0 --- /dev/null +++ b/astroquery/astorbdb/core.py @@ -0,0 +1,746 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst + +import astropy.units as u +import astropy.coordinates as coord +import astropy.io.votable as votable +import warnings +from astropy.table import Table +from astropy.time import Time +from astropy.io import fits +import json +from collections import OrderedDict + +from ..query import BaseQuery +from ..utils import commons +from ..utils import async_to_sync +from . import conf + +__all__ = ['AstInfo', 'AstInfoClass'] + +@async_to_sync +class AstInfoClass(BaseQuery): + + ## NEED TO ADD EXAMPLE OUTPUT TO ALL METHODS ## + + """ + A class for querying Lowell Observatory's `astorbDB + `_ service. + """ + # Not all the methods below are necessary but these cover most of the common + # cases, new methods may be added if necessary, follow the guidelines at + # + + URL = conf.server + TIMEOUT = conf.timeout + + # internal flag whether to return the raw reponse + _return_raw = False + + # actual query uri + _uri = None + + def designations_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for designation + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available color data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> designations = AstInfo.designations('Beagle') + >>> print(designations) + OrderedDict({'alternate_designations': ['1954 HJ', 'A908 BJ', 'A917 ST'], 'name': 'Beagle', 'number': 656, 'primary_designation': 'Beagle'}) + """ + + self.query_type = 'designations' + + response = self._request('GET', + url=self.URL + object_name + '/designations', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def elements_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for designation + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available color data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> elements = AstInfo.elements('Beagle') + >>> print(elements) + OrderedDict({'a': , 'aphelion_dist': , ...}) + """ + + self.query_type = 'elements' + + response = self._request('GET', + url=self.URL + object_name + '/elements', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def orbit_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for orbit + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available orbit data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> orbit = AstInfo.orbit('Beagle') + >>> print(orbit) + OrderedDict({'a1con': , 'a2con': , 'a3con': , ...}) + """ + + self.query_type = 'orbit' + + response = self._request('GET', + url=self.URL + object_name + '/orbit', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def albedos_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for albedo + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available albedo data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> albedos = AstInfo.albedos('Beagle') + >>> print(albedos) + [{'albedo': 0.065, 'albedo_error_lower': -0.002, ..., 'survey_name': 'Usui et al. (2011)'}, + {'albedo': 0.0625, 'albedo_error_lower': -0.015, ..., 'survey_name': 'Infrared Astronomical Satellite (IRAS)'}, + ...] + """ + + self.query_type = 'albedos' + + response = self._request('GET', + url=self.URL + object_name + '/data/albedos', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def colors_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for color + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available color data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> colors = AstInfo.colors('Beagle') + >>> print(colors) + [{'citation_bibcode': '2010PDSS..125.....S', ..., 'color': 0.431, 'color_error': 0.035, ..., 'sys_color': 'J-H'}, + {'citation_bibcode': '2010PDSS..125.....S', ..., 'color': 0.076, 'color_error': 0.041, ..., 'sys_color': 'H-K'}, + ...] + """ + + self.query_type = 'colors' + + response = self._request('GET', + url=self.URL + object_name + '/data/colors', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def taxonomies_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for taxonomy + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available taxonomy data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> taxonomies = AstInfo.taxonomies('Beagle') + >>> print(taxonomies) + [{'citation_bibcode': '2011PDSS..145.....H', ..., 'survey_name': 'Carvano et al. (2010)', 'taxonomy': 'C', ...}, + {'citation_bibcode': '2013Icar..226..723D', ..., 'survey_name': 'DeMeo et al. (2013)', 'taxonomy': 'C', ...}] + """ + + self.query_type = 'taxonomies' + + response = self._request('GET', + url=self.URL + object_name + '/data/taxonomies', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def lightcurves_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for lightcurve + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available lightcurve data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> lightcurves = AstInfo.lightcurves('Beagle') + >>> print(lightcurves) + [{'ambiguous_period': False, ..., 'amp_max': , 'amp_min': , ..., 'period': , ...}] + """ + + self.query_type = 'lightcurves' + + response = self._request('GET', + url=self.URL + object_name + '/data/lightcurves', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def dynamicalfamily_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for dynamical family + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available dynamical family data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> dynamicalfamily = AstInfo.dynamicalfamily('Beagle') + >>> print(dynamicalfamily) + [{'citation_bibcode': '2015PDSS..234.....N', ..., 'family': 'Themis', ...}, + {'citation_bibcode': '2015PDSS..234.....N', ..., 'family': 'Beagle', ...}] + """ + + self.query_type = 'dynamicalfamily' + + response = self._request('GET', + url=self.URL + object_name + '/data/dynamical-family', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def escaperoutes_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for NEO escape route + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available NEO escape route data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> escaperoutes = AstInfo.escaperoutes('3552') + >>> print(escaperoutes) + [{'citation_bibcode': '2018Icar..312..181G', ..., 'dp21_complex': 0.03695, 'dp31_complex': 0.00105, ...}] + """ + + self.query_type = 'escaperoutes' + + response = self._request('GET', + url=self.URL + object_name + '/data/escape-routes', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = response.url + + return response + + + def all_astinfo_async(self,object_name, *, + get_raw_response=False, + get_uri=False, + cache=True): + """ + This method uses a REST interface to query the `Lowell Observatory + astorbDB database `_ for NEO escape route + data for a single object and returns a dictionary from JSON results + + Parameters + ---------- + object_name : str + name of the identifier to query. + + Returns + ------- + res : A dictionary holding available NEO escape route data + + Examples + -------- + >>> from astroquery.astorbdb import AstInfo + >>> all_astinfo = AstInfo.all_astinfo('Beagle') + >>> print(all_astinfo) + OrderedDict({ + 'designations': OrderedDict({'alternate_designations': ['1954 HJ', 'A908 BJ', 'A917 ST'], 'name': 'Beagle', ...}), + 'elements': OrderedDict({'a': , 'aphelion_dist': , ...}), + 'orbit': OrderedDict({'a1con': , 'a2con': , 'a3con': , ...}), + 'albedos': [{'albedo': 0.065, 'albedo_error_lower': -0.002, 'albedo_error_upper': 0.002, ..., 'survey_name': 'Usui et al. (2011)'}, + {'albedo': 0.0625, 'albedo_error_lower': -0.015, 'albedo_error_upper': 0.015, ..., 'survey_name': 'Infrared Astronomical Satellite (IRAS)'}, + ...], + 'colors': [{'citation_bibcode': '2010PDSS..125.....S', ..., 'color': 0.431, 'color_error': 0.035, ..., 'sys_color': 'J-H'}, + {'citation_bibcode': '2010PDSS..125.....S', ..., 'color': 0.076, 'color_error': 0.041, ..., 'sys_color': 'H-K'}, + ...], + 'taxonomies': [{'citation_bibcode': '2011PDSS..145.....H', ..., 'survey_name': 'Carvano et al. (2010)', 'taxonomy': 'C', ...}, + {'citation_bibcode': '2013Icar..226..723D', ..., 'survey_name': 'DeMeo et al. (2013)', 'taxonomy': 'C', ...}], + 'lightcurves': [{'ambiguous_period': False, ..., 'amp_max': , 'amp_min': , ..., 'period': , ...}], + 'dynamicalfamily': [{'citation_bibcode': '2015PDSS..234.....N', ..., 'family': 'Themis', ...}, + {'citation_bibcode': '2015PDSS..234.....N', ..., 'family': 'Beagle', ...}], + 'escaperoutes': [] + }) + """ + + self.query_type = 'all_astinfo' + + response = {} + + response['designations'] = self._request('GET', + url=self.URL + object_name + '/designations', + timeout=self.TIMEOUT, cache=cache) + + response['elements'] = self._request('GET', + url=self.URL + object_name + '/elements', + timeout=self.TIMEOUT, cache=cache) + + response['orbit'] = self._request('GET', + url=self.URL + object_name + '/orbit', + timeout=self.TIMEOUT, cache=cache) + + response['albedos'] = self._request('GET', + url=self.URL + object_name + '/data/albedos', + timeout=self.TIMEOUT, cache=cache) + + response['colors'] = self._request('GET', + url=self.URL + object_name + '/data/colors', + timeout=self.TIMEOUT, cache=cache) + + response['taxonomies'] = self._request('GET', + url=self.URL + object_name + '/data/taxonomies', + timeout=self.TIMEOUT, cache=cache) + + response['lightcurves'] = self._request('GET', + url=self.URL + object_name + '/data/lightcurves', + timeout=self.TIMEOUT, cache=cache) + + response['dynamicalfamily'] = self._request('GET', + url=self.URL + object_name + '/data/dynamical-family', + timeout=self.TIMEOUT, cache=cache) + + response['escaperoutes'] = self._request('GET', + url=self.URL + object_name + '/data/escape-routes', + timeout=self.TIMEOUT, cache=cache) + + if get_raw_response: + self._return_raw = True + + if get_uri: + self._uri = {'designations':response['designations'].url, + 'elements':response['elements'].url, + 'orbit':response['orbit'].url, + 'albedos':response['albedos'].url, + 'colors':response['colors'].url, + 'taxonomies':response['taxonomies'].url, + 'lightcurves':response['lightcurves'].url, + 'dynamicalfamily':response['dynamicalfamily'].url, + 'escaperoutes':response['escaperoutes'].url + } + + return response + + + def _parse_result(self, response, *, verbose=None): + """ + Parser for astorbDB AstInfo request results + """ + + if self._return_raw: + return response.text + + # decode json response from Lowell astorbDB into ascii + try: + if self.query_type == 'all_astinfo': + src = OrderedDict() + for key in response: + src[key] = OrderedDict(json.loads(response[key].text)) + else: + src = OrderedDict(json.loads(response.text)) + except ValueError: + raise ValueError('Server response not readable.') + + if self.query_type == 'designations': + src = self._process_data_designations(src) + + if self.query_type == 'elements': + src = self._process_data_elements(src) + + if self.query_type == 'orbit': + src = self._process_data_orbit(src) + + if self.query_type == 'albedos': + src = self._process_data_albedos(src) + + if self.query_type == 'colors': + src = self._process_data_colors(src) + + if self.query_type == 'taxonomies': + src = self._process_data_taxonomies(src) + + if self.query_type == 'lightcurves': + src = self._process_data_lightcurves(src) + + if self.query_type == 'dynamicalfamily': + src = self._process_data_dynamicalfamily(src) + + if self.query_type == 'escaperoutes': + src = self._process_data_escaperoutes(src) + + if self.query_type == 'all_astinfo': + src['designations'] = self._process_data_designations(src['designations']) + src['elements'] = self._process_data_elements(src['elements']) + src['orbit'] = self._process_data_orbit(src['orbit']) + src['albedos'] = self._process_data_albedos(src['albedos']) + src['colors'] = self._process_data_colors(src['colors']) + src['taxonomies'] = self._process_data_taxonomies(src['taxonomies']) + src['lightcurves'] = self._process_data_lightcurves(src['lightcurves']) + src['dynamicalfamily'] = self._process_data_dynamicalfamily(src['dynamicalfamily']) + src['escaperoutes'] = self._process_data_escaperoutes(src['escaperoutes']) + + # add query uri, if desired + if self._uri is not None: + src['query_uri'] = self._uri + + return src + + + + def _process_data_designations(self, src): + """ + internal routine to process raw data in OrderedDict format + + """ + + if 'designations' in src: + src = OrderedDict(src['designations']) + + return src + + + def _process_data_elements(self, src): + """ + internal routine to process raw data in OrderedDict format, must + be able to work recursively + + """ + + if 'elements' in src: + src = OrderedDict(src['elements']) + src['a'] = u.Quantity(src['a'], u.au) + src['aphelion_dist'] = u.Quantity(src['aphelion_dist'], u.au) + if src['delta_v'] is not None: + src['delta_v'] = u.Quantity(src['delta_v'], u.km/u.s) + src['ecc_anomaly'] = u.Quantity(src['ecc_anomaly'], u.deg) + src['epoch'] = Time(src['epoch'], format='isot', scale='utc') + src['h'] = u.Quantity(src['h'], u.mag) + src['i'] = u.Quantity(src['m'], u.deg) + src['long_of_perihelion'] = u.Quantity(src['long_of_perihelion'], u.deg) + src['m'] = u.Quantity(src['m'], u.deg) + src['moid_earth'] = u.Quantity(src['moid_earth'], u.au) + src['moid_jupiter'] = u.Quantity(src['moid_jupiter'], u.au) + src['moid_mars'] = u.Quantity(src['moid_mars'], u.au) + src['moid_mercury'] = u.Quantity(src['moid_mercury'], u.au) + src['moid_neptune'] = u.Quantity(src['moid_neptune'], u.au) + src['moid_saturn'] = u.Quantity(src['moid_saturn'], u.au) + src['moid_uranus'] = u.Quantity(src['moid_uranus'], u.au) + src['moid_venus'] = u.Quantity(src['moid_venus'], u.au) + src['node'] = u.Quantity(src['node'], u.deg) + src['peri'] = u.Quantity(src['peri'], u.deg) + src['q'] = u.Quantity(src['q'], u.au) + src['r'] = u.Quantity(src['r'], u.au) + src['true_anomaly'] = u.Quantity(src['true_anomaly'], u.deg) + src['x'] = u.Quantity(src['x'], u.au) + src['y'] = u.Quantity(src['y'], u.au) + src['z'] = u.Quantity(src['z'], u.au) + + return src + + + def _process_data_orbit(self, src): + """ + internal routine to process raw data in OrderedDict format, must + be able to work recursively + + """ + + if 'orbit' in src: + src = OrderedDict(src['orbit']) + src['a1con'] = u.Quantity(src['a1con'], u.au/(u.d ** 2)) + src['a2con'] = u.Quantity(src['a2con'], u.au/(u.d ** 2)) + src['a3con'] = u.Quantity(src['a3con'], u.au/(u.d ** 2)) + src['arc'] = u.Quantity(src['arc'], u.yr) + + return src + + + def _process_data_albedos(self, src): + """ + internal routine to process raw data in Dict format + + """ + + if 'albedos' in src: + src = src['albedos'] + for i in range(len(src)): + src[i]['diameter'] = u.Quantity(src[i]['diameter'], u.km) + src[i]['diameter_error_lower'] = u.Quantity(src[i]['diameter_error_lower'], u.km) + src[i]['diameter_error_upper'] = u.Quantity(src[i]['diameter_error_upper'], u.km) + + return src + + + def _process_data_colors(self, src): + """ + internal routine to process raw data in Dict format + + """ + + if 'colors' in src: + src = src['colors'] + for i in range(len(src)): + src[i]['jd'] = Time(src[i]['jd'], format='jd', scale='utc') + + return src + + + def _process_data_taxonomies(self, src): + """ + internal routine to process raw data in OrderedDict format, must + be able to work recursively + + """ + + if 'taxonomies' in src: + src = src['taxonomies'] + + return src + + + def _process_data_lightcurves(self, src): + """ + internal routine to process raw data in OrderedDict format, must + be able to work recursively + + """ + + if 'lightcurves' in src: + src = src['lightcurves'] + for i in range(len(src)): + if src[i]['amp_max'] is not None: + src[i]['amp_max'] = u.Quantity(src[i]['amp_max'], u.mag) + if src[i]['amp_min'] is not None: + src[i]['amp_min'] = u.Quantity(src[i]['amp_min'], u.mag) + src[i]['period'] = u.Quantity(src[i]['period'], u.h) + + return src + + + def _process_data_dynamicalfamily(self, src): + """ + internal routine to process raw data in OrderedDict format, must + be able to work recursively + + """ + + if 'dynamical-family' in src: + src = src['dynamical-family'] + + return src + + + def _process_data_escaperoutes(self, src): + """ + internal routine to process raw data in OrderedDict format, must + be able to work recursively + + """ + + if 'escape-routes' in src: + src = src['escape-routes'] + for i in range(len(src)): + src[i]['epoch'] = Time(src[i]['epoch'], format='isot', scale='utc') + + return src + + +AstInfo = AstInfoClass() + +# once your class is done, tests should be written +# See ./tests for examples on this + +# Next you should write the docs in astroquery/docs/module_name +# using Sphinx. diff --git a/astroquery/astorbdb/tests/__init__.py b/astroquery/astorbdb/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/astroquery/astorbdb/tests/data/dummy.dat b/astroquery/astorbdb/tests/data/dummy.dat new file mode 100644 index 0000000000..aa5bd30df5 --- /dev/null +++ b/astroquery/astorbdb/tests/data/dummy.dat @@ -0,0 +1,2 @@ +this is a dummy data file. +Similarly include xml, html, fits and other data files for tests diff --git a/astroquery/astorbdb/tests/setup_package.py b/astroquery/astorbdb/tests/setup_package.py new file mode 100644 index 0000000000..72b8669485 --- /dev/null +++ b/astroquery/astorbdb/tests/setup_package.py @@ -0,0 +1,15 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst + + +import os + + +# setup paths to the test data +# can specify a single file or a list of files +def get_package_data(): + paths = [os.path.join('data', '*.dat'), + os.path.join('data', '*.xml'), + ] # etc, add other extensions + # you can also enlist files individually by names + # finally construct and return a dict for the sub module + return {'astroquery.template_module.tests': paths} diff --git a/astroquery/astorbdb/tests/test_module.py b/astroquery/astorbdb/tests/test_module.py new file mode 100644 index 0000000000..f2574589e1 --- /dev/null +++ b/astroquery/astorbdb/tests/test_module.py @@ -0,0 +1,80 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst + +# astroquery uses the pytest framework for testing +# this is already available in astropy and does +# not require a separate install. Import it using: +import pytest + +# It would be best if tests are separated in two +# modules. This module performs tests on local data +# by mocking HTTP requests and responses. To test the +# same functions on the remote server, put the relevant +# tests in the 'test_module_remote.py' + +# Now import other commonly used modules for tests +import os + +from astropy.table import Table +import astropy.coordinates as coord +import astropy.units as u + +from astroquery.utils.mocks import MockResponse + +# finally import the module which is to be tested +# and the various configuration items created +from ... import template_module +from ...template_module import conf + +# Local tests should have the corresponding data stored +# in the ./data folder. This is the actual HTTP response +# one would expect from the server when a valid query is made. +# Its best to keep the data file small, so that testing is +# quicker. When running tests locally the stored data is used +# to mock the HTTP requests and response part of the query +# thereby saving time and bypassing unreliability for +# an actual remote network query. + +DATA_FILES = {'GET': + # You might have a different response for each URL you're + # querying: + {'http://dummy_server_mirror_1': + 'dummy.dat'}} + + +# ./setup_package.py helps the test function locate the data file +# define a function that can construct the full path to the file in the +# ./data directory: +def data_path(filename): + data_dir = os.path.join(os.path.dirname(__file__), 'data') + return os.path.join(data_dir, filename) + + +# define a monkeypatch replacement request function that returns the +# dummy HTTP response for the dummy 'get' function, by +# reading in data from some data file: +def nonremote_request(self, request_type, url, **kwargs): + # kwargs are ignored in this case, but they don't have to be + # (you could use them to define which data file to read) + with open(data_path(DATA_FILES[request_type][url]), 'rb') as f: + response = MockResponse(content=f.read(), url=url) + return response + + +# use a pytest fixture to create a dummy 'requests.get' function, +# that mocks(monkeypatches) the actual 'requests.get' function: +@pytest.fixture +def patch_request(request): + mp = request.getfixturevalue("monkeypatch") + + mp.setattr(template_module.core.TemplateClass, '_request', + nonremote_request) + return mp + + +# finally test the methods using the mock HTTP response +def test_query_object(patch_request): + result = template_module.core.TemplateClass().query_object('m1') + assert isinstance(result, Table) + +# similarly fill in tests for each of the methods +# look at tests in existing modules for more examples diff --git a/astroquery/astorbdb/tests/test_module_remote.py b/astroquery/astorbdb/tests/test_module_remote.py new file mode 100644 index 0000000000..ca7ba46800 --- /dev/null +++ b/astroquery/astorbdb/tests/test_module_remote.py @@ -0,0 +1,16 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst + + +# performs similar tests as test_module.py, but performs +# the actual HTTP request rather than monkeypatching them. +# should be disabled or enabled at will - use the +# remote_data decorator from astropy: + +import pytest + + +@pytest.mark.remote_data +class TestTemplateClass: + # now write tests for each method here + def test_this(self): + pass From 40e8902aa7934ca75fce545c82eb543c18349794 Mon Sep 17 00:00:00 2001 From: hhsieh00 Date: Tue, 4 Feb 2025 10:31:15 -1000 Subject: [PATCH 2/4] Fixing some codestyle issues in core.py Fixing some codestyle issues in core.py --- astroquery/astorbdb/core.py | 172 +++++++++++++++--------------------- 1 file changed, 72 insertions(+), 100 deletions(-) diff --git a/astroquery/astorbdb/core.py b/astroquery/astorbdb/core.py index d713d69ef0..27dba2846f 100644 --- a/astroquery/astorbdb/core.py +++ b/astroquery/astorbdb/core.py @@ -1,27 +1,20 @@ # Licensed under a 3-clause BSD style license - see LICENSE.rst import astropy.units as u -import astropy.coordinates as coord -import astropy.io.votable as votable -import warnings -from astropy.table import Table from astropy.time import Time -from astropy.io import fits import json from collections import OrderedDict from ..query import BaseQuery -from ..utils import commons from ..utils import async_to_sync from . import conf __all__ = ['AstInfo', 'AstInfoClass'] + @async_to_sync class AstInfoClass(BaseQuery): - ## NEED TO ADD EXAMPLE OUTPUT TO ALL METHODS ## - """ A class for querying Lowell Observatory's `astorbDB `_ service. @@ -39,7 +32,7 @@ class AstInfoClass(BaseQuery): # actual query uri _uri = None - def designations_async(self,object_name, *, + def designations_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -47,15 +40,15 @@ def designations_async(self,object_name, *, This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for designation data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- - res : A dictionary holding available color data + res : A dictionary holding available designation data Examples -------- @@ -66,7 +59,7 @@ def designations_async(self,object_name, *, """ self.query_type = 'designations' - + response = self._request('GET', url=self.URL + object_name + '/designations', timeout=self.TIMEOUT, cache=cache) @@ -76,27 +69,26 @@ def designations_async(self,object_name, *, if get_uri: self._uri = response.url - + return response - - def elements_async(self,object_name, *, + def elements_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): """ This method uses a REST interface to query the `Lowell Observatory - astorbDB database `_ for designation + astorbDB database `_ for orbital element data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- - res : A dictionary holding available color data + res : A dictionary holding available orbital element data Examples -------- @@ -107,7 +99,7 @@ def elements_async(self,object_name, *, """ self.query_type = 'elements' - + response = self._request('GET', url=self.URL + object_name + '/elements', timeout=self.TIMEOUT, cache=cache) @@ -117,11 +109,10 @@ def elements_async(self,object_name, *, if get_uri: self._uri = response.url - + return response - - def orbit_async(self,object_name, *, + def orbit_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -129,12 +120,12 @@ def orbit_async(self,object_name, *, This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for orbit data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- res : A dictionary holding available orbit data @@ -148,21 +139,20 @@ def orbit_async(self,object_name, *, """ self.query_type = 'orbit' - + response = self._request('GET', url=self.URL + object_name + '/orbit', timeout=self.TIMEOUT, cache=cache) - + if get_raw_response: self._return_raw = True if get_uri: self._uri = response.url - + return response - - def albedos_async(self,object_name, *, + def albedos_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -170,12 +160,12 @@ def albedos_async(self,object_name, *, This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for albedo data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- res : A dictionary holding available albedo data @@ -191,21 +181,20 @@ def albedos_async(self,object_name, *, """ self.query_type = 'albedos' - + response = self._request('GET', url=self.URL + object_name + '/data/albedos', timeout=self.TIMEOUT, cache=cache) - + if get_raw_response: self._return_raw = True if get_uri: self._uri = response.url - - return response + return response - def colors_async(self,object_name, *, + def colors_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -213,12 +202,12 @@ def colors_async(self,object_name, *, This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for color data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- res : A dictionary holding available color data @@ -234,11 +223,11 @@ def colors_async(self,object_name, *, """ self.query_type = 'colors' - + response = self._request('GET', url=self.URL + object_name + '/data/colors', timeout=self.TIMEOUT, cache=cache) - + if get_raw_response: self._return_raw = True @@ -247,8 +236,7 @@ def colors_async(self,object_name, *, return response - - def taxonomies_async(self,object_name, *, + def taxonomies_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -256,12 +244,12 @@ def taxonomies_async(self,object_name, *, This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for taxonomy data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- res : A dictionary holding available taxonomy data @@ -276,21 +264,20 @@ def taxonomies_async(self,object_name, *, """ self.query_type = 'taxonomies' - + response = self._request('GET', url=self.URL + object_name + '/data/taxonomies', timeout=self.TIMEOUT, cache=cache) - + if get_raw_response: self._return_raw = True if get_uri: self._uri = response.url - + return response - - def lightcurves_async(self,object_name, *, + def lightcurves_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -298,12 +285,12 @@ def lightcurves_async(self,object_name, *, This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for lightcurve data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- res : A dictionary holding available lightcurve data @@ -317,21 +304,20 @@ def lightcurves_async(self,object_name, *, """ self.query_type = 'lightcurves' - + response = self._request('GET', url=self.URL + object_name + '/data/lightcurves', timeout=self.TIMEOUT, cache=cache) - + if get_raw_response: self._return_raw = True if get_uri: self._uri = response.url - - return response + return response - def dynamicalfamily_async(self,object_name, *, + def dynamicalfamily_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -339,12 +325,12 @@ def dynamicalfamily_async(self,object_name, *, This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for dynamical family data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- res : A dictionary holding available dynamical family data @@ -359,21 +345,20 @@ def dynamicalfamily_async(self,object_name, *, """ self.query_type = 'dynamicalfamily' - + response = self._request('GET', url=self.URL + object_name + '/data/dynamical-family', timeout=self.TIMEOUT, cache=cache) - + if get_raw_response: self._return_raw = True if get_uri: self._uri = response.url - + return response - - def escaperoutes_async(self,object_name, *, + def escaperoutes_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -381,12 +366,12 @@ def escaperoutes_async(self,object_name, *, This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for NEO escape route data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- res : A dictionary holding available NEO escape route data @@ -400,7 +385,7 @@ def escaperoutes_async(self,object_name, *, """ self.query_type = 'escaperoutes' - + response = self._request('GET', url=self.URL + object_name + '/data/escape-routes', timeout=self.TIMEOUT, cache=cache) @@ -410,27 +395,26 @@ def escaperoutes_async(self,object_name, *, if get_uri: self._uri = response.url - - return response + return response - def all_astinfo_async(self,object_name, *, + def all_astinfo_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): """ - This method uses a REST interface to query the `Lowell Observatory - astorbDB database `_ for NEO escape route + This method uses REST interfaces to query the `Lowell Observatory + astorbDB database `_ for all AstInfo data for a single object and returns a dictionary from JSON results - + Parameters ---------- object_name : str name of the identifier to query. - + Returns ------- - res : A dictionary holding available NEO escape route data + res : A dictionary holding available AstInfo data Examples -------- @@ -459,23 +443,23 @@ def all_astinfo_async(self,object_name, *, self.query_type = 'all_astinfo' response = {} - + response['designations'] = self._request('GET', url=self.URL + object_name + '/designations', timeout=self.TIMEOUT, cache=cache) - + response['elements'] = self._request('GET', url=self.URL + object_name + '/elements', timeout=self.TIMEOUT, cache=cache) - + response['orbit'] = self._request('GET', url=self.URL + object_name + '/orbit', timeout=self.TIMEOUT, cache=cache) - + response['albedos'] = self._request('GET', url=self.URL + object_name + '/data/albedos', timeout=self.TIMEOUT, cache=cache) - + response['colors'] = self._request('GET', url=self.URL + object_name + '/data/colors', timeout=self.TIMEOUT, cache=cache) @@ -510,9 +494,8 @@ def all_astinfo_async(self,object_name, *, 'dynamicalfamily':response['dynamicalfamily'].url, 'escaperoutes':response['escaperoutes'].url } - - return response + return response def _parse_result(self, response, *, verbose=None): """ @@ -541,7 +524,7 @@ def _parse_result(self, response, *, verbose=None): if self.query_type == 'orbit': src = self._process_data_orbit(src) - + if self.query_type == 'albedos': src = self._process_data_albedos(src) @@ -577,8 +560,6 @@ def _parse_result(self, response, *, verbose=None): return src - - def _process_data_designations(self, src): """ internal routine to process raw data in OrderedDict format @@ -590,7 +571,6 @@ def _process_data_designations(self, src): return src - def _process_data_elements(self, src): """ internal routine to process raw data in OrderedDict format, must @@ -629,23 +609,21 @@ def _process_data_elements(self, src): return src - def _process_data_orbit(self, src): """ internal routine to process raw data in OrderedDict format, must be able to work recursively """ - + if 'orbit' in src: src = OrderedDict(src['orbit']) src['a1con'] = u.Quantity(src['a1con'], u.au/(u.d ** 2)) src['a2con'] = u.Quantity(src['a2con'], u.au/(u.d ** 2)) src['a3con'] = u.Quantity(src['a3con'], u.au/(u.d ** 2)) src['arc'] = u.Quantity(src['arc'], u.yr) - - return src + return src def _process_data_albedos(self, src): """ @@ -659,9 +637,8 @@ def _process_data_albedos(self, src): src[i]['diameter'] = u.Quantity(src[i]['diameter'], u.km) src[i]['diameter_error_lower'] = u.Quantity(src[i]['diameter_error_lower'], u.km) src[i]['diameter_error_upper'] = u.Quantity(src[i]['diameter_error_upper'], u.km) - - return src + return src def _process_data_colors(self, src): """ @@ -673,9 +650,8 @@ def _process_data_colors(self, src): src = src['colors'] for i in range(len(src)): src[i]['jd'] = Time(src[i]['jd'], format='jd', scale='utc') - - return src + return src def _process_data_taxonomies(self, src): """ @@ -689,7 +665,6 @@ def _process_data_taxonomies(self, src): return src - def _process_data_lightcurves(self, src): """ internal routine to process raw data in OrderedDict format, must @@ -705,9 +680,8 @@ def _process_data_lightcurves(self, src): if src[i]['amp_min'] is not None: src[i]['amp_min'] = u.Quantity(src[i]['amp_min'], u.mag) src[i]['period'] = u.Quantity(src[i]['period'], u.h) - - return src + return src def _process_data_dynamicalfamily(self, src): """ @@ -721,7 +695,6 @@ def _process_data_dynamicalfamily(self, src): return src - def _process_data_escaperoutes(self, src): """ internal routine to process raw data in OrderedDict format, must @@ -736,7 +709,6 @@ def _process_data_escaperoutes(self, src): return src - AstInfo = AstInfoClass() # once your class is done, tests should be written From 574f865387c356ac25e2b88eeceebc9f144c397b Mon Sep 17 00:00:00 2001 From: hhsieh00 Date: Tue, 4 Feb 2025 10:44:20 -1000 Subject: [PATCH 3/4] fixing more codestyle issues in core.py fixing more codestyle issues in core.py --- astroquery/astorbdb/core.py | 122 ++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/astroquery/astorbdb/core.py b/astroquery/astorbdb/core.py index 27dba2846f..ed2ce7c15a 100644 --- a/astroquery/astorbdb/core.py +++ b/astroquery/astorbdb/core.py @@ -55,14 +55,14 @@ def designations_async(self, object_name, *, >>> from astroquery.astorbdb import AstInfo >>> designations = AstInfo.designations('Beagle') >>> print(designations) - OrderedDict({'alternate_designations': ['1954 HJ', 'A908 BJ', 'A917 ST'], 'name': 'Beagle', 'number': 656, 'primary_designation': 'Beagle'}) + OrderedDict({'alternate_designations': ['1954 HJ', ...], 'name': 'Beagle', 'number': 656, ...}) """ self.query_type = 'designations' response = self._request('GET', - url=self.URL + object_name + '/designations', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/designations', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -73,9 +73,9 @@ def designations_async(self, object_name, *, return response def elements_async(self, object_name, *, - get_raw_response=False, - get_uri=False, - cache=True): + get_raw_response=False, + get_uri=False, + cache=True): """ This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for orbital element @@ -101,8 +101,8 @@ def elements_async(self, object_name, *, self.query_type = 'elements' response = self._request('GET', - url=self.URL + object_name + '/elements', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/elements', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -135,14 +135,14 @@ def orbit_async(self, object_name, *, >>> from astroquery.astorbdb import AstInfo >>> orbit = AstInfo.orbit('Beagle') >>> print(orbit) - OrderedDict({'a1con': , 'a2con': , 'a3con': , ...}) + OrderedDict({'a1con': , 'a2con': , ...}) """ self.query_type = 'orbit' response = self._request('GET', - url=self.URL + object_name + '/orbit', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/orbit', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -153,9 +153,9 @@ def orbit_async(self, object_name, *, return response def albedos_async(self, object_name, *, - get_raw_response=False, - get_uri=False, - cache=True): + get_raw_response=False, + get_uri=False, + cache=True): """ This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for albedo @@ -183,8 +183,8 @@ def albedos_async(self, object_name, *, self.query_type = 'albedos' response = self._request('GET', - url=self.URL + object_name + '/data/albedos', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/albedos', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -195,9 +195,9 @@ def albedos_async(self, object_name, *, return response def colors_async(self, object_name, *, - get_raw_response=False, - get_uri=False, - cache=True): + get_raw_response=False, + get_uri=False, + cache=True): """ This method uses a REST interface to query the `Lowell Observatory astorbDB database `_ for color @@ -217,8 +217,8 @@ def colors_async(self, object_name, *, >>> from astroquery.astorbdb import AstInfo >>> colors = AstInfo.colors('Beagle') >>> print(colors) - [{'citation_bibcode': '2010PDSS..125.....S', ..., 'color': 0.431, 'color_error': 0.035, ..., 'sys_color': 'J-H'}, - {'citation_bibcode': '2010PDSS..125.....S', ..., 'color': 0.076, 'color_error': 0.041, ..., 'sys_color': 'H-K'}, + [{..., 'color': 0.431, 'color_error': 0.035, ..., 'sys_color': 'J-H'}, + {..., 'color': 0.076, 'color_error': 0.041, ..., 'sys_color': 'H-K'}, ...] """ @@ -266,8 +266,8 @@ def taxonomies_async(self, object_name, *, self.query_type = 'taxonomies' response = self._request('GET', - url=self.URL + object_name + '/data/taxonomies', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/taxonomies', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -300,14 +300,14 @@ def lightcurves_async(self, object_name, *, >>> from astroquery.astorbdb import AstInfo >>> lightcurves = AstInfo.lightcurves('Beagle') >>> print(lightcurves) - [{'ambiguous_period': False, ..., 'amp_max': , 'amp_min': , ..., 'period': , ...}] + [{..., 'amp_max': , 'amp_min': , ..., 'period': , ...}] """ self.query_type = 'lightcurves' response = self._request('GET', - url=self.URL + object_name + '/data/lightcurves', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/lightcurves', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -347,8 +347,8 @@ def dynamicalfamily_async(self, object_name, *, self.query_type = 'dynamicalfamily' response = self._request('GET', - url=self.URL + object_name + '/data/dynamical-family', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/dynamical-family', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -387,8 +387,8 @@ def escaperoutes_async(self, object_name, *, self.query_type = 'escaperoutes' response = self._request('GET', - url=self.URL + object_name + '/data/escape-routes', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/escape-routes', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -399,9 +399,9 @@ def escaperoutes_async(self, object_name, *, return response def all_astinfo_async(self, object_name, *, - get_raw_response=False, - get_uri=False, - cache=True): + get_raw_response=False, + get_uri=False, + cache=True): """ This method uses REST interfaces to query the `Lowell Observatory astorbDB database `_ for all AstInfo @@ -421,19 +421,20 @@ def all_astinfo_async(self, object_name, *, >>> from astroquery.astorbdb import AstInfo >>> all_astinfo = AstInfo.all_astinfo('Beagle') >>> print(all_astinfo) + OrderedDict({ - 'designations': OrderedDict({'alternate_designations': ['1954 HJ', 'A908 BJ', 'A917 ST'], 'name': 'Beagle', ...}), + 'designations': OrderedDict({'alternate_designations': ['1954 HJ', ...], 'name': 'Beagle', ...}), 'elements': OrderedDict({'a': , 'aphelion_dist': , ...}), - 'orbit': OrderedDict({'a1con': , 'a2con': , 'a3con': , ...}), - 'albedos': [{'albedo': 0.065, 'albedo_error_lower': -0.002, 'albedo_error_upper': 0.002, ..., 'survey_name': 'Usui et al. (2011)'}, - {'albedo': 0.0625, 'albedo_error_lower': -0.015, 'albedo_error_upper': 0.015, ..., 'survey_name': 'Infrared Astronomical Satellite (IRAS)'}, + 'orbit': OrderedDict({'a1con': , 'a2con': , ...}), + 'albedos': [{'albedo': 0.065, ..., 'survey_name': 'Usui et al. (2011)'}, + {'albedo': 0.0625, ..., 'survey_name': 'Infrared Astronomical Satellite (IRAS)'}, ...], - 'colors': [{'citation_bibcode': '2010PDSS..125.....S', ..., 'color': 0.431, 'color_error': 0.035, ..., 'sys_color': 'J-H'}, - {'citation_bibcode': '2010PDSS..125.....S', ..., 'color': 0.076, 'color_error': 0.041, ..., 'sys_color': 'H-K'}, + 'colors': [{..., 'color': 0.431, 'color_error': 0.035, ..., 'sys_color': 'J-H'}, + {..., 'color': 0.076, 'color_error': 0.041, ..., 'sys_color': 'H-K'}, ...], - 'taxonomies': [{'citation_bibcode': '2011PDSS..145.....H', ..., 'survey_name': 'Carvano et al. (2010)', 'taxonomy': 'C', ...}, - {'citation_bibcode': '2013Icar..226..723D', ..., 'survey_name': 'DeMeo et al. (2013)', 'taxonomy': 'C', ...}], - 'lightcurves': [{'ambiguous_period': False, ..., 'amp_max': , 'amp_min': , ..., 'period': , ...}], + 'taxonomies': [{..., 'survey_name': 'Carvano et al. (2010)', 'taxonomy': 'C', ...}, + {..., 'survey_name': 'DeMeo et al. (2013)', 'taxonomy': 'C', ...}], + 'lightcurves': [{..., 'amp_max': , ..., 'period': , ...}], 'dynamicalfamily': [{'citation_bibcode': '2015PDSS..234.....N', ..., 'family': 'Themis', ...}, {'citation_bibcode': '2015PDSS..234.....N', ..., 'family': 'Beagle', ...}], 'escaperoutes': [] @@ -445,40 +446,40 @@ def all_astinfo_async(self, object_name, *, response = {} response['designations'] = self._request('GET', - url=self.URL + object_name + '/designations', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/designations', + timeout=self.TIMEOUT, cache=cache) response['elements'] = self._request('GET', - url=self.URL + object_name + '/elements', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/elements', + timeout=self.TIMEOUT, cache=cache) response['orbit'] = self._request('GET', - url=self.URL + object_name + '/orbit', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/orbit', + timeout=self.TIMEOUT, cache=cache) response['albedos'] = self._request('GET', - url=self.URL + object_name + '/data/albedos', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/albedos', + timeout=self.TIMEOUT, cache=cache) response['colors'] = self._request('GET', - url=self.URL + object_name + '/data/colors', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/colors', + timeout=self.TIMEOUT, cache=cache) response['taxonomies'] = self._request('GET', - url=self.URL + object_name + '/data/taxonomies', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/taxonomies', + timeout=self.TIMEOUT, cache=cache) response['lightcurves'] = self._request('GET', - url=self.URL + object_name + '/data/lightcurves', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/lightcurves', + timeout=self.TIMEOUT, cache=cache) response['dynamicalfamily'] = self._request('GET', - url=self.URL + object_name + '/data/dynamical-family', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/dynamical-family', + timeout=self.TIMEOUT, cache=cache) response['escaperoutes'] = self._request('GET', - url=self.URL + object_name + '/data/escape-routes', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/escape-routes', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -709,6 +710,7 @@ def _process_data_escaperoutes(self, src): return src + AstInfo = AstInfoClass() # once your class is done, tests should be written From 755b5c913fa5327d1fa19956d4f66b57e01cb00e Mon Sep 17 00:00:00 2001 From: hhsieh00 Date: Tue, 4 Feb 2025 10:50:02 -1000 Subject: [PATCH 4/4] more codestyle issue fixes --- astroquery/astorbdb/core.py | 100 ++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/astroquery/astorbdb/core.py b/astroquery/astorbdb/core.py index ed2ce7c15a..4a40735870 100644 --- a/astroquery/astorbdb/core.py +++ b/astroquery/astorbdb/core.py @@ -225,8 +225,8 @@ def colors_async(self, object_name, *, self.query_type = 'colors' response = self._request('GET', - url=self.URL + object_name + '/data/colors', - timeout=self.TIMEOUT, cache=cache) + url=self.URL + object_name + '/data/colors', + timeout=self.TIMEOUT, cache=cache) if get_raw_response: self._return_raw = True @@ -277,7 +277,7 @@ def taxonomies_async(self, object_name, *, return response - def lightcurves_async(self, object_name, *, + def lightcurves_async(self, object_name, *, get_raw_response=False, get_uri=False, cache=True): @@ -485,16 +485,16 @@ def all_astinfo_async(self, object_name, *, self._return_raw = True if get_uri: - self._uri = {'designations':response['designations'].url, - 'elements':response['elements'].url, - 'orbit':response['orbit'].url, - 'albedos':response['albedos'].url, - 'colors':response['colors'].url, - 'taxonomies':response['taxonomies'].url, - 'lightcurves':response['lightcurves'].url, - 'dynamicalfamily':response['dynamicalfamily'].url, - 'escaperoutes':response['escaperoutes'].url - } + self._uri = {'designations': response['designations'].url, + 'elements': response['elements'].url, + 'orbit': response['orbit'].url, + 'albedos': response['albedos'].url, + 'colors': response['colors'].url, + 'taxonomies': response['taxonomies'].url, + 'lightcurves': response['lightcurves'].url, + 'dynamicalfamily': response['dynamicalfamily'].url, + 'escaperoutes': response['escaperoutes'].url + } return response @@ -545,15 +545,15 @@ def _parse_result(self, response, *, verbose=None): src = self._process_data_escaperoutes(src) if self.query_type == 'all_astinfo': - src['designations'] = self._process_data_designations(src['designations']) - src['elements'] = self._process_data_elements(src['elements']) - src['orbit'] = self._process_data_orbit(src['orbit']) - src['albedos'] = self._process_data_albedos(src['albedos']) - src['colors'] = self._process_data_colors(src['colors']) - src['taxonomies'] = self._process_data_taxonomies(src['taxonomies']) - src['lightcurves'] = self._process_data_lightcurves(src['lightcurves']) + src['designations'] = self._process_data_designations(src['designations']) + src['elements'] = self._process_data_elements(src['elements']) + src['orbit'] = self._process_data_orbit(src['orbit']) + src['albedos'] = self._process_data_albedos(src['albedos']) + src['colors'] = self._process_data_colors(src['colors']) + src['taxonomies'] = self._process_data_taxonomies(src['taxonomies']) + src['lightcurves'] = self._process_data_lightcurves(src['lightcurves']) src['dynamicalfamily'] = self._process_data_dynamicalfamily(src['dynamicalfamily']) - src['escaperoutes'] = self._process_data_escaperoutes(src['escaperoutes']) + src['escaperoutes'] = self._process_data_escaperoutes(src['escaperoutes']) # add query uri, if desired if self._uri is not None: @@ -581,32 +581,32 @@ def _process_data_elements(self, src): if 'elements' in src: src = OrderedDict(src['elements']) - src['a'] = u.Quantity(src['a'], u.au) - src['aphelion_dist'] = u.Quantity(src['aphelion_dist'], u.au) + src['a'] = u.Quantity(src['a'], u.au) + src['aphelion_dist'] = u.Quantity(src['aphelion_dist'], u.au) if src['delta_v'] is not None: - src['delta_v'] = u.Quantity(src['delta_v'], u.km/u.s) - src['ecc_anomaly'] = u.Quantity(src['ecc_anomaly'], u.deg) - src['epoch'] = Time(src['epoch'], format='isot', scale='utc') - src['h'] = u.Quantity(src['h'], u.mag) - src['i'] = u.Quantity(src['m'], u.deg) + src['delta_v'] = u.Quantity(src['delta_v'], u.km/u.s) + src['ecc_anomaly'] = u.Quantity(src['ecc_anomaly'], u.deg) + src['epoch'] = Time(src['epoch'], format='isot', scale='utc') + src['h'] = u.Quantity(src['h'], u.mag) + src['i'] = u.Quantity(src['m'], u.deg) src['long_of_perihelion'] = u.Quantity(src['long_of_perihelion'], u.deg) - src['m'] = u.Quantity(src['m'], u.deg) - src['moid_earth'] = u.Quantity(src['moid_earth'], u.au) - src['moid_jupiter'] = u.Quantity(src['moid_jupiter'], u.au) - src['moid_mars'] = u.Quantity(src['moid_mars'], u.au) - src['moid_mercury'] = u.Quantity(src['moid_mercury'], u.au) - src['moid_neptune'] = u.Quantity(src['moid_neptune'], u.au) - src['moid_saturn'] = u.Quantity(src['moid_saturn'], u.au) - src['moid_uranus'] = u.Quantity(src['moid_uranus'], u.au) - src['moid_venus'] = u.Quantity(src['moid_venus'], u.au) - src['node'] = u.Quantity(src['node'], u.deg) - src['peri'] = u.Quantity(src['peri'], u.deg) - src['q'] = u.Quantity(src['q'], u.au) - src['r'] = u.Quantity(src['r'], u.au) - src['true_anomaly'] = u.Quantity(src['true_anomaly'], u.deg) - src['x'] = u.Quantity(src['x'], u.au) - src['y'] = u.Quantity(src['y'], u.au) - src['z'] = u.Quantity(src['z'], u.au) + src['m'] = u.Quantity(src['m'], u.deg) + src['moid_earth'] = u.Quantity(src['moid_earth'], u.au) + src['moid_jupiter'] = u.Quantity(src['moid_jupiter'], u.au) + src['moid_mars'] = u.Quantity(src['moid_mars'], u.au) + src['moid_mercury'] = u.Quantity(src['moid_mercury'], u.au) + src['moid_neptune'] = u.Quantity(src['moid_neptune'], u.au) + src['moid_saturn'] = u.Quantity(src['moid_saturn'], u.au) + src['moid_uranus'] = u.Quantity(src['moid_uranus'], u.au) + src['moid_venus'] = u.Quantity(src['moid_venus'], u.au) + src['node'] = u.Quantity(src['node'], u.deg) + src['peri'] = u.Quantity(src['peri'], u.deg) + src['q'] = u.Quantity(src['q'], u.au) + src['r'] = u.Quantity(src['r'], u.au) + src['true_anomaly'] = u.Quantity(src['true_anomaly'], u.deg) + src['x'] = u.Quantity(src['x'], u.au) + src['y'] = u.Quantity(src['y'], u.au) + src['z'] = u.Quantity(src['z'], u.au) return src @@ -619,10 +619,10 @@ def _process_data_orbit(self, src): if 'orbit' in src: src = OrderedDict(src['orbit']) - src['a1con'] = u.Quantity(src['a1con'], u.au/(u.d ** 2)) - src['a2con'] = u.Quantity(src['a2con'], u.au/(u.d ** 2)) - src['a3con'] = u.Quantity(src['a3con'], u.au/(u.d ** 2)) - src['arc'] = u.Quantity(src['arc'], u.yr) + src['a1con'] = u.Quantity(src['a1con'], u.au/(u.d ** 2)) + src['a2con'] = u.Quantity(src['a2con'], u.au/(u.d ** 2)) + src['a3con'] = u.Quantity(src['a3con'], u.au/(u.d ** 2)) + src['arc'] = u.Quantity(src['arc'], u.yr) return src @@ -680,7 +680,7 @@ def _process_data_lightcurves(self, src): src[i]['amp_max'] = u.Quantity(src[i]['amp_max'], u.mag) if src[i]['amp_min'] is not None: src[i]['amp_min'] = u.Quantity(src[i]['amp_min'], u.mag) - src[i]['period'] = u.Quantity(src[i]['period'], u.h) + src[i]['period'] = u.Quantity(src[i]['period'], u.h) return src