Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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