/usr/lib/python2.7/dist-packages/pyfits/hdu/nonstandard.py is in python-pyfits 1:3.2-1build2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | import gzip
from pyfits.file import _File
from pyfits.hdu.base import NonstandardExtHDU
from pyfits.hdu.hdulist import HDUList
from pyfits.header import Header
from pyfits.util import lazyproperty, BytesIO, fileobj_name, _pad_length
class FitsHDU(NonstandardExtHDU):
"""
A non-standard extension HDU for encapsulating entire FITS files within a
single HDU of a container FITS file. These HDUs have an extension (that is
an XTENSION keyword) of FITS.
The FITS file contained in the HDU's data can be accessed by the `hdulist`
attribute which returns the contained FITS file as an `HDUList` object.
"""
_extension = 'FITS'
@lazyproperty
def hdulist(self):
self._file.seek(self._data_offset)
fileobj = BytesIO()
# Read the data into a BytesIO--reading directly from the file
# won't work (at least for gzipped files) due to problems deep
# within the gzip module that make it difficult to read gzip files
# embedded in another file
fileobj.write(self._file.read(self.size))
fileobj.seek(0)
if self._header['COMPRESS']:
fileobj = gzip.GzipFile(fileobj=fileobj)
return HDUList.fromfile(fileobj, mode='readonly')
@classmethod
def fromfile(cls, filename, compress=False):
"""
Like `FitsHDU.fromhdulist()`, but creates a FitsHDU from a file on
disk.
Parameters
----------
filename : str
The path to the file to read into a FitsHDU
compress : bool (optional)
Gzip compress the FITS file
"""
return cls.fromhdulist(HDUList.fromfile(filename), compress=compress)
@classmethod
def fromhdulist(cls, hdulist, compress=False):
"""
Creates a new FitsHDU from a given HDUList object.
Parameters
----------
hdulist : HDUList
A valid Headerlet object.
compress : bool (optional)
Gzip compress the FITS file
"""
fileobj = bs = BytesIO()
if compress:
if hasattr(hdulist, '_file'):
name = fileobj_name(hdulist._file)
else:
name = None
fileobj = gzip.GzipFile(name, mode='wb', fileobj=bs)
hdulist.writeto(fileobj)
if compress:
fileobj.close()
# A proper HDUList should still be padded out to a multiple of 2880
# technically speaking
padding = (_pad_length(bs.tell()) * cls._padding_byte).encode('ascii')
bs.write(padding)
bs.seek(0)
cards = [
('XTENSION', cls._extension, 'FITS extension'),
('BITPIX', 8, 'array data type'),
('NAXIS', 1, 'number of array dimensions'),
('NAXIS1', len(bs.getvalue()), 'Axis length'),
('PCOUNT', 0, 'number of parameters'),
('GCOUNT', 1, 'number of groups'),
]
# Add the XINDn keywords proposed by Perry, though nothing is done with
# these at the moment
if len(hdulist) > 1:
for idx, hdu in enumerate(hdulist[1:]):
cards.append(('XIND' + str(idx + 1), hdu._header_offset,
'byte offset of extension %d' % (idx + 1)))
cards.append(('COMPRESS', compress, 'Uses gzip compression'))
header = Header(cards)
# TODO: This wrapping of the fileobj should probably be handled by
# cls.fromstring, though cls.fromstring itself has a strange
# implementation that I probably need to fix. For example, it
# shouldn't care about fileobjs. There should be a _BaseHDU.fromfile
# for that (there is _BaseHDU.readfrom which plays that role, but its
# semantics are also a little unclear...)
return cls.fromstring(header, fileobj=_File(bs))
@classmethod
def match_header(cls, header):
"""
This is a class method used in the pyfits refactoring branch to
recognize whether or not this class should be used for instantiating
an HDU object based on values in the header.
It is included here for forward-compatibility.
"""
card = header.cards[0]
if card.keyword != 'XTENSION':
return False
xtension = card.value
if isinstance(xtension, basestring):
xtension = xtension.rstrip()
return xtension == cls._extension
# TODO: Add header verification
def _summary(self):
# TODO: Perhaps make this more descriptive...
return (self.name, self.__class__.__name__, len(self._header))
|