Source code for baseband.mark4.file_info

# Licensed under the GPLv3 - see LICENSE
"""The Mark4FileReaderInfo property.

Includes information about what is needed to calcuate times,
number of tracks and offset of first header.
"""

from ..base.file_info import FileReaderInfo, info_item


__all__ = ['Mark4FileReaderInfo']


[docs]class Mark4FileReaderInfo(FileReaderInfo): """Standardized information on Mark 4 file readers. The ``info`` descriptor has a number of standard attributes, which are determined from arguments passed in opening the file, from the first header (``info.header0``) and from possibly scanning the file to determine the duration of frames. This class has two additional attributes specific to Mark 4 files (``ntrack`` and ``offset0``, see below). Examples -------- The most common use is simply to print information:: >>> from baseband.data import SAMPLE_MARK4 >>> from baseband import mark4 >>> fh = mark4.open(SAMPLE_MARK4, 'rb') >>> fh.info Mark4File information: format = mark4 number_of_frames = 2 frame_rate = 400.0 Hz sample_rate = 32.0 MHz samples_per_frame = 80000 sample_shape = (8,) bps = 2 complex_data = False readable = True ntrack = 64 offset0 = 2696 <BLANKLINE> missing: decade, ref_time: needed to infer full times. <BLANKLINE> checks: decodable: True >>> fh.close() >>> fh = mark4.open(SAMPLE_MARK4, 'rb', decade=2010) >>> fh.info Mark4File information: format = mark4 number_of_frames = 2 frame_rate = 400.0 Hz sample_rate = 32.0 MHz samples_per_frame = 80000 sample_shape = (8,) bps = 2 complex_data = False start_time = 2014-06-16T07:38:12.475000000 readable = True ntrack = 64 offset0 = 2696 <BLANKLINE> checks: decodable: True >>> fh.close() """ attr_names = (FileReaderInfo.attr_names[:-4] + ('ntrack', 'offset0') + FileReaderInfo.attr_names[-4:]) """Attributes that the container provides.""" ntrack = info_item(needs='_parent', doc=( 'Number of "tape tracks" simulated in the disk file.')) decade = info_item(needs='_parent', doc=( 'Decade in which the observations were taken')) ref_time = info_item(needs='_parent', doc=( 'Reference time within 4 years of the observation time')) @info_item def time_info(self): """Additional time info needed to get the start time.""" time_info = (self.decade, self.ref_time) if time_info == (None, None): self.missing['decade'] = self.missing['ref_time'] = ( "needed to infer full times.") return None return time_info @info_item def offset0(self): """Offset in bytes to the location of the first header.""" with self._parent.temporary_offset(0) as fh: return fh.locate_frames()[0] @info_item(needs='offset0') def header0(self): with self._parent.temporary_offset(self.offset0) as fh: return fh.read_header() @info_item(needs='header0') def frame0(self): with self._parent.temporary_offset(self.offset0) as fh: return fh.read_frame() @info_item(needs='header0') def number_of_frames(self): """Total number of frames.""" with self._parent.temporary_offset( -self.header0.frame_nbytes, 2) as fh: fh.find_header(self.header0, forward=False) number_of_frames = ((fh.tell() - self.offset0) / self.header0.frame_nbytes) + 1 if number_of_frames % 1 == 0: return int(number_of_frames) else: self.warnings['number_of_frames'] = ( 'file contains non-integer number ({}) of frames' .format(number_of_frames)) return None # Override just to replace what it "needs". @info_item(needs='offset0') def format(self): return 'mark4' @info_item(needs=('header0', 'time_info')) def start_time(self): """Time of the first sample.""" return super().start_time