LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
LSST Data Management Base Package
processBrightStars.py
Go to the documentation of this file.
1 # This file is part of pipe_tasks.
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 """Extract small cutouts around bright stars, normalize and warp them to the
23 same arbitrary pixel grid.
24 """
25 
26 __all__ = ["ProcessBrightStarsTask"]
27 
28 import numpy as np
29 import astropy.units as u
30 
31 from lsst import geom
32 from lsst.afw import math as afwMath
33 from lsst.afw import image as afwImage
34 from lsst.afw import detection as afwDetect
35 from lsst.afw import cameraGeom as cg
36 from lsst.afw.geom import transformFactory as tFactory
37 import lsst.pex.config as pexConfig
38 from lsst.pipe import base as pipeBase
39 from lsst.pipe.base import connectionTypes as cT
40 from lsst.pex.exceptions import InvalidParameterError
41 from lsst.meas.algorithms.loadIndexedReferenceObjects import LoadIndexedReferenceObjectsTask
42 from lsst.meas.algorithms import ReferenceObjectLoader
43 from lsst.meas.algorithms import brightStarStamps as bSS
44 
45 
46 class ProcessBrightStarsConnections(pipeBase.PipelineTaskConnections,
47  dimensions=("instrument", "visit", "detector")):
48  inputExposure = cT.Input(
49  doc="Input exposure from which to extract bright star stamps",
50  name="calexp",
51  storageClass="ExposureF",
52  dimensions=("visit", "detector")
53  )
54  skyCorr = cT.Input(
55  doc="Input Sky Correction to be subtracted from the calexp if doApplySkyCorr=True",
56  name="skyCorr",
57  storageClass="Background",
58  dimensions=("instrument", "visit", "detector")
59  )
60  refCat = cT.PrerequisiteInput(
61  doc="Reference catalog that contains bright star positions",
62  name="gaia_dr2_20200414",
63  storageClass="SimpleCatalog",
64  dimensions=("skypix",),
65  multiple=True,
66  deferLoad=True
67  )
68  brightStarStamps = cT.Output(
69  doc="Set of preprocessed postage stamps, each centered on a single bright star.",
70  name="brightStarStamps",
71  storageClass="BrightStarStamps",
72  dimensions=("visit", "detector")
73  )
74 
75  def __init__(self, *, config=None):
76  super().__init__(config=config)
77  if not config.doApplySkyCorr:
78  self.inputs.remove("skyCorr")
79 
80 
81 class ProcessBrightStarsConfig(pipeBase.PipelineTaskConfig,
82  pipelineConnections=ProcessBrightStarsConnections):
83  """Configuration parameters for ProcessBrightStarsTask
84  """
85  magLimit = pexConfig.Field(
86  dtype=float,
87  doc="Magnitude limit, in Gaia G; all stars brighter than this value will be processed",
88  default=18
89  )
90  stampSize = pexConfig.ListField(
91  dtype=int,
92  doc="Size of the stamps to be extracted, in pixels",
93  default=(250, 250)
94  )
95  modelStampBuffer = pexConfig.Field(
96  dtype=float,
97  doc="'Buffer' factor to be applied to determine the size of the stamp the processed stars will "
98  "be saved in. This will also be the size of the extended PSF model.",
99  default=1.1
100  )
101  doRemoveDetected = pexConfig.Field(
102  dtype=bool,
103  doc="Whether DETECTION footprints, other than that for the central object, should be changed to "
104  "BAD",
105  default=True
106  )
107  doApplyTransform = pexConfig.Field(
108  dtype=bool,
109  doc="Apply transform to bright star stamps to correct for optical distortions?",
110  default=True
111  )
112  warpingKernelName = pexConfig.ChoiceField(
113  dtype=str,
114  doc="Warping kernel",
115  default="lanczos5",
116  allowed={
117  "bilinear": "bilinear interpolation",
118  "lanczos3": "Lanczos kernel of order 3",
119  "lanczos4": "Lanczos kernel of order 4",
120  "lanczos5": "Lanczos kernel of order 5",
121  }
122  )
123  annularFluxRadii = pexConfig.ListField(
124  dtype=int,
125  doc="Inner and outer radii of the annulus used to compute the AnnularFlux for normalization, "
126  "in pixels.",
127  default=(40, 50)
128  )
129  annularFluxStatistic = pexConfig.ChoiceField(
130  dtype=str,
131  doc="Type of statistic to use to compute annular flux.",
132  default="MEANCLIP",
133  allowed={
134  "MEAN": "mean",
135  "MEDIAN": "median",
136  "MEANCLIP": "clipped mean",
137  }
138  )
139  numSigmaClip = pexConfig.Field(
140  dtype=float,
141  doc="Sigma for outlier rejection; ignored if annularFluxStatistic != 'MEANCLIP'.",
142  default=4
143  )
144  numIter = pexConfig.Field(
145  dtype=int,
146  doc="Number of iterations of outlier rejection; ignored if annularFluxStatistic != 'MEANCLIP'.",
147  default=3
148  )
149  badMaskPlanes = pexConfig.ListField(
150  dtype=str,
151  doc="Mask planes that, if set, lead to associated pixels not being included in the computation of the"
152  " annular flux.",
153  default=('BAD', 'CR', 'CROSSTALK', 'EDGE', 'NO_DATA', 'SAT', 'SUSPECT', 'UNMASKEDNAN')
154  )
155  minPixelsWithinFrame = pexConfig.Field(
156  dtype=int,
157  doc="Minimum number of pixels that must fall within the stamp boundary for the bright star to be"
158  " saved when its center is beyond the exposure boundary.",
159  default=50
160  )
161  doApplySkyCorr = pexConfig.Field(
162  dtype=bool,
163  doc="Apply full focal plane sky correction before extracting stars?",
164  default=True
165  )
166  refObjLoader = pexConfig.ConfigurableField(
167  target=LoadIndexedReferenceObjectsTask,
168  doc="Reference object loader for astrometric calibration.",
169  )
170 
171  def setDefaults(self):
172  self.refObjLoaderrefObjLoader.ref_dataset_name = "gaia_dr2_20200414"
173 
174 
175 class ProcessBrightStarsTask(pipeBase.PipelineTask, pipeBase.CmdLineTask):
176  """The description of the parameters for this Task are detailed in
177  :lsst-task:`~lsst.pipe.base.PipelineTask`.
178 
179  Notes
180  -----
181  `ProcessBrightStarsTask` is used to extract, process, and store small
182  image cut-outs (or "postage stamps") around bright stars. It relies on
183  three methods, called in succession:
184 
185  `extractStamps`
186  Find bright stars within the exposure using a reference catalog and
187  extract a stamp centered on each.
188  `warpStamps`
189  Shift and warp each stamp to remove optical distortions and sample all
190  stars on the same pixel grid.
191  `measureAndNormalize`
192  Compute the flux of an object in an annulus and normalize it. This is
193  required to normalize each bright star stamp as their central pixels
194  are likely saturated and/or contain ghosts, and cannot be used.
195  """
196  ConfigClass = ProcessBrightStarsConfig
197  _DefaultName = "processBrightStars"
198  RunnerClass = pipeBase.ButlerInitializedTaskRunner
199 
200  def __init__(self, butler=None, initInputs=None, *args, **kwargs):
201  super().__init__(*args, **kwargs)
202  # Compute (model) stamp size depending on provided "buffer" value
203  self.modelStampSizemodelStampSize = [int(self.config.stampSize[0]*self.config.modelStampBuffer),
204  int(self.config.stampSize[1]*self.config.modelStampBuffer)]
205  # force it to be odd-sized so we have a central pixel
206  if not self.modelStampSizemodelStampSize[0] % 2:
207  self.modelStampSizemodelStampSize[0] += 1
208  if not self.modelStampSizemodelStampSize[1] % 2:
209  self.modelStampSizemodelStampSize[1] += 1
210  # central pixel
211  self.modelCentermodelCenter = self.modelStampSizemodelStampSize[0]//2, self.modelStampSizemodelStampSize[1]//2
212  # configure Gaia refcat
213  if butler is not None:
214  self.makeSubtask('refObjLoader', butler=butler)
215 
216  def applySkyCorr(self, calexp, skyCorr):
217  """Apply correction to the sky background level.
218 
219  Sky corrections can be generated with the 'skyCorrection.py'
220  executable in pipe_drivers. Because the sky model used by that
221  code extends over the entire focal plane, this can produce
222  better sky subtraction.
223  The calexp is updated in-place.
224 
225  Parameters
226  ----------
227  calexp : `lsst.afw.image.Exposure` or `lsst.afw.image.MaskedImage`
228  Calibrated exposure.
229  skyCorr : `lsst.afw.math.backgroundList.BackgroundList` or None,
230  optional
231  Full focal plane sky correction, obtained by running
232  `lsst.pipe.drivers.skyCorrection.SkyCorrectionTask`.
233  """
234  if isinstance(calexp, afwImage.Exposure):
235  calexp = calexp.getMaskedImage()
236  calexp -= skyCorr.getImage()
237 
238  def extractStamps(self, inputExposure, refObjLoader=None):
239  """ Read position of bright stars within `inputExposure` from refCat
240  and extract them.
241 
242  Parameters
243  ----------
244  inputExposure : `afwImage.exposure.exposure.ExposureF`
245  The image from which bright star stamps should be extracted.
246  refObjLoader : `LoadIndexedReferenceObjectsTask`, optional
247  Loader to find objects within a reference catalog.
248 
249  Returns
250  -------
251  result : `lsst.pipe.base.Struct`
252  Result struct with components:
253 
254  - ``starIms``: `list` of stamps
255  - ``pixCenters``: `list` of corresponding coordinates to each
256  star's center, in pixels.
257  - ``GMags``: `list` of corresponding (Gaia) G magnitudes.
258  - ``gaiaIds``: `np.ndarray` of corresponding unique Gaia
259  identifiers.
260  """
261  if refObjLoader is None:
262  refObjLoader = self.refObjLoader
263  starIms = []
264  pixCenters = []
265  GMags = []
266  ids = []
267  wcs = inputExposure.getWcs()
268  # select stars within, or close enough to input exposure from refcat
269  inputIm = inputExposure.maskedImage
270  inputExpBBox = inputExposure.getBBox()
271  dilatationExtent = geom.Extent2I(np.array(self.config.stampSize) - self.config.minPixelsWithinFrame)
272  # TODO (DM-25894): handle catalog with stars missing from Gaia
273  withinCalexp = refObjLoader.loadPixelBox(inputExpBBox.dilatedBy(dilatationExtent), wcs,
274  filterName="phot_g_mean")
275  refCat = withinCalexp.refCat
276  # keep bright objects
277  fluxLimit = ((self.config.magLimit*u.ABmag).to(u.nJy)).to_value()
278  GFluxes = np.array(refCat['phot_g_mean_flux'])
279  bright = GFluxes > fluxLimit
280  # convert to AB magnitudes
281  allGMags = [((gFlux*u.nJy).to(u.ABmag)).to_value() for gFlux in GFluxes[bright]]
282  allIds = refCat.columns.extract("id", where=bright)["id"]
283  selectedColumns = refCat.columns.extract('coord_ra', 'coord_dec', where=bright)
284  for j, (ra, dec) in enumerate(zip(selectedColumns["coord_ra"], selectedColumns["coord_dec"])):
285  sp = geom.SpherePoint(ra, dec, geom.radians)
286  cpix = wcs.skyToPixel(sp)
287  try:
288  starIm = inputExposure.getCutout(sp, geom.Extent2I(self.config.stampSize))
289  except InvalidParameterError:
290  # star is beyond boundary
291  bboxCorner = np.array(cpix) - np.array(self.config.stampSize)/2
292  # compute bbox as it would be otherwise
293  idealBBox = geom.Box2I(geom.Point2I(bboxCorner), geom.Extent2I(self.config.stampSize))
294  clippedStarBBox = geom.Box2I(idealBBox)
295  clippedStarBBox.clip(inputExpBBox)
296  if clippedStarBBox.getArea() > 0:
297  # create full-sized stamp with all pixels
298  # flagged as NO_DATA
299  starIm = afwImage.ExposureF(bbox=idealBBox)
300  starIm.image[:] = np.nan
301  starIm.mask.set(inputExposure.mask.getPlaneBitMask("NO_DATA"))
302  # recover pixels from intersection with the exposure
303  clippedIm = inputIm.Factory(inputIm, clippedStarBBox)
304  starIm.maskedImage[clippedStarBBox] = clippedIm
305  # set detector and wcs, used in warpStars
306  starIm.setDetector(inputExposure.getDetector())
307  starIm.setWcs(inputExposure.getWcs())
308  else:
309  continue
310  if self.config.doRemoveDetected:
311  # give detection footprint of other objects the BAD flag
312  detThreshold = afwDetect.Threshold(starIm.mask.getPlaneBitMask("DETECTED"),
313  afwDetect.Threshold.BITMASK)
314  omask = afwDetect.FootprintSet(starIm.mask, detThreshold)
315  allFootprints = omask.getFootprints()
316  otherFootprints = []
317  for fs in allFootprints:
318  if not fs.contains(geom.Point2I(cpix)):
319  otherFootprints.append(fs)
320  nbMatchingFootprints = len(allFootprints) - len(otherFootprints)
321  if not nbMatchingFootprints == 1:
322  self.log.warn("Failed to uniquely identify central DETECTION footprint for star "
323  f"{allIds[j]}; found {nbMatchingFootprints} footprints instead.")
324  omask.setFootprints(otherFootprints)
325  omask.setMask(starIm.mask, "BAD")
326  starIms.append(starIm)
327  pixCenters.append(cpix)
328  GMags.append(allGMags[j])
329  ids.append(allIds[j])
330  return pipeBase.Struct(starIms=starIms,
331  pixCenters=pixCenters,
332  GMags=GMags,
333  gaiaIds=ids)
334 
335  def warpStamps(self, stamps, pixCenters):
336  """Warps and shifts all given stamps so they are sampled on the same
337  pixel grid and centered on the central pixel. This includes rotating
338  the stamp depending on detector orientation.
339 
340  Parameters
341  ----------
342  stamps : `collections.abc.Sequence`
343  [`afwImage.exposure.exposure.ExposureF`]
344  Image cutouts centered on a single object.
345  pixCenters : `collections.abc.Sequence` [`geom.Point2D`]
346  Positions of each object's center (as obtained from the refCat),
347  in pixels.
348 
349  Returns
350  -------
351  warpedStars : `list` [`afwImage.maskedImage.maskedImage.MaskedImage`]
352  """
353  # warping control; only contains shiftingALg provided in config
354  warpCont = afwMath.WarpingControl(self.config.warpingKernelName)
355  # Compare model to star stamp sizes
356  bufferPix = (self.modelStampSizemodelStampSize[0] - self.config.stampSize[0],
357  self.modelStampSizemodelStampSize[1] - self.config.stampSize[1])
358  # Initialize detector instance (note all stars were extracted from an
359  # exposure from the same detector)
360  det = stamps[0].getDetector()
361  # Define correction for optical distortions
362  if self.config.doApplyTransform:
363  pixToTan = det.getTransform(cg.PIXELS, cg.TAN_PIXELS)
364  else:
365  pixToTan = tFactory.makeIdentityTransform()
366  # Array of all possible rotations for detector orientation:
367  possibleRots = np.array([k*np.pi/2 for k in range(4)])
368  # determine how many, if any, rotations are required
369  yaw = det.getOrientation().getYaw()
370  nb90Rots = np.argmin(np.abs(possibleRots - float(yaw)))
371 
372  # apply transformation to each star
373  warpedStars = []
374  for star, cent in zip(stamps, pixCenters):
375  # (re)create empty destination image
376  destImage = afwImage.MaskedImageF(*self.modelStampSizemodelStampSize)
377  bottomLeft = geom.Point2D(star.image.getXY0())
378  newBottomLeft = pixToTan.applyForward(bottomLeft)
379  newBottomLeft.setX(newBottomLeft.getX() - bufferPix[0]/2)
380  newBottomLeft.setY(newBottomLeft.getY() - bufferPix[1]/2)
381  # Convert to int
382  newBottomLeft = geom.Point2I(newBottomLeft)
383  # Set origin
384  destImage.setXY0(newBottomLeft)
385 
386  # Define linear shifting to recenter stamps
387  newCenter = pixToTan.applyForward(cent) # center of warped star
388  shift = self.modelCentermodelCenter[0] + newBottomLeft[0] - newCenter[0],\
389  self.modelCentermodelCenter[1] + newBottomLeft[1] - newCenter[1]
390  affineShift = geom.AffineTransform(shift)
391  shiftTransform = tFactory.makeTransform(affineShift)
392 
393  # Define full transform (warp and shift)
394  starWarper = pixToTan.then(shiftTransform)
395 
396  # Apply it
397  goodPix = afwMath.warpImage(destImage, star.getMaskedImage(),
398  starWarper, warpCont)
399  if not goodPix:
400  self.log.debug("Warping of a star failed: no good pixel in output")
401 
402  # Arbitrarily set origin of shifted star to 0
403  destImage.setXY0(0, 0)
404 
405  # Apply rotation if apropriate
406  if nb90Rots:
407  destImage = afwMath.rotateImageBy90(destImage, nb90Rots)
408  warpedStars.append(destImage.clone())
409  return warpedStars
410 
411  @pipeBase.timeMethod
412  def run(self, inputExposure, refObjLoader=None, dataId=None, skyCorr=None):
413  """Identify bright stars within an exposure using a reference catalog,
414  extract stamps around each, then preprocess them. The preprocessing
415  steps are: shifting, warping and potentially rotating them to the same
416  pixel grid; computing their annular flux and normalizing them.
417 
418  Parameters
419  ----------
420  inputExposure : `afwImage.exposure.exposure.ExposureF`
421  The image from which bright star stamps should be extracted.
422  refObjLoader : `LoadIndexedReferenceObjectsTask`, optional
423  Loader to find objects within a reference catalog.
424  dataId : `dict` or `lsst.daf.butler.DataCoordinate`
425  The dataId of the exposure (and detector) bright stars should be
426  extracted from.
427  skyCorr : `lsst.afw.math.backgroundList.BackgroundList` or ``None``,
428  optional
429  Full focal plane sky correction, obtained by running
430  `lsst.pipe.drivers.skyCorrection.SkyCorrectionTask`.
431 
432  Returns
433  -------
434  result : `lsst.pipe.base.Struct`
435  Result struct with component:
436 
437  - ``brightStarStamps``: ``bSS.BrightStarStamps``
438  """
439  if self.config.doApplySkyCorr:
440  self.log.info("Applying sky correction to exposure %s (exposure will be modified in-place).",
441  dataId)
442  self.applySkyCorrapplySkyCorr(inputExposure, skyCorr)
443  self.log.info("Extracting bright stars from exposure %s", dataId)
444  # Extract stamps around bright stars
445  extractedStamps = self.extractStampsextractStamps(inputExposure, refObjLoader=refObjLoader)
446  # Warp (and shift, and potentially rotate) them
447  self.log.info("Applying warp and/or shift to %i star stamps from exposure %s",
448  len(extractedStamps.starIms), dataId)
449  warpedStars = self.warpStampswarpStamps(extractedStamps.starIms, extractedStamps.pixCenters)
450  brightStarList = [bSS.BrightStarStamp(stamp_im=warp,
451  gaiaGMag=extractedStamps.GMags[j],
452  gaiaId=extractedStamps.gaiaIds[j])
453  for j, warp in enumerate(warpedStars)]
454  # Compute annularFlux and normalize
455  self.log.info("Computing annular flux and normalizing %i bright stars from exposure %s",
456  len(warpedStars), dataId)
457  # annularFlux statistic set-up, excluding mask planes
458  statsControl = afwMath.StatisticsControl()
459  statsControl.setNumSigmaClip(self.config.numSigmaClip)
460  statsControl.setNumIter(self.config.numIter)
461  innerRadius, outerRadius = self.config.annularFluxRadii
462  statsFlag = afwMath.stringToStatisticsProperty(self.config.annularFluxStatistic)
463  brightStarStamps = bSS.BrightStarStamps.initAndNormalize(brightStarList,
464  innerRadius=innerRadius,
465  outerRadius=outerRadius,
466  imCenter=self.modelCentermodelCenter,
467  statsControl=statsControl,
468  statsFlag=statsFlag,
469  badMaskPlanes=self.config.badMaskPlanes)
470  return pipeBase.Struct(brightStarStamps=brightStarStamps)
471 
472  def runDataRef(self, dataRef):
473  """Read in required calexp, extract and process stamps around bright
474  stars and write them to disk.
475 
476  Parameters
477  ----------
478  dataRef : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
479  Data reference to the calexp to extract bright stars from.
480  """
481  calexp = dataRef.get("calexp")
482  skyCorr = dataRef.get("skyCorr") if self.config.doApplySkyCorr else None
483  output = self.runrun(calexp, dataId=dataRef.dataId, skyCorr=skyCorr)
484  # Save processed bright star stamps
485  dataRef.put(output.brightStarStamps, "brightStarStamps")
486  return pipeBase.Struct(brightStarStamps=output.brightStarStamps)
487 
488  def runQuantum(self, butlerQC, inputRefs, outputRefs):
489  inputs = butlerQC.get(inputRefs)
490  inputs['dataId'] = str(butlerQC.quantum.dataId)
491  refObjLoader = ReferenceObjectLoader(dataIds=[ref.datasetRef.dataId
492  for ref in inputRefs.refCat],
493  refCats=inputs.pop("refCat"),
494  config=self.config.refObjLoader)
495  output = self.runrun(**inputs, refObjLoader=refObjLoader)
496  butlerQC.put(output, outputRefs)
table::Key< int > to
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition: Exposure.h:72
Pass parameters to a Statistics object.
Definition: Statistics.h:93
Parameters to control convolution.
Definition: warpExposure.h:250
An affine coordinate transformation consisting of a linear transformation and an offset.
An integer coordinate rectangle.
Definition: Box.h:55
Point in an unspecified spherical coordinate system.
Definition: SpherePoint.h:57
def runQuantum(self, butlerQC, inputRefs, outputRefs)
def run(self, inputExposure, refObjLoader=None, dataId=None, skyCorr=None)
def extractStamps(self, inputExposure, refObjLoader=None)
def __init__(self, butler=None, initInputs=None, *args, **kwargs)
Property stringToStatisticsProperty(std::string const property)
Conversion function to switch a string to a Property (see Statistics.h)
Definition: Statistics.cc:747
std::shared_ptr< ImageT > rotateImageBy90(ImageT const &image, int nQuarter)
Rotate an image by an integral number of quarter turns.
Definition: rotateImage.cc:39
int warpImage(DestImageT &destImage, geom::SkyWcs const &destWcs, SrcImageT const &srcImage, geom::SkyWcs const &srcWcs, WarpingControl const &control, typename DestImageT::SinglePixel padValue=lsst::afw::math::edgePixel< DestImageT >(typename lsst::afw::image::detail::image_traits< DestImageT >::image_category()))
Warp an Image or MaskedImage to a new Wcs.
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations.