LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
lsst.pipe.drivers.background.SkyMeasurementTask Class Reference
Inheritance diagram for lsst.pipe.drivers.background.SkyMeasurementTask:

Public Member Functions

def getSkyData (self, butler, calibId)
 
def backgroundToExposure (self, statsImage, bbox)
 
def measureBackground (self, image)
 
def averageBackgrounds (self, bgList)
 
def measureScale (self, image, skyBackground)
 
def solveScales (self, scales)
 
def subtractSkyFrame (self, image, skyBackground, scale, bgList=None)
 

Static Public Member Functions

def exposureToBackground (bgExp)
 

Static Public Attributes

 ConfigClass = SkyMeasurementConfig
 

Detailed Description

Task for creating, persisting and using sky frames

A sky frame is like a fringe frame (the sum of many exposures of the night sky,
combined with rejection to remove astrophysical objects) except the structure
is on larger scales, and hence we bin the images and represent them as a
background model (a `lsst.afw.math.BackgroundMI`).  The sky frame represents
the dominant response of the camera to the sky background.

Definition at line 82 of file background.py.

Member Function Documentation

◆ averageBackgrounds()

def lsst.pipe.drivers.background.SkyMeasurementTask.averageBackgrounds (   self,
  bgList 
)
Average multiple background models

The input background models should be a `BackgroundList` consisting
of a single `BackgroundMI`.

Parameters
----------
bgList : `list` of `lsst.afw.math.BackgroundList`
    Background models to average.

Returns
-------
bgExp : `lsst.afw.image.Exposure`
    Background model in Exposure format.

Definition at line 211 of file background.py.

211  def averageBackgrounds(self, bgList):
212  """Average multiple background models
213 
214  The input background models should be a `BackgroundList` consisting
215  of a single `BackgroundMI`.
216 
217  Parameters
218  ----------
219  bgList : `list` of `lsst.afw.math.BackgroundList`
220  Background models to average.
221 
222  Returns
223  -------
224  bgExp : `lsst.afw.image.Exposure`
225  Background model in Exposure format.
226  """
227  assert all(len(bg) == 1 for bg in bgList), "Mixed bgList: %s" % ([len(bg) for bg in bgList],)
228  images = [bg[0][0].getStatsImage() for bg in bgList]
229  boxes = [bg[0][0].getImageBBox() for bg in bgList]
230  assert len(set((box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY()) for box in boxes)) == 1, \
231  "Bounding boxes not all equal"
232  bbox = boxes.pop(0)
233 
234  # Ensure bad pixels are masked
235  maskVal = afwImage.Mask.getPlaneBitMask("BAD")
236  for img in images:
237  bad = numpy.isnan(img.getImage().getArray())
238  img.getMask().getArray()[bad] = maskVal
239 
240  stats = afwMath.StatisticsControl()
241  stats.setAndMask(maskVal)
242  stats.setNanSafe(True)
243  combined = afwMath.statisticsStack(images, afwMath.MEANCLIP, stats)
244 
245  # Set bad pixels to the median
246  # Specifically NOT going to attempt to interpolate the bad values because we're only working on a
247  # single CCD here and can't use the entire field-of-view to do the interpolation (which is what we
248  # would need to avoid introducing problems at the edge of CCDs).
249  array = combined.getImage().getArray()
250  bad = numpy.isnan(array)
251  median = numpy.median(array[~bad])
252  array[bad] = median
253 
254  # Put it into an exposure, which is required for calibs
255  return self.backgroundToExposure(combined, bbox)
256 
Pass parameters to a Statistics object.
Definition: Statistics.h:92
daf::base::PropertySet * set
Definition: fits.cc:912
std::shared_ptr< lsst::afw::image::Image< PixelT > > statisticsStack(std::vector< std::shared_ptr< lsst::afw::image::Image< PixelT >>> &images, Property flags, StatisticsControl const &sctrl=StatisticsControl(), std::vector< lsst::afw::image::VariancePixel > const &wvector=std::vector< lsst::afw::image::VariancePixel >(0))
A function to compute some statistics of a stack of Images.
bool all(CoordinateExpr< N > const &expr) noexcept
Return true if all elements are true.

◆ backgroundToExposure()

def lsst.pipe.drivers.background.SkyMeasurementTask.backgroundToExposure (   self,
  statsImage,
  bbox 
)
Convert a background model to an exposure

Calibs need to be persisted as an Exposure, so we need to convert
the background model to an Exposure.

Parameters
----------
statsImage : `lsst.afw.image.MaskedImageF`
    Background model's statistics image.
bbox : `lsst.geom.Box2I`
    Bounding box for image.

Returns
-------
exp : `lsst.afw.image.Exposure`
    Background model in Exposure format.

Definition at line 142 of file background.py.

