LSSTApplications  11.0-24-g0a022a1,12.1-4-g110c6f4+31,15.0+14,15.0+9,15.0-1-g19261fa+6,15.0-1-g60afb23+14,15.0-1-g615e0bb+6,15.0-1-g6668b0b+5,15.0-1-g788a293+14,15.0-1-ga91101e+14,15.0-1-gae1598d+8,15.0-1-gd076f1f+13,15.0-1-gdf18595+2,15.0-1-gf4f1c34+8,15.0-2-g100d730+7,15.0-2-g18f3f21+7,15.0-2-g20c4630+1,15.0-2-g35685a8+8,15.0-2-g5dfaa72+1,15.0-2-gf38729e+7,15.0-23-g309a1dfe0,15.0-3-g150fc43+16,15.0-3-g6f085af+7,15.0-3-g707930d,15.0-3-g9103c06+8,15.0-3-ga03b4ca+19,15.0-3-gaec6799+5,15.0-4-g45f767a+8,15.0-4-g5589a47,15.0-4-g654b129+12,15.0-4-gff20472+17,15.0-5-g0db841d,15.0-5-g23e394c,15.0-6-g86eaddf,15.0-6-g9a9df217+8,15.0-7-gab4c137+9,15.0-7-gab79a70c+6
LSSTDataManagementBasePackage
secondMomentStarSelector.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 #
4 # Copyright 2008-2017 AURA/LSST.
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
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 LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <https://www.lsstcorp.org/LegalNotices/>.
22 #
23 from builtins import range
24 from builtins import object
25 import collections
26 import math
27 
28 import numpy
29 
30 from lsst.afw.cameraGeom import PIXELS, TAN_PIXELS
31 from lsst.afw.table import SourceCatalog, SourceTable
32 from lsst.pipe.base import Struct
33 import lsst.pex.config as pexConfig
34 import lsst.afw.detection as afwDetection
35 import lsst.afw.display.ds9 as ds9
36 import lsst.afw.image as afwImage
37 import lsst.afw.math as afwMath
38 import lsst.afw.geom as afwGeom
39 from .psfCandidate import makePsfCandidate
40 from .doubleGaussianPsf import DoubleGaussianPsf
41 from lsst.meas.base import SingleFrameMeasurementTask, SingleFrameMeasurementConfig
42 from .starSelector import BaseStarSelectorTask, starSelectorRegistry
43 
44 
45 class SecondMomentStarSelectorConfig(BaseStarSelectorTask.ConfigClass):
46  fluxLim = pexConfig.Field(
47  doc="specify the minimum psfFlux for good Psf Candidates",
48  dtype=float,
49  default=12500.0,
50  check=lambda x: x >= 0.0,
51  )
52  fluxMax = pexConfig.Field(
53  doc="specify the maximum psfFlux for good Psf Candidates (ignored if == 0)",
54  dtype=float,
55  default=0.0,
56  check=lambda x: x >= 0.0,
57  )
58  clumpNSigma = pexConfig.Field(
59  doc="candidate PSF's shapes must lie within this many sigma of the average shape",
60  dtype=float,
61  default=2.0,
62  check=lambda x: x >= 0.0,
63  )
64  histSize = pexConfig.Field(
65  doc="Number of bins in moment histogram",
66  dtype=int,
67  default=64,
68  check=lambda x: x > 0,
69  )
70  histMomentMax = pexConfig.Field(
71  doc="Maximum moment to consider",
72  dtype=float,
73  default=100.0,
74  check=lambda x: x > 0,
75  )
76  histMomentMaxMultiplier = pexConfig.Field(
77  doc="Multiplier of mean for maximum moments histogram range",
78  dtype=float,
79  default=5.0,
80  check=lambda x: x > 0,
81  )
82  histMomentClip = pexConfig.Field(
83  doc="Clipping threshold for moments histogram range",
84  dtype=float,
85  default=5.0,
86  check=lambda x: x > 0,
87  )
88  histMomentMinMultiplier = pexConfig.Field(
89  doc="Multiplier of mean for minimum moments histogram range",
90  dtype=float,
91  default=2.0,
92  check=lambda x: x > 0,
93  )
94 
95  def setDefaults(self):
96  BaseStarSelectorTask.ConfigClass.setDefaults(self)
97  self.badFlags = [
98  "base_PixelFlags_flag_edge",
99  "base_PixelFlags_flag_interpolatedCenter",
100  "base_PixelFlags_flag_saturatedCenter",
101  "base_PixelFlags_flag_crCenter",
102  ]
103 
104 
105 Clump = collections.namedtuple('Clump', ['peak', 'x', 'y', 'ixx', 'ixy', 'iyy', 'a', 'b', 'c'])
106 
107 
109 
110  """A functor to check whether a source has any flags set that should cause it to be labeled bad."""
111 
112  def __init__(self, table, badFlags, fluxLim, fluxMax):
113  self.keys = [table.getSchema().find(name).key for name in badFlags]
114  self.keys.append(table.getCentroidFlagKey())
115  self.fluxLim = fluxLim
116  self.fluxMax = fluxMax
117 
118  def __call__(self, source):
119  for k in self.keys:
120  if source.get(k):
121  return False
122  if self.fluxLim is not None and source.getPsfFlux() < self.fluxLim: # ignore faint objects
123  return False
124  if self.fluxMax != 0.0 and source.getPsfFlux() > self.fluxMax: # ignore bright objects
125  return False
126  return True
127 
128 
134 
135 
137  """!A star selector based on second moments
138 
139  @anchor SecondMomentStarSelectorTask_
140 
141  @section meas_algorithms_secondMomentStarSelector_Contents Contents
142 
143  - @ref meas_algorithms_secondMomentStarSelector_Purpose
144  - @ref meas_algorithms_secondMomentStarSelector_Initialize
145  - @ref meas_algorithms_secondMomentStarSelector_IO
146  - @ref meas_algorithms_secondMomentStarSelector_Config
147  - @ref meas_algorithms_secondMomentStarSelector_Debug
148 
149  @section meas_algorithms_secondMomentStarSelector_Purpose Description
150 
151  A star selector based on second moments.
152 
153  @warning This is a naive algorithm; use with caution.
154 
155  @section meas_algorithms_secondMomentStarSelector_Initialize Task initialisation
156 
157  @copydoc \_\_init\_\_
158 
159  @section meas_algorithms_secondMomentStarSelector_IO Invoking the Task
160 
161  Like all star selectors, the main method is `run`.
162 
163  @section meas_algorithms_secondMomentStarSelector_Config Configuration parameters
164 
165  See @ref SecondMomentStarSelectorConfig
166 
167  @section meas_algorithms_secondMomentStarSelector_Debug Debug variables
168 
169  SecondMomentStarSelectorTask has a debug dictionary with the following keys:
170  <dl>
171  <dt>display
172  <dd>bool; if True display debug information
173  </dl>
174  display = lsstDebug.Info(__name__).display
175  displayExposure = lsstDebug.Info(__name__).displayExposure
176  pauseAtEnd = lsstDebug.Info(__name__).pauseAtEnd
177 
178  For example, put something like:
179  @code{.py}
180  import lsstDebug
181  def DebugInfo(name):
182  di = lsstDebug.getInfo(name) # N.b. lsstDebug.Info(name) would call us recursively
183  if name.endswith("catalogStarSelector"):
184  di.display = True
185 
186  return di
187 
188  lsstDebug.Info = DebugInfo
189  @endcode
190  into your `debug.py` file and run your task with the `--debug` flag.
191  """
192  ConfigClass = SecondMomentStarSelectorConfig
193  usesMatches = False # selectStars does not use its matches argument
194 
195  def selectStars(self, exposure, sourceCat, matches=None):
196  """!Return a list of PSF candidates that represent likely stars
197 
198  A list of PSF candidates may be used by a PSF fitter to construct a PSF.
199 
200  @param[in] exposure the exposure containing the sources
201  @param[in] sourceCat catalog of sources that may be stars (an lsst.afw.table.SourceCatalog)
202  @param[in] matches astrometric matches; ignored by this star selector
203 
204  @return an lsst.pipe.base.Struct containing:
205  - starCat catalog of selected stars (a subset of sourceCat)
206  """
207  import lsstDebug
208  display = lsstDebug.Info(__name__).display
209 
210  isGoodSource = CheckSource(sourceCat.getTable(), self.config.badFlags, self.config.fluxLim,
211  self.config.fluxMax)
212 
213  detector = exposure.getDetector()
214 
215  mi = exposure.getMaskedImage()
216  #
217  # Create an Image of Ixx v. Iyy, i.e. a 2-D histogram
218  #
219 
220  # Use stats on our Ixx/yy values to determine the xMax/yMax range for clump image
221  iqqList = []
222  for s in sourceCat:
223  ixx, iyy = s.getIxx(), s.getIyy()
224  # ignore NaN and unrealistically large values
225  if (ixx == ixx and ixx < self.config.histMomentMax and
226  iyy == iyy and iyy < self.config.histMomentMax and
227  isGoodSource(s)):
228  iqqList.append(s.getIxx())
229  iqqList.append(s.getIyy())
230  stat = afwMath.makeStatistics(iqqList, afwMath.MEANCLIP | afwMath.STDEVCLIP | afwMath.MAX)
231  iqqMean = stat.getValue(afwMath.MEANCLIP)
232  iqqStd = stat.getValue(afwMath.STDEVCLIP)
233  iqqMax = stat.getValue(afwMath.MAX)
234 
235  iqqLimit = max(iqqMean + self.config.histMomentClip*iqqStd,
236  self.config.histMomentMaxMultiplier*iqqMean)
237  # if the max value is smaller than our range, use max as the limit, but don't go below N*mean
238  if iqqLimit > iqqMax:
239  iqqLimit = max(self.config.histMomentMinMultiplier*iqqMean, iqqMax)
240 
241  psfHist = _PsfShapeHistogram(detector=detector,
242  xSize=self.config.histSize, ySize=self.config.histSize,
243  ixxMax=iqqLimit, iyyMax=iqqLimit)
244 
245  if display:
246  frame = 0
247  ds9.mtv(mi, frame=frame, title="PSF candidates")
248  ctypes = []
249 
250  for source in sourceCat:
251  good = isGoodSource(source)
252  if good:
253  notRejected = psfHist.insert(source)
254  if display:
255  if good:
256  if notRejected:
257  ctypes.append(ds9.GREEN) # good
258  else:
259  ctypes.append(ds9.MAGENTA) # rejected
260  else:
261  ctypes.append(ds9.RED) # bad
262 
263  if display:
264  with ds9.Buffering():
265  for source, ctype in zip(sourceCat, ctypes):
266  ds9.dot("o", source.getX() - mi.getX0(), source.getY() - mi.getY0(),
267  frame=frame, ctype=ctype)
268 
269  clumps = psfHist.getClumps(display=display)
270 
271  #
272  # Go through and find all the PSF-like objects
273  #
274  # We'll split the image into a number of cells, each of which contributes only
275  # one PSF candidate star
276  #
277  starCat = SourceCatalog(sourceCat.table)
278 
279  pixToTanPix = None
280  if detector is not None:
281  pixToTanPix = detector.getTransform(PIXELS, TAN_PIXELS)
282 
283  # psf candidate shapes must lie within this many RMS of the average shape
284  # N.b. if Ixx == Iyy, Ixy = 0 the criterion is
285  # dx^2 + dy^2 < self.config.clumpNSigma*(Ixx + Iyy) == 2*self.config.clumpNSigma*Ixx
286  for source in sourceCat:
287  if not isGoodSource(source):
288  continue
289  Ixx, Ixy, Iyy = source.getIxx(), source.getIxy(), source.getIyy()
290  if pixToTanPix:
291  p = afwGeom.Point2D(source.getX(), source.getY())
292  linTransform = afwGeom.linearizeTransform(pixToTanPix, p).getLinear()
293  m = afwGeom.Quadrupole(Ixx, Iyy, Ixy)
294  m.transform(linTransform)
295  Ixx, Iyy, Ixy = m.getIxx(), m.getIyy(), m.getIxy()
296 
297  x, y = psfHist.momentsToPixel(Ixx, Iyy)
298  for clump in clumps:
299  dx, dy = (x - clump.x), (y - clump.y)
300 
301  if math.sqrt(clump.a*dx*dx + 2*clump.b*dx*dy + clump.c*dy*dy) < 2*self.config.clumpNSigma:
302  # A test for > would be confused by NaN
303  if not isGoodSource(source):
304  continue
305  try:
306  psfCandidate = makePsfCandidate(source, exposure)
307 
308  # The setXXX methods are class static, but it's convenient to call them on
309  # an instance as we don't know Exposure's pixel type
310  # (and hence psfCandidate's exact type)
311  if psfCandidate.getWidth() == 0:
312  psfCandidate.setBorderWidth(self.config.borderWidth)
313  psfCandidate.setWidth(self.config.kernelSize + 2*self.config.borderWidth)
314  psfCandidate.setHeight(self.config.kernelSize + 2*self.config.borderWidth)
315 
316  im = psfCandidate.getMaskedImage().getImage()
317  if not numpy.isfinite(afwMath.makeStatistics(im, afwMath.MAX).getValue()):
318  continue
319  starCat.append(source)
320 
321  if display:
322  ds9.dot("o", source.getX() - mi.getX0(), source.getY() - mi.getY0(),
323  size=4, frame=frame, ctype=ds9.CYAN)
324  except Exception as err:
325  self.log.error("Failed on source %s: %s" % (source.getId(), err))
326  break
327 
328  return Struct(
329  starCat=starCat,
330  )
331 
332 
334 
335  """A class to represent a histogram of (Ixx, Iyy)
336  """
337 
338  def __init__(self, xSize=32, ySize=32, ixxMax=30, iyyMax=30, detector=None, xy0=afwGeom.Point2D(0, 0)):
339  """Construct a _PsfShapeHistogram
340 
341  The maximum seeing FWHM that can be tolerated is [xy]Max/2.35 pixels.
342  The 'resolution' of stars vs galaxies/CRs is provided by [xy]Size/[xy]Max.
343  A larger (better) resolution may thresh the peaks, but a smaller (worse)
344  resolution will allow stars and galaxies/CRs to mix. The disadvantages of
345  a larger (better) resolution can be compensated (some) by using multiple
346  histogram peaks.
347 
348  @input[in] [xy]Size: the size of the psfImage (in pixels)
349  @input[in] ixxMax, iyyMax: the maximum values for I[xy][xy]
350  """
351  self._xSize, self._ySize = xSize, ySize
352  self._xMax, self._yMax = ixxMax, iyyMax
353  self._psfImage = afwImage.ImageF(afwGeom.ExtentI(xSize, ySize), 0)
354  self._num = 0
355  self.detector = detector
356  self.xy0 = xy0
357 
358  def getImage(self):
359  return self._psfImage
360 
361  def insert(self, source):
362  """Insert source into the histogram."""
363 
364  ixx, iyy, ixy = source.getIxx(), source.getIyy(), source.getIxy()
365  if self.detector:
366  tanSys = self.detector.makeCameraSys(TAN_PIXELS)
367  if tanSys in self.detector.getTransformMap():
368  pixToTanPix = self.detector.getTransform(PIXELS, TAN_PIXELS)
369  p = afwGeom.Point2D(source.getX(), source.getY())
370  linTransform = afwGeom.linearizeTransform(pixToTanPix, p).getLinear()
371  m = afwGeom.Quadrupole(ixx, iyy, ixy)
372  m.transform(linTransform)
373  ixx, iyy, ixy = m.getIxx(), m.getIyy(), m.getIxy()
374 
375  try:
376  pixel = self.momentsToPixel(ixx, iyy)
377  i = int(pixel[0])
378  j = int(pixel[1])
379  except:
380  return 0
381 
382  if i in range(0, self._xSize) and j in range(0, self._ySize):
383  if i != 0 or j != 0:
384  self._psfImage.set(i, j, self._psfImage.get(i, j) + 1)
385  self._num += 1
386  return 1 # success
387 
388  return 0 # failure
389 
390  def momentsToPixel(self, ixx, iyy):
391  # x = math.sqrt(ixx) * self._xSize / self._xMax
392  # y = math.sqrt(iyy) * self._ySize / self._yMax
393  x = ixx * self._xSize / self._xMax
394  y = iyy * self._ySize / self._yMax
395  return x, y
396 
397  def pixelToMoments(self, x, y):
398  """Given a peak position in self._psfImage, return the corresponding (Ixx, Iyy)"""
399 
400  # ixx = (x*self._xMax/self._xSize)**2
401  # iyy = (y*self._yMax/self._ySize)**2
402  ixx = x*self._xMax/self._xSize
403  iyy = y*self._yMax/self._ySize
404  return ixx, iyy
405 
406  def getClumps(self, sigma=1.0, display=False):
407  if self._num <= 0:
408  raise RuntimeError("No candidate PSF sources")
409 
410  psfImage = self.getImage()
411  #
412  # Embed psfImage into a larger image so we can smooth when measuring it
413  #
414  width, height = psfImage.getWidth(), psfImage.getHeight()
415  largeImg = psfImage.Factory(afwGeom.ExtentI(2*width, 2*height))
416  largeImg.set(0)
417 
418  bbox = afwGeom.BoxI(afwGeom.PointI(width, height), afwGeom.ExtentI(width, height))
419  largeImg.assign(psfImage, bbox, afwImage.LOCAL)
420  #
421  # Now measure that image, looking for the highest peak. Start by building an Exposure
422  #
423  msk = afwImage.Mask(largeImg.getDimensions())
424  msk.set(0)
425  var = afwImage.ImageF(largeImg.getDimensions())
426  var.set(1)
427  mpsfImage = afwImage.MaskedImageF(largeImg, msk, var)
428  mpsfImage.setXY0(afwGeom.PointI(-width, -height))
429  del msk
430  del var
431  exposure = afwImage.makeExposure(mpsfImage)
432 
433  #
434  # Next run an object detector
435  #
436  maxVal = afwMath.makeStatistics(psfImage, afwMath.MAX).getValue()
437  threshold = maxVal - sigma*math.sqrt(maxVal)
438  if threshold <= 0.0:
439  threshold = maxVal
440 
441  threshold = afwDetection.Threshold(threshold)
442 
443  ds = afwDetection.FootprintSet(mpsfImage, threshold, "DETECTED")
444  #
445  # And measure it. This policy isn't the one we use to measure
446  # Sources, it's only used to characterize this PSF histogram
447  #
448  schema = SourceTable.makeMinimalSchema()
449  psfImageConfig = SingleFrameMeasurementConfig()
450  psfImageConfig.slots.centroid = "base_SdssCentroid"
451  psfImageConfig.plugins["base_SdssCentroid"].doFootprintCheck = False
452  psfImageConfig.slots.psfFlux = None # "base_PsfFlux"
453  psfImageConfig.slots.apFlux = "base_CircularApertureFlux_3_0"
454  psfImageConfig.slots.modelFlux = None
455  psfImageConfig.slots.instFlux = None
456  psfImageConfig.slots.calibFlux = None
457  psfImageConfig.slots.shape = "base_SdssShape"
458  # Formerly, this code had centroid.sdss, flux.psf, flux.naive,
459  # flags.pixel, and shape.sdss
460  psfImageConfig.algorithms.names = ["base_SdssCentroid", "base_CircularApertureFlux", "base_SdssShape"]
461  psfImageConfig.algorithms["base_CircularApertureFlux"].radii = [3.0]
462  psfImageConfig.validate()
463  task = SingleFrameMeasurementTask(schema, config=psfImageConfig)
464 
465  sourceCat = SourceCatalog(schema)
466 
467  gaussianWidth = 1.5 # Gaussian sigma for detection convolution
468  exposure.setPsf(DoubleGaussianPsf(11, 11, gaussianWidth))
469 
470  ds.makeSources(sourceCat)
471  #
472  # Show us the Histogram
473  #
474  if display:
475  frame = 1
476  dispImage = mpsfImage.Factory(mpsfImage, afwGeom.BoxI(afwGeom.PointI(width, height),
477  afwGeom.ExtentI(width, height)),
478  afwImage.LOCAL)
479  ds9.mtv(dispImage, title="PSF Selection Image", frame=frame)
480 
481  clumps = list() # List of clumps, to return
482  e = None # thrown exception
483  IzzMin = 1.0 # Minimum value for second moments
484  IzzMax = (self._xSize/8.0)**2 # Max value ... clump radius should be < clumpImgSize/8
485  apFluxes = []
486  task.run(sourceCat, exposure) # notes that this is backwards for the new framework
487  for i, source in enumerate(sourceCat):
488  if source.getCentroidFlag():
489  continue
490  x, y = source.getX(), source.getY()
491 
492  apFluxes.append(source.getApFlux())
493 
494  val = mpsfImage.getImage().get(int(x) + width, int(y) + height)
495 
496  psfClumpIxx = source.getIxx()
497  psfClumpIxy = source.getIxy()
498  psfClumpIyy = source.getIyy()
499 
500  if display:
501  if i == 0:
502  ds9.pan(x, y, frame=frame)
503 
504  ds9.dot("+", x, y, ctype=ds9.YELLOW, frame=frame)
505  ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y,
506  ctype=ds9.YELLOW, frame=frame)
507 
508  if psfClumpIxx < IzzMin or psfClumpIyy < IzzMin:
509  psfClumpIxx = max(psfClumpIxx, IzzMin)
510  psfClumpIyy = max(psfClumpIyy, IzzMin)
511  if display:
512  ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y,
513  ctype=ds9.RED, frame=frame)
514 
515  det = psfClumpIxx*psfClumpIyy - psfClumpIxy*psfClumpIxy
516  try:
517  a, b, c = psfClumpIyy/det, -psfClumpIxy/det, psfClumpIxx/det
518  except ZeroDivisionError:
519  a, b, c = 1e4, 0, 1e4
520 
521  clumps.append(Clump(peak=val, x=x, y=y, a=a, b=b, c=c,
522  ixx=psfClumpIxx, ixy=psfClumpIxy, iyy=psfClumpIyy))
523 
524  if len(clumps) == 0:
525  msg = "Failed to determine center of PSF clump"
526  if e:
527  msg += ": %s" % e
528  raise RuntimeError(msg)
529 
530  # if it's all we got return it
531  if len(clumps) == 1:
532  return clumps
533 
534  # which clump is the best?
535  # if we've undistorted the moments, stars should only have 1 clump
536  # use the apFlux from the clump measurement, and take the highest
537  # ... this clump has more psf star candidate neighbours than the others.
538 
539  # get rid of any that are huge, and thus poorly defined
540  goodClumps = []
541  for clump in clumps:
542  if clump.ixx < IzzMax and clump.iyy < IzzMax:
543  goodClumps.append(clump)
544 
545  # if culling > IzzMax cost us all clumps, we'll have to take what we have
546  if len(goodClumps) == 0:
547  goodClumps = clumps
548 
549  # use the 'brightest' clump
550  iBestClump = numpy.argsort(apFluxes)[0]
551  clumps = [clumps[iBestClump]]
552  return clumps
553 
554 
555 starSelectorRegistry.register("secondMoment", SecondMomentStarSelectorTask)
An ellipse core with quadrupole moments as parameters.
Definition: Quadrupole.h:47
def __init__(self, xSize=32, ySize=32, ixxMax=30, iyyMax=30, detector=None, xy0=afwGeom.Point2D(0, 0))
A subtask for measuring the properties of sources on a single exposure.
Definition: sfm.py:152
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33
daf::base::PropertySet * set
Definition: fits.cc:818
An integer coordinate rectangle.
Definition: Box.h:55
AffineTransform linearizeTransform(TransformPoint2ToPoint2 const &original, Point2D const &inPoint)
Approximate a Transform by its local linearization.
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
The makeStatistics() overload to handle lsst::afw::math::MaskedVector<>
Definition: Statistics.h:518
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:414
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:84
Config class for single frame measurement driver task.
Definition: sfm.py:116
int max
Definition: BoundedField.cc:99
std::shared_ptr< PsfCandidate< PixelT > > makePsfCandidate(boost::shared_ptr< afw::table::SourceRecord > const &source, boost::shared_ptr< afw::image::Exposure< PixelT > > image)
Return a PsfCandidate of the right sort.
Definition: PsfCandidate.h:182
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
def selectStars(self, exposure, sourceCat, matches=None)
Return a list of PSF candidates that represent likely stars.
daf::base::PropertyList * list
Definition: fits.cc:819