LSST Applications g00d0e8bbd7+edbf708997,g03191d30f7+9ce8016dbd,g1955dfad08+0bd186d245,g199a45376c+5137f08352,g1fd858c14a+a888a50aa2,g262e1987ae+45f9aba685,g29ae962dfc+1c7d47a24f,g2cef7863aa+73c82f25e4,g35bb328faa+edbf708997,g3fd5ace14f+eed17d2c67,g47891489e3+6dc8069a4c,g53246c7159+edbf708997,g64539dfbff+c4107e45b5,g67b6fd64d1+6dc8069a4c,g74acd417e5+f452e9c21a,g786e29fd12+af89c03590,g7ae74a0b1c+a25e60b391,g7aefaa3e3d+2025e9ce17,g7cc15d900a+2d158402f9,g87389fa792+a4172ec7da,g89139ef638+6dc8069a4c,g8d4809ba88+c4107e45b5,g8d7436a09f+e96c132b44,g8ea07a8fe4+db21c37724,g98df359435+aae6d409c1,ga2180abaac+edbf708997,gac66b60396+966efe6077,gb632fb1845+88945a90f8,gbaa8f7a6c5+38b34f4976,gbf99507273+edbf708997,gca7fc764a6+6dc8069a4c,gd7ef33dd92+6dc8069a4c,gda68eeecaf+7d1e613a8d,gdab6d2f7ff+f452e9c21a,gdbb4c4dda9+c4107e45b5,ge410e46f29+6dc8069a4c,ge41e95a9f2+c4107e45b5,geaed405ab2+e194be0d2b,w.2025.47
LSST Data Management Base Package
Loading...
Searching...
No Matches
_fitsContinued.py
Go to the documentation of this file.
1# This file is part of afw.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22__all__ = ["Fits"]
23
24from collections.abc import Mapping
25
26from lsst.utils import continueClass
27from ._fits import (
28 CompressionAlgorithm,
29 CompressionOptions,
30 DitherAlgorithm,
31 Fits,
32 QuantizationOptions,
33 ScalingAlgorithm,
34)
35
36
37@continueClass
38class Fits: # noqa: F811
39 def __enter__(self):
40 return self
41
42 def __exit__(self, cls, exc, traceback):
43 self.closeFile()
44
45
46@continueClass
47class QuantizationOptions: # noqa: F811
48 @classmethod
49 def from_mapping(cls, mapping: Mapping[str, object]) -> QuantizationOptions:
50 """Construct from a dictionary with keys matching this struct's fields.
51
52 Parameters
53 ----------
54 mapping : `~collections.abc.Mapping`
55 Mapping from string to value. Enumeration values may be passed as
56 string value names.
57
58 Returns
59 -------
60 options : `QuantizationOptions`
61 An instance of this options class.
62
63 Notes
64 -----
65 Allowed keys are:
66
67 - ``dither``: `str`, one of ``NO_DITHER``, ``SUBTRACTIVE_DITHER_1``, or
68 ``SUBTRACTIVE_DITHER_2``. Defaults to ``NO_DITHER``.
69 - ``scaling``: `str`, one of ``STDEV_CFITSIO``, ``STDEV_MASKED``,
70 ``RANGE``, or ``MANUAL`` (see C++ docs for definitions).
71 - ``mask_planes`` : `list` of `str`, names of mask planes to reject in
72 ``STDEV_MASKED`` and ``RANGE`` (but only when writing objects with
73 mask planes)
74 - ``level``: `float`, target compression level (see C++ docs).
75 - ``seed``: random number seed for dithering. Default is zero, which
76 uses a timestamp-based seed when used directly, but a data ID-based
77 seed when used via `lsst.obs.base.FitsExposureFormatter`.
78 """
79 copy = dict(mapping)
80 result = QuantizationOptions()
81 if "dither" in copy:
82 result.dither = DitherAlgorithm[copy.pop("dither")]
83 if "scaling" in copy:
84 result.scaling = ScalingAlgorithm[copy.pop("scaling")]
85 if "mask_planes" in copy:
86 result.mask_planes = copy.pop("mask_planes")
87 if "level" in copy:
88 result.level = copy.pop("level")
89 if "seed" in copy:
90 result.seed = copy.pop("seed")
91 if copy:
92 raise ValueError(f"Unrecognized quantization options: {list(copy.keys())}.")
93 return result
94
95 def to_dict(self) -> dict[str, object]:
96 """"Return the mapping representation of these options.
97
98 Returns
99 -------
100 mapping : `dict`
101 See `from_mapping`.
102 """
103 return {
104 "dither": self.dither.name,
105 "scaling": self.scaling.name,
106 "mask_planes": list(self.mask_planes),
107 "level": self.level,
108 "seed": self.seed,
109 }
110
111 def __repr__(self):
112 return (
113 f"{self.__class__.__name__}(dither={self.dither!r}, scaling={self.scaling!r}, "
114 f"mask_planes={self.mask_planes!r}, level={self.level!r}, seed={self.seed!r})"
115 )
116
117
118@continueClass
119class CompressionOptions: # noqa: F811
120 @classmethod
121 def from_mapping(cls, mapping: Mapping[str, object]) -> CompressionOptions:
122 """Construct from a dictionary with keys matching this struct's fields.
123
124 Parameters
125 ----------
126 mapping : `~collections.abc.Mapping`
127 Mapping from string to value. Enumeration values may be passed as
128 string value names. Missing keys are mapped to default values.
129
130 Returns
131 -------
132 options : `CompressionOptions`
133 An instance of this options class.
134
135 Notes
136 -----
137 Allowed keys are:
138
139 - ``algorithm``: `str`, one of ``GZIP_1``, ``GZIP_2``, or ``RICE_1``.
140 - ``tile_width``: `int`, zero to use entire rows.
141 - ``tile_height``: `int`, zero to use entire columns.
142 - ``quantization``: `dict` or `None` (see
143 `QuantizationOptions.from_mapping`).
144
145 Missing keys are replaced by defaults that reflect lossless compression
146 (``GZIP_2``) with single rows as tiles.
147 """
148 copy = dict(mapping)
149 result = CompressionOptions()
150 if "algorithm" in copy:
151 result.algorithm = CompressionAlgorithm[copy.pop("algorithm")]
152 if "tile_width" in copy:
153 result.tile_width = copy.pop("tile_width")
154 if "tile_height" in copy:
155 result.tile_height = copy.pop("tile_height")
156 if (quantization := copy.pop("quantization", None)) is not None:
157 result.quantization = QuantizationOptions.from_mapping(quantization)
158 if copy:
159 raise ValueError(f"Unrecognized compression options: {list(copy.keys())}.")
160 return result
161
162 def to_dict(self) -> dict[str, object]:
163 """"Return the mapping representation of these options.
164
165 Returns
166 -------
167 mapping : `dict`
168 See `from_mapping`.
169 """
170 return {
171 "algorithm": self.algorithm.name,
172 "tile_width": self.tile_width,
173 "tile_height": self.tile_height,
174 "quantization": self.quantization.to_dict() if self.quantization is not None else None,
175 }
176
177 def __repr__(self):
178 return (
179 f"{self.__class__.__name__}(algorithm={self.algorithm!r}, "
180 f"tile_width={self.tile_width!r}, tile_height={self.tile_height!r}, "
181 f"quantization={self.quantization!r})"
182 )
CompressionOptions from_mapping(cls, Mapping[str, object] mapping)
__exit__(self, cls, exc, traceback)
QuantizationOptions from_mapping(cls, Mapping[str, object] mapping)