142  def backgroundToExposure(self, statsImage, bbox):
143  """Convert a background model to an exposure
144 
145  Calibs need to be persisted as an Exposure, so we need to convert
146  the background model to an Exposure.
147 
148  Parameters
149  ----------
150  statsImage : `lsst.afw.image.MaskedImageF`
151  Background model's statistics image.
152  bbox : `lsst.geom.Box2I`
153  Bounding box for image.
154 
155  Returns
156  -------
157  exp : `lsst.afw.image.Exposure`
158  Background model in Exposure format.
159  """
160  exp = afwImage.makeExposure(statsImage)
161  header = exp.getMetadata()
162  header.set("BOX.MINX", bbox.getMinX())
163  header.set("BOX.MINY", bbox.getMinY())
164  header.set("BOX.MAXX", bbox.getMaxX())
165  header.set("BOX.MAXY", bbox.getMaxY())
166  header.set("ALGORITHM", self.config.background.algorithm)
167  return exp
168 
std::shared_ptr< Exposure< ImagePixelT, MaskPixelT, VariancePixelT > > makeExposure(MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > &mimage, std::shared_ptr< geom::SkyWcs const > wcs=std::shared_ptr< geom::SkyWcs const >())
A function to return an Exposure of the correct type (cf.
Definition: Exposure.h:462

◆ exposureToBackground()

def lsst.pipe.drivers.background.SkyMeasurementTask.exposureToBackground (   bgExp)
static
Convert an exposure to background model

Calibs need to be persisted as an Exposure, so we need to convert
the persisted Exposure to a background model.

Parameters
----------
bgExp : `lsst.afw.image.Exposure`
    Background model in Exposure format.

Returns
-------
bg : `lsst.afw.math.BackgroundList`
    Background model

Definition at line 112 of file background.py.

112  def exposureToBackground(bgExp):
113  """Convert an exposure to background model
114 
115  Calibs need to be persisted as an Exposure, so we need to convert
116  the persisted Exposure to a background model.
117 
118  Parameters
119  ----------
120  bgExp : `lsst.afw.image.Exposure`
121  Background model in Exposure format.
122 
123  Returns
124  -------
125  bg : `lsst.afw.math.BackgroundList`
126  Background model
127  """
128  header = bgExp.getMetadata()
129  xMin = header.getScalar("BOX.MINX")
130  yMin = header.getScalar("BOX.MINY")
131  xMax = header.getScalar("BOX.MAXX")
132  yMax = header.getScalar("BOX.MAXY")
133  algorithm = header.getScalar("ALGORITHM")
134  bbox = geom.Box2I(geom.Point2I(xMin, yMin), geom.Point2I(xMax, yMax))
135  return afwMath.BackgroundList(
136  (afwMath.BackgroundMI(bbox, bgExp.getMaskedImage()),
137  afwMath.stringToInterpStyle(algorithm),
138  afwMath.stringToUndersampleStyle("REDUCE_INTERP_ORDER"),
139  afwMath.ApproximateControl.UNKNOWN,
140  0, 0, False))
141 
A class to evaluate image background levels.
Definition: Background.h:434
An integer coordinate rectangle.
Definition: Box.h:55
Interpolate::Style stringToInterpStyle(std::string const &style)
Conversion function to switch a string to an Interpolate::Style.
Definition: Interpolate.cc:256
UndersampleStyle stringToUndersampleStyle(std::string const &style)
Conversion function to switch a string to an UndersampleStyle.
Definition: Background.cc:117

◆ getSkyData()

def lsst.pipe.drivers.background.SkyMeasurementTask.getSkyData (   self,
  butler,
  calibId 
)
Retrieve sky frame from the butler

Parameters
----------
butler : `lsst.daf.persistence.Butler`
    Data butler
calibId : `dict`
    Data identifier for calib

Returns
-------
sky : `lsst.afw.math.BackgroundList`
    Sky frame

Definition at line 93 of file background.py.

93  def getSkyData(self, butler, calibId):
94  """Retrieve sky frame from the butler
95 
96  Parameters
97  ----------
98  butler : `lsst.daf.persistence.Butler`
99  Data butler
100  calibId : `dict`
101  Data identifier for calib
102 
103  Returns
104  -------
105  sky : `lsst.afw.math.BackgroundList`
106  Sky frame
107  """
108  exp = butler.get("sky", calibId)
109  return self.exposureToBackground(exp)
110 

◆ measureBackground()

def lsst.pipe.drivers.background.SkyMeasurementTask.measureBackground (   self,
  image 
)
Measure a background model for image

This doesn't use a full-featured background model (e.g., no Chebyshev
approximation) because we just want the binning behaviour.  This will
allow us to average the bins later (`averageBackgrounds`).

The `BackgroundMI` is wrapped in a `BackgroundList` so it can be
pickled and persisted.

