Skip to content

Commit

Permalink
Merge pull request #453 from mhvk/nuppi-tentative-support
Browse files Browse the repository at this point in the history
Assume channels first rather than erroring on unknown PKTFMT.
  • Loading branch information
mhvk committed Jul 31, 2020
1 parent 6a676b1 commit 586a5c9
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
Bug Fixes
---------

- Allow the GUPPI reader to assume channel-first ordering by default, i.e.,
no longer insist that PKTFMT is one of '1SFA' or 'SIMPLE'. Instead, ``info``
will include a warning for formats not known to work. [#453]

4.0 (2020-07-18)
================
Expand Down
10 changes: 10 additions & 0 deletions baseband/guppi/file_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class GUPPIFileReaderInfo(FileReaderInfo):
# Get sample_rate from header rather than calculate it from frame_rate
# and samples_per_frame, since we need to correct for overlap.
attr_names = list(FileReaderInfo.attr_names)
attr_names.insert(attr_names.index('format')+1, 'pktfmt')
attr_names.insert(attr_names.index('samples_per_frame')+1, 'overlap')
attr_names = tuple(attr_names)
"""Attributes that the container provides."""
Expand All @@ -21,3 +22,12 @@ class GUPPIFileReaderInfo(FileReaderInfo):
'Number of complete samples that overlap between frames.'))
sample_rate = info_item(needs='header0', doc=(
'Number of complete samples per second.'))

@info_item(needs='header0')
def pktfmt(self):
"""Packet format for the data."""
pktfmt = self.header0['PKTFMT']
if pktfmt not in self.header0.supported_formats:
self.warnings['pktfmt'] = (f'Unknown pktfmt {pktfmt!r}. '
f'Assuming channels are stored first.')
return pktfmt
21 changes: 16 additions & 5 deletions baseband/guppi/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ class GUPPIHeader(fits.Header):
('NPOL', 1),
('OBSNCHAN', 1)]

supported_formats = {'1SFA', 'SIMPLE'}
"""GUPPI formats that are known to work.
'1SFA' is used for all modes other than FAST4K (which is only used
for total intensity). 'SIMPLE' is from DSPSR, and used to support
time-first payloads. See
https://safe.nrao.edu/wiki/pub/Main/JoeBrandt/guppi_status_shmem.pdf
If a format is not in this set, yet is known to work, a PR would be
most welcome.
"""

def __init__(self, *args, verify=True, mutable=True, **kwargs):
# Comments handled by fits.Header__init__().
super().__init__(*args, **kwargs)
Expand All @@ -77,13 +89,12 @@ def __init__(self, *args, verify=True, mutable=True, **kwargs):

def verify(self):
"""Basic check of integrity."""
# Same check as dspsr's dsp::GUPPIFile::is_valid
assert all(key in self for key in ('BLOCSIZE',
'PKTIDX'))
# '1SFA' is used for all modes other than FAST4K (which is only used
# for total intensity). 'SIMPLE' is from DSPSR, and used to support
# time-first payloads. See
# https://safe.nrao.edu/wiki/pub/Main/JoeBrandt/guppi_status_shmem.pdf
assert self['PKTFMT'] in ('1SFA', 'SIMPLE')
# We could check here for self['PKTFMT'] in self.supported_formats
# but that would break reading of unsupported but working formats,
# so instead this becomes just a warning in file_info.

def copy(self):
"""Create a mutable and independent copy of the header."""
Expand Down
16 changes: 16 additions & 0 deletions baseband/guppi/tests/test_guppi.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,22 @@ def test_file_info(self):
assert info.frame_rate == header.sample_rate / (
header.samples_per_frame - header.overlap)

def test_file_info_unsupported_format(self, tmpdir):
filename = str(tmpdir.join('file.uppi'))
with guppi.open(SAMPLE_FILE, 'rb') as fh:
f = fh.read_frame()
f.header = f.header.copy()
f['PKTFMT'] = 'unknown'
with guppi.open(filename, 'wb') as fw:
fw.write_frame(f)

with guppi.open(filename, 'rb') as fr:
info = fr.info

assert info.pktfmt == 'unknown'
assert 'pktfmt' in info.warnings
assert 'Unknown pktfmt' in info.warnings['pktfmt']

def test_frame(self, tmpdir):
with guppi.open(SAMPLE_FILE, 'rb') as fh:
frame = fh.read_frame(memmap=False)
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ baseband.io =
all =
baseband-tasks[all]
test =
pytest<6.0
pytest-astropy-header
pytest-doctestplus
pytest-openfiles
Expand Down

0 comments on commit 586a5c9

Please sign in to comment.