diff --git a/astroquery/nasa_ads/__init__.py b/astroquery/nasa_ads/__init__.py new file mode 100644 index 0000000000..f5cf998f7e --- /dev/null +++ b/astroquery/nasa_ads/__init__.py @@ -0,0 +1,62 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst +""" +SAO/NASA ADS Query Tool +----------------------------------- + +:Author: Magnus Vilhelm Persson (magnusp@vilhelm.nu) + +""" + +from astropy import config as _config + + +class Conf(_config.ConfigNamespace): + """ + Configuration parameters for `astroquery.nasa_ads`. + """ + + server = _config.ConfigItem( + 'http://adswww.harvard.edu', + 'SAO/NASA ADS main server.' + ) + mirrors = _config.ConfigItem( + ['http://cdsads.u-strasbg.fr', + 'http://ukads.nottingham.ac.uk', + 'http://esoads.eso.org', + 'http://ads.ari.uni-heidelberg.de', + 'http://ads.inasan.ru', + 'http://ads.mao.kiev.ua', + 'http://ads.astro.puc.cl', + 'http://ads.nao.ac.jp', + 'http://ads.bao.ac.cn', + 'http://ads.iucaa.ernet.in', + 'http://ads.arsip.lipi.go.id', + 'http://saaoads.chpc.ac.za', + 'http://ads.on.br'], + 'SAO/NASA ADS mirrors around the world' + ) + advanced_path = _config.ConfigItem( + '/cgi-bin/nph-abs_connect', + 'Path for advanced query (unconfirmed)' + ) + simple_path = _config.ConfigItem( + '/cgi-bin/basic_connect', + 'Path for simple query (return XML)' + ) + timeout = _config.ConfigItem( + 120, + 'Time limit for connecting to ADS server' + ) + +conf = Conf() + + +conf.adsfields = ['bibcode', 'title', 'author', 'affiliation', + 'journal', 'volume', 'pubdate', 'page', 'lastpage', 'keywords', 'keyword', + 'origin', 'copyright', 'link', 'name', 'url', 'count', 'score', 'citations', + 'abstract', 'doi', 'eprintid'] + +from .core import ADSClass, ADS + +__all__ = ['ADSClass', 'ADS', + 'Conf', 'conf'] diff --git a/astroquery/nasa_ads/core.py b/astroquery/nasa_ads/core.py new file mode 100644 index 0000000000..b93f155b4d --- /dev/null +++ b/astroquery/nasa_ads/core.py @@ -0,0 +1,102 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst +""" +Module to search the SAO/NASA Astrophysics Data System + +:author: Magnus Persson + +""" + +import warnings +from ..query import BaseQuery +from ..utils import commons, async_to_sync +from . import conf +from astropy.table import Table, Column + +from ..utils.class_or_instance import class_or_instance +from ..utils import commons, async_to_sync +from .utils import * + +from xml.dom import minidom + +__all__ = ['ADS', 'ADSClass'] + +@async_to_sync +class ADSClass(BaseQuery): + + SERVER = conf.server + QUERY_ADVANCED_PATH = conf.advanced_path + QUERY_SIMPLE_PATH = conf.simple_path + TIMEOUT = conf.timeout + + QUERY_SIMPLE_URL = SERVER + QUERY_SIMPLE_PATH + QUERY_ADVANCED_URL = SERVER + QUERY_ADVANCED_PATH + + def __init__(self, *args): + """ set some parameters """ + pass + + @class_or_instance + def query_simple(self, query_string, get_query_payload=False, get_raw_response=False): + self.query_string = query_string + request_payload = self._args_to_payload(query_string) + + response = commons.send_request(self.QUERY_SIMPLE_URL, request_payload, self.TIMEOUT) + + # primarily for debug purposes, but also useful if you want to send + # someone a URL linking directly to the data + if get_query_payload: + return request_payload + if get_raw_response: + return response + # parse the XML response into AstroPy Table + resulttable = self._parse_response(response.encode(results.encoding).decode('utf-8')) + + return resulttable + + def _parse_response(self, response): + xmlrepr = minidom.parseString(response.text) + # Check if there are any results! + + # get the list of hits + hitlist = xmlrepr.childNodes[0].childNodes + hitlist = hitlist[1::2] # every second hit is a "line break" + + # Grab the various fields + titles = _get_data_from_xml(hitlist, 'title') + bibcode = _get_data_from_xml(hitlist, 'bibcode') + journal = _get_data_from_xml(hitlist, 'journal') + volume = _get_data_from_xml(hitlist, 'volume') + pubdate = _get_data_from_xml(hitlist, 'pubdate') + page = _get_data_from_xml(hitlist, 'page') + score = _get_data_from_xml(hitlist, 'score') + citations = _get_data_from_xml(hitlist, 'citations') + abstract = _get_data_from_xml(hitlist, 'abstract') + doi = _get_data_from_xml(hitlist, 'DOI') + eprintid = _get_data_from_xml(hitlist, 'eprintid') + authors = _get_data_from_xml(hitlist, 'author') + # put into AstroPy Table + t = Table() + t['title'] = titles + t['bibcode'] = bibcode + t['journal'] = journal + t['volume'] = volume + t['pubdate'] = pubdate + t['page'] = page + t['score'] = score + t['citations'] = citations + t['abstract'] = abstract + t['doi'] = doi + t['eprintid'] = eprintid + t['authors'] = authors + + return t + + def _args_to_payload(self, query_string): + # convert arguments to a valid requests payload + # i.e. a dictionary + return {'qsearch' : query_string, 'data_type' : 'XML'} + + + +ADS = ADSClass() + diff --git a/astroquery/nasa_ads/tests/__init__.py b/astroquery/nasa_ads/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/astroquery/nasa_ads/tests/test_nasaads.py b/astroquery/nasa_ads/tests/test_nasaads.py new file mode 100644 index 0000000000..9258d879e4 --- /dev/null +++ b/astroquery/nasa_ads/tests/test_nasaads.py @@ -0,0 +1,7 @@ +from ... import nasa_ads +from astropy.tests.helper import remote_data + +@remote_data +def test_simple(): + x = nasa_ads.ADS.query_simple('^Persson Origin of water around deeply embedded low-mass protostars') + assert x[-1]['authors'][0] == 'Persson, M. V.' diff --git a/astroquery/nasa_ads/utils.py b/astroquery/nasa_ads/utils.py new file mode 100644 index 0000000000..b8da20a56f --- /dev/null +++ b/astroquery/nasa_ads/utils.py @@ -0,0 +1,18 @@ + + +def _get_data_from_xml(doclist, fieldname, nohitreturn=None): + """Get the fieldname (i.e. author, title etc) + from minidom.parseString().childNodes[0].childNodes list + """ + result = [] + for element in doclist: + fieldlist = element.getElementsByTagName(fieldname) + try: + tmp = fieldlist[0] + except IndexError: + fields = [nohitreturn] + fields = [] + for field in fieldlist: # this is useful for e.g. author field + fields.append(field.childNodes[0].data) + result.append(fields) + return result diff --git a/docs/api.rst b/docs/api.rst index 83adbf4849..e889a82f68 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -171,7 +171,7 @@ Directory Structure:: if get_query_payload: return request_payload - return result + return response @class_or_instance def get_images_async(self, *args): diff --git a/docs/index.rst b/docs/index.rst index ce8bd9f7d4..ab0a50b25a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -132,6 +132,7 @@ The following modules have been completed using a common API: atomic/atomic.rst alma/alma.rst skyview/skyview.rst + nasa_ads/nasa_ads.rst These others are functional, but do not follow a common & consistent API: @@ -225,6 +226,7 @@ above categories. lamda/lamda.rst nist/nist.rst splatalogue/splatalogue.rst + nasa_ads/nasa_ads.rst Developer documentation diff --git a/docs/nasa_ads/nasa_ads.rst b/docs/nasa_ads/nasa_ads.rst new file mode 100644 index 0000000000..033ef9fbb6 --- /dev/null +++ b/docs/nasa_ads/nasa_ads.rst @@ -0,0 +1,65 @@ +.. doctest-skip-all + +.. _astroquery.nasa_ads: + +**************************************** +NASA ADS Queries (`astroquery.nasa_ads`) +**************************************** + +Getting Started +=============== + +This module provides an interface to the online `SAO/NASA Astrophysics Data System`_. +At the moment only the "simple search", i.e. omni-box search is available, and only +a subset of the results are accessible. + +Examples +======== + +Search works by specific identifier +----------------------------------- +.. code-block:: python + + from astroquery import nasa_ads as na + # the "^" makes ADS to return only papers where Persson + # is first author + results = na.ADS.query_simple('^Persson Origin of water\ + around deeply embedded low-mass protostars') results[0].title + + # to sort after publication date + results.sort(['pubdate']) + + # get the title of the last hit + title = results[-1]['title'][0] + + # printout the authors of the last hit + print results[-1]['authors'] + + +Get links +--------- +Not yet implemented. + +Download publisher/ArXiv PDF +---------------------------- +Not yet implemented. + +Get Bibtex +---------- +Not yet implemented. + + + + + + +Reference/API +============= + +#.. automodapi:: astroquery.nasa_ads:no-inheritance-diagram: + +.. _nasa_ads: http://adsabs.harvard.edu/ +.. _SAO/NASA Astrophysics Data System: http://adsabs.harvard.edu/ + + +