Parameters
----------
image : `lsst.afw.image.MaskedImage`
    Image for which to measure background.

Returns
-------
bgModel : `lsst.afw.math.BackgroundList`
    Background model.

Definition at line 169 of file background.py.

169  def measureBackground(self, image):
170  """Measure a background model for image
171 
172  This doesn't use a full-featured background model (e.g., no Chebyshev
173  approximation) because we just want the binning behaviour. This will
174  allow us to average the bins later (`averageBackgrounds`).
175 
176  The `BackgroundMI` is wrapped in a `BackgroundList` so it can be
177  pickled and persisted.
178 
179  Parameters
180  ----------
181  image : `lsst.afw.image.MaskedImage`
182  Image for which to measure background.
183 
184  Returns
185  -------
186  bgModel : `lsst.afw.math.BackgroundList`
187  Background model.
188  """
189  stats = afwMath.StatisticsControl()
190  stats.setAndMask(image.getMask().getPlaneBitMask(self.config.background.mask))
191  stats.setNanSafe(True)
193  self.config.background.algorithm,
194  max(int(image.getWidth()/self.config.background.xBinSize + 0.5), 1),
195  max(int(image.getHeight()/self.config.background.yBinSize + 0.5), 1),
196  "REDUCE_INTERP_ORDER",
197  stats,
198  self.config.background.statistic
199  )
200 
201  bg = afwMath.makeBackground(image, ctrl)
202 
203  return afwMath.BackgroundList((
204  bg,
205  afwMath.stringToInterpStyle(self.config.background.algorithm),
206  afwMath.stringToUndersampleStyle("REDUCE_INTERP_ORDER"),
207  afwMath.ApproximateControl.UNKNOWN,
208  0, 0, False
209  ))
210 
int max
Pass parameters to a Background object.
Definition: Background.h:56
std::shared_ptr< Background > makeBackground(ImageT const &img, BackgroundControl const &bgCtrl)
A convenience function that uses function overloading to make the correct type of Background.
Definition: Background.h:526

◆ measureScale()

def lsst.pipe.drivers.background.SkyMeasurementTask.measureScale (   self,
  image,
  skyBackground 
)
Measure scale of background model in image

We treat the sky frame much as we would a fringe frame
(except the length scale of the variations is different):
we measure samples on the input image and the sky frame,
which we will use to determine the scaling factor in the
'solveScales` method.

Parameters
----------
image : `lsst.afw.image.Exposure` or `lsst.afw.image.MaskedImage`
    Science image for which to measure scale.
skyBackground : `lsst.afw.math.BackgroundList`
    Sky background model.

Returns
-------
imageSamples : `numpy.ndarray`
    Sample measurements on image.
skySamples : `numpy.ndarray`
    Sample measurements on sky frame.

Definition at line 257 of file background.py.

257  def measureScale(self, image, skyBackground):
258  """Measure scale of background model in image
259 
260  We treat the sky frame much as we would a fringe frame
261  (except the length scale of the variations is different):
262  we measure samples on the input image and the sky frame,
263  which we will use to determine the scaling factor in the
264  'solveScales` method.
265 
266  Parameters
267  ----------
268  image : `lsst.afw.image.Exposure` or `lsst.afw.image.MaskedImage`
269  Science image for which to measure scale.
270  skyBackground : `lsst.afw.math.BackgroundList`
271  Sky background model.
272 
273  Returns
274  -------
275  imageSamples : `numpy.ndarray`
276  Sample measurements on image.
277  skySamples : `numpy.ndarray`
278  Sample measurements on sky frame.
279  """
280  if isinstance(image, afwImage.Exposure):
281  image = image.getMaskedImage()
282  # Ensure more samples than pixels
283  xNumSamples = min(self.config.xNumSamples, image.getWidth())
284  yNumSamples = min(self.config.yNumSamples, image.getHeight())
285  xLimits = numpy.linspace(0, image.getWidth(), xNumSamples + 1, dtype=int)
286  yLimits = numpy.linspace(0, image.getHeight(), yNumSamples + 1, dtype=int)
287  sky = skyBackground.getImage()
288  maskVal = image.getMask().getPlaneBitMask(self.config.stats.mask)
289  ctrl = afwMath.StatisticsControl(self.config.stats.clip, self.config.stats.nIter, maskVal)
290  statistic = afwMath.stringToStatisticsProperty(self.config.stats.statistic)
291  imageSamples = []
292  skySamples = []
293  for xIndex, yIndex in itertools.product(range(xNumSamples), range(yNumSamples)):
294  # -1 on the stop because Box2I is inclusive of the end point and we don't want to overlap boxes
295  xStart, xStop = xLimits[xIndex], xLimits[xIndex + 1] - 1
296  yStart, yStop = yLimits[yIndex], yLimits[yIndex + 1] - 1
297  box = geom.Box2I(geom.Point2I(xStart, yStart), geom.Point2I(xStop, yStop))
298  subImage = image.Factory(image, box)
299  subSky = sky.Factory(sky, box)
300  imageSamples.append(afwMath.makeStatistics(subImage, statistic, ctrl).getValue())
301  skySamples.append(afwMath.makeStatistics(subSky, statistic, ctrl).getValue())
302  return imageSamples, skySamples
303 
int min
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition: Exposure.h:72
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
Definition: Statistics.h:359
Property stringToStatisticsProperty(std::string const property)
Conversion function to switch a string to a Property (see Statistics.h)
Definition: Statistics.cc:738

