Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions astroquery/hitran/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ class Conf(_config.ConfigNamespace):

conf = Conf()

from .core import Hitran, HitranClass
from .core import Hitran, HitranClass, parse_hitran_text

__all__ = ['Hitran', 'HitranClass', 'conf']
__all__ = ['Hitran', 'HitranClass', 'parse_hitran_text', 'conf']
87 changes: 66 additions & 21 deletions astroquery/hitran/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from . import conf
from .utils import parse_readme

__all__ = ['Hitran', 'HitranClass']
__all__ = ['Hitran', 'HitranClass', 'parse_hitran_text']


@async_to_sync
Expand Down Expand Up @@ -227,26 +227,71 @@ def _parse_result(self, response, *, verbose=False):
"""
Parse a response into an `~astropy.table.Table`
"""
formats = parse_readme(self.FORMATFILE)

dtypes = [entry['dtype'] for entry in formats.values()]

rows = []
for line in response.text.split('\n'):
if line.strip():
row = []
start = 0
for key, entry in formats.items():
formatter = entry['formatter']
length = entry['length']
value = formatter(line[start:start+length])
row.append(value)
start = start + length
rows.append(row)

result = Table(rows=rows, names=formats.keys(), dtype=dtypes)

return result
return parse_hitran_text(response.text, formatfile=self.FORMATFILE)

@staticmethod
def read(filename, *, formatfile=None):
"""
Read a HITRAN ``.par`` file from disk into an `~astropy.table.Table`.

Parameters
----------
filename : str
Path to a HITRAN ``.par`` (160-column fixed-width) file.
formatfile : str, optional
Path to a HITRAN format ``readme.txt`` file describing the
column layout. Defaults to the bundled HITRAN 2004 format.

Returns
-------
result : `~astropy.table.Table`
Parsed line list.
"""
if formatfile is None:
formatfile = HitranClass.FORMATFILE
with open(filename, 'r') as fh:
text = fh.read()
return parse_hitran_text(text, formatfile=formatfile)


def parse_hitran_text(text, *, formatfile=HitranClass.FORMATFILE):
"""
Parse the text of a HITRAN ``.par`` line list into an `~astropy.table.Table`.

Parameters
----------
text : str
Contents of a HITRAN ``.par`` file (160-column fixed-width records,
one per line).
formatfile : str, optional
Path to a HITRAN format ``readme.txt`` file describing the column
layout. Defaults to the bundled HITRAN 2004 format.

Returns
-------
result : `~astropy.table.Table`
Parsed line list.
"""
formats = parse_readme(formatfile)

dtypes = [entry['dtype'] for entry in formats.values()]

rows = []
for line in text.split('\n'):
if line.strip():
row = []
start = 0
for key, entry in formats.items():
formatter = entry['formatter']
length = entry['length']
value = formatter(line[start:start+length])
row.append(value)
start = start + length
rows.append(row)

result = Table(rows=rows, names=formats.keys(), dtype=dtypes)

return result


Hitran = HitranClass()
57 changes: 46 additions & 11 deletions astroquery/hitran/tests/test_hitran.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from astropy import units as u
from astropy.table import Table

from ...hitran import Hitran
from ...hitran import Hitran, parse_hitran_text

HITRAN_DATA = 'H2O.data'

Expand All @@ -21,8 +21,8 @@ def __init__(self):

@property
def text(self):
with open(self.filename) as f:
return f.read()
with open(self.filename) as fh:
return fh.read()


def test_query_async():
Expand All @@ -36,19 +36,54 @@ def test_query_async():
np.testing.assert_almost_equal(response['numax'], 10.)


EXPECTED_KEYS = {'molec_id', 'local_iso_id', 'nu', 'sw', 'a',
'gamma_air', 'gamma_self', 'elower',
'n_air', 'delta_air', 'global_upper_quanta',
'global_lower_quanta', 'local_upper_quanta',
'local_lower_quanta', 'ierr1', 'ierr2',
'ierr3', 'ierr4', 'ierr5', 'ierr6', 'iref1',
'iref2', 'iref3', 'iref4', 'iref5', 'iref6',
'line_mixing_flag', 'gp', 'gpp'}


def test_query():
hitran = Hitran()
response = MockResponseHitran()
tbl = hitran._parse_result(response)
assert isinstance(tbl, Table)
assert len(tbl) == 122
assert set(tbl.keys()) == set(['molec_id', 'local_iso_id', 'nu', 'sw', 'a',
'gamma_air', 'gamma_self', 'elower',
'n_air', 'delta_air', 'global_upper_quanta',
'global_lower_quanta', 'local_upper_quanta',
'local_lower_quanta', 'ierr1', 'ierr2',
'ierr3', 'ierr4', 'ierr5', 'ierr6', 'iref1',
'iref2', 'iref3', 'iref4', 'iref5', 'iref6',
'line_mixing_flag', 'gp', 'gpp'])
assert set(tbl.keys()) == EXPECTED_KEYS
assert tbl['molec_id'][0] == 1
np.testing.assert_almost_equal(tbl['nu'][0], 0.072059)


def test_parse_hitran_text():
with open(data_path(HITRAN_DATA)) as fh:
text = fh.read()
tbl = parse_hitran_text(text)
assert isinstance(tbl, Table)
assert len(tbl) == 122
assert set(tbl.keys()) == EXPECTED_KEYS
assert tbl['molec_id'][0] == 1
np.testing.assert_almost_equal(tbl['nu'][0], 0.072059)


def test_parse_hitran_text_matches_parse_result():
"""parse_hitran_text and _parse_result must produce identical tables."""
response = MockResponseHitran()
tbl_from_response = Hitran._parse_result(response)
tbl_from_text = parse_hitran_text(response.text)
assert len(tbl_from_response) == len(tbl_from_text)
assert tbl_from_response.keys() == tbl_from_text.keys()
for key in tbl_from_response.keys():
np.testing.assert_array_equal(tbl_from_response[key],
tbl_from_text[key])


def test_read_par_file():
tbl = Hitran.read(data_path(HITRAN_DATA))
assert isinstance(tbl, Table)
assert len(tbl) == 122
assert set(tbl.keys()) == EXPECTED_KEYS
assert tbl['molec_id'][0] == 1
np.testing.assert_almost_equal(tbl['nu'][0], 0.072059)
Loading