LSSTApplications  16.0-10-g0ee56ad+5,16.0-11-ga33d1f2+5,16.0-12-g3ef5c14+3,16.0-12-g71e5ef5+18,16.0-12-gbdf3636+3,16.0-13-g118c103+3,16.0-13-g8f68b0a+3,16.0-15-gbf5c1cb+4,16.0-16-gfd17674+3,16.0-17-g7c01f5c+3,16.0-18-g0a50484+1,16.0-20-ga20f992+8,16.0-21-g0e05fd4+6,16.0-21-g15e2d33+4,16.0-22-g62d8060+4,16.0-22-g847a80f+4,16.0-25-gf00d9b8+1,16.0-28-g3990c221+4,16.0-3-gf928089+3,16.0-32-g88a4f23+5,16.0-34-gd7987ad+3,16.0-37-gc7333cb+2,16.0-4-g10fc685+2,16.0-4-g18f3627+26,16.0-4-g5f3a788+26,16.0-5-gaf5c3d7+4,16.0-5-gcc1f4bb+1,16.0-6-g3b92700+4,16.0-6-g4412fcd+3,16.0-6-g7235603+4,16.0-69-g2562ce1b+2,16.0-8-g14ebd58+4,16.0-8-g2df868b+1,16.0-8-g4cec79c+6,16.0-8-gadf6c7a+1,16.0-8-gfc7ad86,16.0-82-g59ec2a54a+1,16.0-9-g5400cdc+2,16.0-9-ge6233d7+5,master-g2880f2d8cf+3,v17.0.rc1
LSSTDataManagementBasePackage
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 
24 import os
25 import lsst.daf.base as dafBase
26 import lsst.geom
27 import lsst.afw.image as afwImage
28 from lsst.afw.fits import FitsError, MemFileManager, reduceToFits, Fits, DEFAULT_HDU
29 from . import mathLib as afwMath
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  In deference to the deprecated-but-not-yet-removed
42  `~lsst.afw.math.Background.getImageF()` API, we also accept a single
43  `lsst.afw.math.Background` and extract the ``interpStyle`` and
44  ``undersampleStyle`` from the as-used values.
45  """
46 
47  def __init__(self, *args):
48  self._backgrounds = []
49  for a in args:
50  self.append(a)
51 
52  def __getitem__(self, *args):
53  """Return an item
54 
55  Parameters
56  ----------
57  *args
58  Any valid list index.
59  """
60  #
61  # Set any previously-unknown Styles (they are set by bkgd.getImage())
62  #
63  for i, val in enumerate(self._backgrounds):
64  bkgd, interpStyle, undersampleStyle, approxStyle, \
65  approxOrderX, approxOrderY, approxWeighting = val
66  if interpStyle is None or undersampleStyle is None:
67  interpStyle = bkgd.getAsUsedInterpStyle()
68  undersampleStyle = bkgd.getAsUsedUndersampleStyle()
69  actrl = bkgd.getBackgroundControl().getApproximateControl()
70  approxStyle = actrl.getStyle()
71  approxOrderX = actrl.getOrderX()
72  approxOrderY = actrl.getOrderY()
73  approxWeighting = actrl.getWeighting()
74  self._backgrounds[i] = (bkgd, interpStyle, undersampleStyle,
75  approxStyle, approxOrderX, approxOrderY, approxWeighting)
76  #
77  # And return what they wanted
78  #
79  return self._backgrounds.__getitem__(*args)
80 
81  def __len__(self, *args):
82  return self._backgrounds.__len__(*args)
83 
84  def append(self, val):
85  try:
86  bkgd, interpStyle, undersampleStyle, approxStyle, \
87  approxOrderX, approxOrderY, approxWeighting = val
88  except TypeError:
89  bkgd = val
90  interpStyle = None
91  undersampleStyle = None
92  approxStyle = None
93  approxOrderX = None
94  approxOrderY = None
95  approxWeighting = None
96 
97  bgInfo = (bkgd, interpStyle, undersampleStyle, approxStyle,
98  approxOrderX, approxOrderY, approxWeighting)
99  self._backgrounds.append(bgInfo)
100 
101  def clone(self):
102  """Return a shallow copy
103 
104  Shallow copies do not share backgrounds that are appended after copying,
105  but do share changes to contained background objects.
106  """
107  return BackgroundList(*self)
108 
109  def writeFits(self, fileName, flags=0):
110  """Save our list of Backgrounds to a file.
111 
112  Parameters
113  -----------
114  fileName : `str`
115  FITS file to write
116  flags : `int`
117  Flags to control details of writing; currently unused, but present
118  for consistency with `lsst.afw.table.BaseCatalog.writeFits`.
119  """
120 
121  for i, bkgd in enumerate(self):
122  (bkgd, interpStyle, undersampleStyle, approxStyle, approxOrderX, approxOrderY,
123  approxWeighting) = bkgd
124 
125  statsImage = bkgd.getStatsImage()
126 
127  md = dafBase.PropertyList()
128  md.set("INTERPSTYLE", int(interpStyle))
129  md.set("UNDERSAMPLESTYLE", int(undersampleStyle))
130  md.set("APPROXSTYLE", int(approxStyle))
131  md.set("APPROXORDERX", approxOrderX)
132  md.set("APPROXORDERY", approxOrderY)
133  md.set("APPROXWEIGHTING", approxWeighting)
134  bbox = bkgd.getImageBBox()
135  md.set("BKGD_X0", bbox.getMinX())
136  md.set("BKGD_Y0", bbox.getMinY())
137  md.set("BKGD_WIDTH", bbox.getWidth())
138  md.set("BKGD_HEIGHT", bbox.getHeight())
139 
140  statsImage.getImage().writeFits(fileName, md, "w" if i == 0 else "a")
141  statsImage.getMask().writeFits(fileName, md, "a")
142  statsImage.getVariance().writeFits(fileName, md, "a")
143 
144  @staticmethod
145  def readFits(fileName, hdu=0, flags=0):
146  """Read our list of Backgrounds from a file.
147 
148  Parameters
149  ----------
150  fileName : `str`
151  FITS file to read
152  hdu : `int`
153  First Header/Data Unit to attempt to read from
154  flags : `int`
155  Flags to control details of reading; currently unused, but present
156  for consistency with `lsst.afw.table.BaseCatalog.readFits`.
157 
158  See Also
159  --------
160  getImage()
161  """
162  if not isinstance(fileName, MemFileManager) and not os.path.exists(fileName):
163  raise RuntimeError("File not found: %s" % fileName)
164 
165  self = BackgroundList()
166 
167  if hdu == DEFAULT_HDU:
168  hdu = -1
169  else:
170  # we want to start at 0 (post RFC-304), but are about to increment
171  hdu -= 1
172 
173  fits = Fits(fileName, "r")
174  fits.setHdu(hdu + 1)
175  if fits.checkCompressedImagePhu():
176  hdu += 1
177 
178  while True:
179  hdu += 1
180 
181  md = dafBase.PropertyList()
182  try:
183  img = afwImage.ImageF(fileName, hdu, md)
184  hdu += 1
185  except FitsError:
186  break
187 
188  msk = afwImage.Mask(fileName, hdu)
189  hdu += 1
190  var = afwImage.ImageF(fileName, hdu)
191 
192  statsImage = afwImage.makeMaskedImage(img, msk, var)
193 
194  x0 = md.getScalar("BKGD_X0")
195  y0 = md.getScalar("BKGD_Y0")
196  width = md.getScalar("BKGD_WIDTH")
197  height = md.getScalar("BKGD_HEIGHT")
198  imageBBox = lsst.geom.BoxI(lsst.geom.PointI(
199  x0, y0), lsst.geom.ExtentI(width, height))
200 
201  interpStyle = afwMath.Interpolate.Style(md.getScalar("INTERPSTYLE"))
202  undersampleStyle = afwMath.UndersampleStyle(
203  md.getScalar("UNDERSAMPLESTYLE"))
204 
205  # Older outputs won't have APPROX* settings. Provide alternative defaults.
206  # Note: Currently X- and Y-orders must be equal due to a limitation in
207  # math::Chebyshev1Function2. Setting approxOrderY = -1 is equivalent
208  # to saying approxOrderY = approxOrderX.
209  approxStyle = md.getScalar("APPROXSTYLE") if "APPROXSTYLE" in md.names() \
210  else afwMath.ApproximateControl.UNKNOWN
211  approxStyle = afwMath.ApproximateControl.Style(approxStyle)
212  approxOrderX = md.getScalar(
213  "APPROXORDERX") if "APPROXORDERX" in md.names() else 1
214  approxOrderY = md.getScalar(
215  "APPROXORDERY") if "APPROXORDERY" in md.names() else -1
216  approxWeighting = md.getScalar(
217  "APPROXWEIGHTING") if "APPROXWEIGHTING" in md.names() else True
218 
219  bkgd = afwMath.BackgroundMI(imageBBox, statsImage)
220  bctrl = bkgd.getBackgroundControl()
221  bctrl.setInterpStyle(interpStyle)
222  bctrl.setUndersampleStyle(undersampleStyle)
224  approxStyle, approxOrderX, approxOrderY, approxWeighting)
225  bctrl.setApproximateControl(actrl)
226  bgInfo = (bkgd, interpStyle, undersampleStyle, approxStyle,
227  approxOrderX, approxOrderY, approxWeighting)
228  self.append(bgInfo)
229 
230  return self
231 
232  def getImage(self):
233  """Compute and return a full-resolution image from our list of
234  (Background, interpStyle, undersampleStyle).
235  """
236 
237  bkgdImage = None
238  for (bkgd, interpStyle, undersampleStyle, approxStyle,
239  approxOrderX, approxOrderY, approxWeighting) in self:
240  if not bkgdImage:
241  if approxStyle != afwMath.ApproximateControl.UNKNOWN:
242  bkgdImage = bkgd.getImageF()
243  else:
244  bkgdImage = bkgd.getImageF(interpStyle, undersampleStyle)
245  else:
246  if approxStyle != afwMath.ApproximateControl.UNKNOWN:
247  bkgdImage += bkgd.getImageF()
248  else:
249  bkgdImage += bkgd.getImageF(interpStyle, undersampleStyle)
250 
251  return bkgdImage
252 
253  def __reduce__(self):
254  return reduceToFits(self)
Class for storing ordered metadata with comments.
Definition: PropertyList.h:68
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition: fits.h:296
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > * makeMaskedImage(typename std::shared_ptr< Image< ImagePixelT >> image, typename std::shared_ptr< Mask< MaskPixelT >> mask=Mask< MaskPixelT >(), typename std::shared_ptr< Image< VariancePixelT >> variance=Image< VariancePixelT >())
A function to return a MaskedImage of the correct type (cf.
Definition: MaskedImage.h:1280
Control how to make an approximation.
Definition: Approximate.h:48
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:78
def readFits(fileName, hdu=0, flags=0)
A class to evaluate image background levels.
Definition: Background.h:444
An integer coordinate rectangle.
Definition: Box.h:54