◆ solveScales()

def lsst.pipe.drivers.background.SkyMeasurementTask.solveScales (   self,
  scales 
)
Solve multiple scales for a single scale factor

Having measured samples from the image and sky frame, we
fit for the scaling factor.

Parameters
----------
scales : `list` of a `tuple` of two `numpy.ndarray` arrays
    A `list` of the results from `measureScale` method.

Returns
-------
scale : `float`
    Scale factor.

Definition at line 304 of file background.py.

304  def solveScales(self, scales):
305  """Solve multiple scales for a single scale factor
306 
307  Having measured samples from the image and sky frame, we
308  fit for the scaling factor.
309 
310  Parameters
311  ----------
312  scales : `list` of a `tuple` of two `numpy.ndarray` arrays
313  A `list` of the results from `measureScale` method.
314 
315  Returns
316  -------
317  scale : `float`
318  Scale factor.
319  """
320  imageSamples = []
321  skySamples = []
322  for ii, ss in scales:
323  imageSamples.extend(ii)
324  skySamples.extend(ss)
325  assert len(imageSamples) == len(skySamples)
326  imageSamples = numpy.array(imageSamples)
327  skySamples = numpy.array(skySamples)
328 
329  def solve(mask):
330  return afwMath.LeastSquares.fromDesignMatrix(skySamples[mask].reshape(mask.sum(), 1),
331  imageSamples[mask],
332  afwMath.LeastSquares.DIRECT_SVD).getSolution()
333 
334  mask = numpy.isfinite(imageSamples) & numpy.isfinite(skySamples)
335  for ii in range(self.config.skyIter):
336  solution = solve(mask)
337  residuals = imageSamples - solution*skySamples
338  lq, uq = numpy.percentile(residuals[mask], [25, 75])
339  stdev = 0.741*(uq - lq) # Robust stdev from IQR
340  with numpy.errstate(invalid="ignore"): # suppress NAN warnings
341  bad = numpy.abs(residuals) > self.config.skyRej*stdev
342  mask[bad] = False
343 
344  return solve(mask)
345 

◆ subtractSkyFrame()

def lsst.pipe.drivers.background.SkyMeasurementTask.subtractSkyFrame (   self,
  image,
  skyBackground,
  scale,
  bgList = None 
)
Subtract sky frame from science image

Parameters
----------
image : `lsst.afw.image.Exposure` or `lsst.afw.image.MaskedImage`
    Science image.
skyBackground : `lsst.afw.math.BackgroundList`
    Sky background model.
scale : `float`
    Scale to apply to background model.
bgList : `lsst.afw.math.BackgroundList`
    List of backgrounds applied to image

Definition at line 346 of file background.py.

346  def subtractSkyFrame(self, image, skyBackground, scale, bgList=None):
347  """Subtract sky frame from science image
348 
349  Parameters
350  ----------
351  image : `lsst.afw.image.Exposure` or `lsst.afw.image.MaskedImage`
352  Science image.
353  skyBackground : `lsst.afw.math.BackgroundList`
354  Sky background model.
355  scale : `float`
356  Scale to apply to background model.
357  bgList : `lsst.afw.math.BackgroundList`
358  List of backgrounds applied to image
359  """
360  if isinstance(image, afwImage.Exposure):
361  image = image.getMaskedImage()
362  if isinstance(image, afwImage.MaskedImage):
363  image = image.getImage()
364  image.scaledMinus(scale, skyBackground.getImage())
365  if bgList is not None:
366  # Append the sky frame to the list of applied background models
367  bgData = list(skyBackground[0])
368  bg = bgData[0]
369  statsImage = bg.getStatsImage().clone()
370  statsImage *= scale
371  newBg = afwMath.BackgroundMI(bg.getImageBBox(), statsImage)
372  newBgData = [newBg] + bgData[1:]
373  bgList.append(newBgData)
374 
375 
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:73
daf::base::PropertyList * list
Definition: fits.cc:913

Member Data Documentation

◆ ConfigClass

lsst.pipe.drivers.background.SkyMeasurementTask.ConfigClass = SkyMeasurementConfig
static

Definition at line 91 of file background.py.


The documentation for this class was generated from the following file: