File: fits.py

package info (click to toggle)
python-imageio 2.4.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,824 kB
  • sloc: python: 18,306; makefile: 145
file content (128 lines) | stat: -rw-r--r-- 4,789 bytes parent folder | download | duplicates (3)
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
# -*- coding: utf-8 -*-
# imageio is distributed under the terms of the (new) BSD License.

""" Plugin for reading FITS files.
"""

from __future__ import absolute_import, print_function, division

from .. import formats
from ..core import Format

_fits = None  # lazily loaded


def load_lib():
    global _fits
    try:
        from astropy.io import fits as _fits
    except ImportError:
        raise ImportError(
            "The FITS format relies on the astropy package."
            "Please refer to http://www.astropy.org/ "
            "for further instructions."
        )
    return _fits


class FitsFormat(Format):

    """ Flexible Image Transport System (FITS) is an open standard defining a
    digital file format useful for storage, transmission and processing of
    scientific and other images. FITS is the most commonly used digital
    file format in astronomy.
    
    This format requires the ``astropy`` package.

    Parameters for reading
    ----------------------
    cache : bool
        If the file name is a URL, `~astropy.utils.data.download_file` is used
        to open the file.  This specifies whether or not to save the file
        locally in Astropy's download cache (default: `True`).
    uint : bool
        Interpret signed integer data where ``BZERO`` is the
        central value and ``BSCALE == 1`` as unsigned integer
        data.  For example, ``int16`` data with ``BZERO = 32768``
        and ``BSCALE = 1`` would be treated as ``uint16`` data.

        Note, for backward compatibility, the kwarg **uint16** may
        be used instead.  The kwarg was renamed when support was
        added for integers of any size.
    ignore_missing_end : bool
        Do not issue an exception when opening a file that is
        missing an ``END`` card in the last header.
    checksum : bool or str
        If `True`, verifies that both ``DATASUM`` and
        ``CHECKSUM`` card values (when present in the HDU header)
        match the header and data of all HDU's in the file.  Updates to a
        file that already has a checksum will preserve and update the
        existing checksums unless this argument is given a value of
        'remove', in which case the CHECKSUM and DATASUM values are not
        checked, and are removed when saving changes to the file.
    disable_image_compression : bool, optional
        If `True`, treats compressed image HDU's like normal
        binary table HDU's.
    do_not_scale_image_data : bool
        If `True`, image data is not scaled using BSCALE/BZERO values
        when read.
    ignore_blank : bool
        If `True`, the BLANK keyword is ignored if present.
    scale_back : bool
        If `True`, when saving changes to a file that contained scaled
        image data, restore the data to the original type and reapply the
        original BSCALE/BZERO values.  This could lead to loss of accuracy
        if scaling back to integer values after performing floating point
        operations on the data.
    """

    def _can_read(self, request):
        # We return True if ext matches, because this is the only plugin
        # that can. If astropy is not installed, a useful error follows.
        return request.extension in self.extensions

    def _can_write(self, request):
        # No write support
        return False

    # -- reader

    class Reader(Format.Reader):
        def _open(self, cache=False, **kwargs):
            if not _fits:
                load_lib()
            hdulist = _fits.open(self.request.get_file(), cache=cache, **kwargs)

            self._index = []
            for n, hdu in zip(range(len(hdulist)), hdulist):
                if isinstance(hdu, _fits.ImageHDU) or isinstance(hdu, _fits.PrimaryHDU):
                    # Ignore (primary) header units with no data (use '.size'
                    # rather than '.data' to avoid actually loading the image):
                    if hdu.size > 0:
                        self._index.append(n)
            self._hdulist = hdulist

        def _close(self):
            self._hdulist.close()

        def _get_length(self):
            return len(self._index)

        def _get_data(self, index):
            # Get data
            if index < 0 or index >= len(self._index):
                raise IndexError("Index out of range while reading from fits")
            im = self._hdulist[self._index[index]].data
            # Return array and empty meta data
            return im, {}

        def _get_meta_data(self, index):
            # Get the meta data for the given index
            raise RuntimeError("The fits format does not support meta data.")


# Register
format = FitsFormat(
    "fits", "Flexible Image Transport System (FITS) format", "fits fit fts", "iIvV"
)
formats.add_format(format)