Loading [MathJax]/extensions/tex2jax.js
LSST Applications g0fba68d861+849f694866,g1fd858c14a+7a7b9dd5ed,g2c84ff76c0+5cb23283cf,g30358e5240+f0e04ebe90,g35bb328faa+fcb1d3bbc8,g436fd98eb5+bdc6fcdd04,g4af146b050+742274f7cd,g4d2262a081+9d5bd0394b,g4e0f332c67+cb09b8a5b6,g53246c7159+fcb1d3bbc8,g5a012ec0e7+477f9c599b,g60b5630c4e+bdc6fcdd04,g67b6fd64d1+2218407a0c,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g7b71ed6315+fcb1d3bbc8,g87b7deb4dc+777438113c,g8852436030+ebf28f0d95,g89139ef638+2218407a0c,g9125e01d80+fcb1d3bbc8,g989de1cb63+2218407a0c,g9f33ca652e+42fb53f4c8,g9f7030ddb1+11b9b6f027,ga2b97cdc51+bdc6fcdd04,gab72ac2889+bdc6fcdd04,gabe3b4be73+1e0a283bba,gabf8522325+3210f02652,gb1101e3267+9c79701da9,gb58c049af0+f03b321e39,gb89ab40317+2218407a0c,gcf25f946ba+ebf28f0d95,gd6cbbdb0b4+e8f9c9c900,gd9a9a58781+fcb1d3bbc8,gde0f65d7ad+47bbabaf80,gded526ad44+8c3210761e,ge278dab8ac+3ef3db156b,ge410e46f29+2218407a0c,gf67bdafdda+2218407a0c,v29.0.0.rc3
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
_backgroundList.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__ = ["BackgroundList"]
23
24import os
25import lsst.daf.base as dafBase
26import lsst.geom
27import lsst.afw.image as afwImage
28from lsst.afw.fits import MemFileManager, reduceToFits, Fits
29from ._math import Interpolate, ApproximateControl, BackgroundMI, UndersampleStyle
30
31
33 """A list-like class to contain a list of (`lsst.afw.math.Background`,
34 `lsst.afw.math.Interpolate.Style`, `~lsst.afw.math.UndersampleStyle`)
35 tuples.
36
37 Parameters
38 ----------
39 *args : `tuple` or `~lsst.afw.math.Background`
40 A sequence of arguments, each of which becomes an element of the list.
41 We also accept a single `lsst.afw.math.Background` and extract the
42 ``interpStyle`` and ``undersampleStyle`` from the as-used values.
43 """
44
45 def __init__(self, *args):
46 self._backgrounds = []
47 for a in args:
48 self.append(a)
49
50 def __getitem__(self, *args):
51 """Return an item
52
53 Parameters
54 ----------
55 *args
56 Any valid list index.
57 """
58 #
59 # Set any previously-unknown Styles (they are set by bkgd.getImage())
60 #
61 for i, val in enumerate(self._backgrounds):
62 bkgd, interpStyle, undersampleStyle, approxStyle, \
63 approxOrderX, approxOrderY, approxWeighting = val
64 if interpStyle is None or undersampleStyle is None:
65 interpStyle = bkgd.getAsUsedInterpStyle()
66 undersampleStyle = bkgd.getAsUsedUndersampleStyle()
67 actrl = bkgd.getBackgroundControl().getApproximateControl()
68 approxStyle = actrl.getStyle()
69 approxOrderX = actrl.getOrderX()
70 approxOrderY = actrl.getOrderY()
71 approxWeighting = actrl.getWeighting()
72 self._backgrounds[i] = (bkgd, interpStyle, undersampleStyle,
73 approxStyle, approxOrderX, approxOrderY, approxWeighting)
74 #
75 # And return what they wanted
76 #
77 return self._backgrounds.__getitem__(*args)
78
79 def __len__(self, *args):
80 return self._backgrounds.__len__(*args)
81
82 def append(self, val):
83 try:
84 bkgd, interpStyle, undersampleStyle, approxStyle, \
85 approxOrderX, approxOrderY, approxWeighting = val
86 except TypeError:
87 bkgd = val
88 interpStyle = None
89 undersampleStyle = None
90 approxStyle = None
91 approxOrderX = None
92 approxOrderY = None
93 approxWeighting = None
94
95 bgInfo = (bkgd, interpStyle, undersampleStyle, approxStyle,
96 approxOrderX, approxOrderY, approxWeighting)
97 self._backgrounds.append(bgInfo)
98
99 def clone(self):
100 """Return a shallow copy
101
102 Shallow copies do not share backgrounds that are appended after copying,
103 but do share changes to contained background objects.
104 """
105 return BackgroundList(*self)
106
107 def writeFits(self, fileName, flags=0):
108 """Save our list of Backgrounds to a file.
109
110 Parameters
111 -----------
112 fileName : `str`
113 FITS file to write
114 flags : `int`
115 Flags to control details of writing; currently unused, but present
116 for consistency with `lsst.afw.table.BaseCatalog.writeFits`.
117 """
118
119 for i, bkgd in enumerate(self):
120 (bkgd, interpStyle, undersampleStyle, approxStyle, approxOrderX, approxOrderY,
121 approxWeighting) = bkgd
122
123 statsImage = bkgd.getStatsImage()
124
126 md.set("INTERPSTYLE", int(interpStyle))
127 md.set("UNDERSAMPLESTYLE", int(undersampleStyle))
128 md.set("APPROXSTYLE", int(approxStyle))
129 md.set("APPROXORDERX", approxOrderX)
130 md.set("APPROXORDERY", approxOrderY)
131 md.set("APPROXWEIGHTING", approxWeighting)
132 bbox = bkgd.getImageBBox()
133 md.set("BKGD_X0", bbox.getMinX())
134 md.set("BKGD_Y0", bbox.getMinY())
135 md.set("BKGD_WIDTH", bbox.getWidth())
136 md.set("BKGD_HEIGHT", bbox.getHeight())
137
138 statsImage.getImage().writeFits(fileName, md, "w" if i == 0 else "a")
139 statsImage.getMask().writeFits(fileName, md, "a")
140 statsImage.getVariance().writeFits(fileName, md, "a")
141
142 @staticmethod
143 def readFits(fileName, hdu=0, flags=0):
144 """Read our list of Backgrounds from a file.
145
146 Parameters
147 ----------
148 fileName : `str`
149 FITS file to read
150 hdu : `int`
151 First Header/Data Unit to attempt to read from
152 flags : `int`
153 Flags to control details of reading; currently unused, but present
154 for consistency with `lsst.afw.table.BaseCatalog.readFits`.
155
156 See Also
157 --------
158 getImage
159 """
160 if not isinstance(fileName, MemFileManager) and not os.path.exists(fileName):
161 raise RuntimeError(f"File not found: {fileName}")
162
163 self = BackgroundList()
164
165 f = Fits(fileName, 'r')
166 nHdus = f.countHdus()
167 f.closeFile()
168 if nHdus % 3 != 0:
169 raise RuntimeError(f"BackgroundList FITS file {fileName} has {nHdus} HDUs;"
170 f"expected a multiple of 3 (compression is not supported).")
171
172 for hdu in range(0, nHdus, 3):
173 # It seems like we ought to be able to just use
174 # MaskedImageFitsReader here, but it warns about EXTTYPE and still
175 # doesn't work quite naturally when starting from a nonzero HDU.
176 imageReader = afwImage.ImageFitsReader(fileName, hdu=hdu)
177 maskReader = afwImage.MaskFitsReader(fileName, hdu=hdu + 1)
178 varianceReader = afwImage.ImageFitsReader(fileName, hdu=hdu + 2)
179 statsImage = afwImage.MaskedImageF(imageReader.read(), maskReader.read(), varianceReader.read())
180 md = imageReader.readMetadata()
181
182 x0 = md["BKGD_X0"]
183 y0 = md["BKGD_Y0"]
184 width = md["BKGD_WIDTH"]
185 height = md["BKGD_HEIGHT"]
186 imageBBox = lsst.geom.BoxI(lsst.geom.PointI(x0, y0), lsst.geom.ExtentI(width, height))
187
188 interpStyle = Interpolate.Style(md["INTERPSTYLE"])
189 undersampleStyle = UndersampleStyle(md["UNDERSAMPLESTYLE"])
190
191 # Older outputs won't have APPROX* settings. Provide alternative defaults.
192 # Note: Currently X- and Y-orders must be equal due to a limitation in
193 # math::Chebyshev1Function2. Setting approxOrderY = -1 is equivalent
194 # to saying approxOrderY = approxOrderX.
195 approxStyle = md.get("APPROXSTYLE", ApproximateControl.UNKNOWN)
196 approxStyle = ApproximateControl.Style(approxStyle)
197 approxOrderX = md.get("APPROXORDERX", 1)
198 approxOrderY = md.get("APPROXORDERY", -1)
199 approxWeighting = md.get("APPROXWEIGHTING", True)
200
201 bkgd = BackgroundMI(imageBBox, statsImage)
202 bctrl = bkgd.getBackgroundControl()
203 bctrl.setInterpStyle(interpStyle)
204 bctrl.setUndersampleStyle(undersampleStyle)
205 actrl = ApproximateControl(approxStyle, approxOrderX, approxOrderY, approxWeighting)
206 bctrl.setApproximateControl(actrl)
207 bgInfo = (bkgd, interpStyle, undersampleStyle, approxStyle,
208 approxOrderX, approxOrderY, approxWeighting)
209 self.append(bgInfo)
210
211 return self
212
213 def getImage(self):
214 """Compute and return a full-resolution image from our list of
215 (Background, interpStyle, undersampleStyle).
216 """
217
218 bkgdImage = None
219 for (bkgd, interpStyle, undersampleStyle, approxStyle,
220 approxOrderX, approxOrderY, approxWeighting) in self:
221 if not bkgdImage:
222 if approxStyle != ApproximateControl.UNKNOWN:
223 bkgdImage = bkgd.getImageF()
224 else:
225 bkgdImage = bkgd.getImageF(interpStyle, undersampleStyle)
226 else:
227 if approxStyle != ApproximateControl.UNKNOWN:
228 bkgdImage += bkgd.getImageF()
229 else:
230 bkgdImage += bkgd.getImageF(interpStyle, undersampleStyle)
231
232 return bkgdImage
233
234 def __reduce__(self):
235 return reduceToFits(self)
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition fits.h:308
A FITS reader class for regular Images.
A FITS reader class for Masks.
Control how to make an approximation.
Definition Approximate.h:48
A class to evaluate image background levels.
Definition Background.h:434
Class for storing ordered metadata with comments.
An integer coordinate rectangle.
Definition Box.h:55