LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
Public Member Functions | Public Attributes | Private Attributes | List of all members
lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram Class Reference
Inheritance diagram for lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram:

Public Member Functions

def __init__
 
def getImage
 
def insert
 
def momentsToPixel
 
def pixelToMoments
 
def getClumps
 

Public Attributes

 detector
 
 xy0
 

Private Attributes

 _ySize
 
 _yMax
 
 _psfImage
 
 _num
 

Detailed Description

A class to represent a histogram of (Ixx, Iyy)

Definition at line 270 of file secondMomentStarSelector.py.

Constructor & Destructor Documentation

def lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram.__init__ (   self,
  xSize = 32,
  ySize = 32,
  ixxMax = 30,
  iyyMax = 30,
  detector = None,
  xy0 = afwGeom.Point2D(0,0 
)
Construct a _PsfShapeHistogram

The maximum seeing FWHM that can be tolerated is [xy]Max/2.35 pixels.
The 'resolution' of stars vs galaxies/CRs is provided by [xy]Size/[xy]Max.
A larger (better) resolution may thresh the peaks, but a smaller (worse)
resolution will allow stars and galaxies/CRs to mix.  The disadvantages of
a larger (better) resolution can be compensated (some) by using multiple
histogram peaks.

@input[in] [xy]Size: the size of the psfImage (in pixels)
@input[in] ixxMax, iyyMax: the maximum values for I[xy][xy]

Definition at line 273 of file secondMomentStarSelector.py.

274  def __init__(self, xSize=32, ySize=32, ixxMax=30, iyyMax=30, detector=None, xy0=afwGeom.Point2D(0,0)):
275  """Construct a _PsfShapeHistogram
276 
277  The maximum seeing FWHM that can be tolerated is [xy]Max/2.35 pixels.
278  The 'resolution' of stars vs galaxies/CRs is provided by [xy]Size/[xy]Max.
279  A larger (better) resolution may thresh the peaks, but a smaller (worse)
280  resolution will allow stars and galaxies/CRs to mix. The disadvantages of
281  a larger (better) resolution can be compensated (some) by using multiple
282  histogram peaks.
283 
284  @input[in] [xy]Size: the size of the psfImage (in pixels)
285  @input[in] ixxMax, iyyMax: the maximum values for I[xy][xy]
286  """
287  self._xSize, self._ySize = xSize, ySize
288  self._xMax, self._yMax = ixxMax, iyyMax
289  self._psfImage = afwImage.ImageF(afwGeom.ExtentI(xSize, ySize), 0)
290  self._num = 0
291  self.detector = detector
292  self.xy0 = xy0

Member Function Documentation

def lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram.getClumps (   self,
  sigma = 1.0,
  display = False 
)

Definition at line 341 of file secondMomentStarSelector.py.

342  def getClumps(self, sigma=1.0, display=False):
343  if self._num <= 0:
344  raise RuntimeError("No candidate PSF sources")
345 
346  psfImage = self.getImage()
347  #
348  # Embed psfImage into a larger image so we can smooth when measuring it
349  #
350  width, height = psfImage.getWidth(), psfImage.getHeight()
351  largeImg = psfImage.Factory(afwGeom.ExtentI(2*width, 2*height))
352  largeImg.set(0)
353 
354  bbox = afwGeom.BoxI(afwGeom.PointI(width, height), afwGeom.ExtentI(width, height))
355  subLargeImg = psfImage.Factory(largeImg, bbox, afwImage.LOCAL)
356  subLargeImg <<= psfImage
357  del subLargeImg
358  #
359  # Now measure that image, looking for the highest peak. Start by building an Exposure
360  #
361  msk = afwImage.MaskU(largeImg.getDimensions())
362  msk.set(0)
363  var = afwImage.ImageF(largeImg.getDimensions())
364  var.set(1)
365  mpsfImage = afwImage.MaskedImageF(largeImg, msk, var)
366  mpsfImage.setXY0(afwGeom.PointI(-width, -height))
367  del msk
368  del var
369  exposure = afwImage.makeExposure(mpsfImage)
370 
371  #
372  # Next run an object detector
373  #
374  maxVal = afwMath.makeStatistics(psfImage, afwMath.MAX).getValue()
375  threshold = maxVal - sigma*math.sqrt(maxVal)
376  if threshold <= 0.0:
377  threshold = maxVal
378 
379  threshold = afwDetection.Threshold(threshold)
380 
381  ds = afwDetection.FootprintSet(mpsfImage, threshold, "DETECTED")
382  #
383  # And measure it. This policy isn't the one we use to measure
384  # Sources, it's only used to characterize this PSF histogram
385  #
386  schema = afwTable.SourceTable.makeMinimalSchema()
387  psfImageConfig = SingleFrameMeasurementConfig()
388  psfImageConfig.doApplyApCorr = "no"
389  psfImageConfig.slots.centroid = "base_SdssCentroid"
390  psfImageConfig.slots.psfFlux = None #"base_PsfFlux"
391  psfImageConfig.slots.apFlux = "base_CircularApertureFlux_3_0"
392  psfImageConfig.slots.modelFlux = None
393  psfImageConfig.slots.instFlux = None
394  psfImageConfig.slots.calibFlux = None
395  psfImageConfig.slots.shape = "base_SdssShape"
396  # Formerly, this code had centroid.sdss, flux.psf, flux.naive,
397  # flags.pixel, and shape.sdss
398  psfImageConfig.algorithms.names = ["base_SdssCentroid", "base_CircularApertureFlux", "base_SdssShape"]
399  psfImageConfig.algorithms["base_CircularApertureFlux"].radii = [3.0]
400  psfImageConfig.validate()
401  task = SingleFrameMeasurementTask(schema, config=psfImageConfig)
402 
403  catalog = afwTable.SourceCatalog(schema)
404 
405  gaussianWidth = 1.5 # Gaussian sigma for detection convolution
406  exposure.setPsf(algorithmsLib.DoubleGaussianPsf(11, 11, gaussianWidth))
407 
408  ds.makeSources(catalog)
409  #
410  # Show us the Histogram
411  #
412  if display:
413  frame = 1
414  dispImage = mpsfImage.Factory(mpsfImage, afwGeom.BoxI(afwGeom.PointI(width, height),
415  afwGeom.ExtentI(width, height)),
416  afwImage.LOCAL)
417  ds9.mtv(dispImage,title="PSF Selection Image", frame=frame)
418 
419 
420  clumps = list() # List of clumps, to return
421  e = None # thrown exception
422  IzzMin = 1.0 # Minimum value for second moments
423  IzzMax = (self._xSize/8.0)**2 # Max value ... clump r < clumpImgSize/8
424  # diameter should be < 1/4 clumpImgSize
425  apFluxes = []
426  task.run(exposure, catalog) # notes that this is backwards for the new framework
427  for i, source in enumerate(catalog):
428  if source.getCentroidFlag():
429  continue
430  x, y = source.getX(), source.getY()
431 
432  apFluxes.append(source.getApFlux())
433 
434  val = mpsfImage.getImage().get(int(x) + width, int(y) + height)
435 
436  psfClumpIxx = source.getIxx()
437  psfClumpIxy = source.getIxy()
438  psfClumpIyy = source.getIyy()
439 
440  if display:
441  if i == 0:
442  ds9.pan(x, y, frame=frame)
443 
444  ds9.dot("+", x, y, ctype=ds9.YELLOW, frame=frame)
445  ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y,
446  ctype=ds9.YELLOW, frame=frame)
447 
448  if psfClumpIxx < IzzMin or psfClumpIyy < IzzMin:
449  psfClumpIxx = max(psfClumpIxx, IzzMin)
450  psfClumpIyy = max(psfClumpIyy, IzzMin)
451  if display:
452  ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y,
453  ctype=ds9.RED, frame=frame)
454 
455  det = psfClumpIxx*psfClumpIyy - psfClumpIxy*psfClumpIxy
456  try:
457  a, b, c = psfClumpIyy/det, -psfClumpIxy/det, psfClumpIxx/det
458  except ZeroDivisionError:
459  a, b, c = 1e4, 0, 1e4
460 
461  clumps.append(Clump(peak=val, x=x, y=y, a=a, b=b, c=c,
462  ixx=psfClumpIxx, ixy=psfClumpIxy, iyy=psfClumpIyy))
463 
464  if len(clumps) == 0:
465  msg = "Failed to determine center of PSF clump"
466  if e:
467  msg += ": %s" % e
468  raise RuntimeError(msg)
469 
470  # if it's all we got return it
471  if len(clumps) == 1:
472  return clumps
473 
474  # which clump is the best?
475  # if we've undistorted the moments, stars should only have 1 clump
476  # use the apFlux from the clump measurement, and take the highest
477  # ... this clump has more psf star candidate neighbours than the others.
478 
479  # get rid of any that are huge, and thus poorly defined
480  goodClumps = []
481  for clump in clumps:
482  if clump.ixx < IzzMax and clump.iyy < IzzMax:
483  goodClumps.append(clump)
484 
485  # if culling > IzzMax cost us all clumps, we'll have to take what we have
486  if len(goodClumps) == 0:
487  goodClumps = clumps
488 
489  # use the 'brightest' clump
490  iBestClump = numpy.argsort(apFluxes)[0]
491  clumps = [clumps[iBestClump]]
492  return clumps
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:44
An integer coordinate rectangle.
Definition: Box.h:53
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
Definition: fwd.h:55
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Definition: Statistics.cc:1082
Exposure< ImagePixelT, MaskPixelT, VariancePixelT >::Ptr makeExposure(MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > &mimage, boost::shared_ptr< Wcs const > wcs=boost::shared_ptr< Wcs const >())
Definition: Exposure.h:308
def lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram.getImage (   self)

Definition at line 293 of file secondMomentStarSelector.py.

294  def getImage(self):
295  return self._psfImage
def lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram.insert (   self,
  source 
)
Insert source into the histogram.

Definition at line 296 of file secondMomentStarSelector.py.

297  def insert(self, source):
298  """Insert source into the histogram."""
299 
300  ixx, iyy, ixy = source.getIxx(), source.getIyy(), source.getIxy()
301  if self.detector:
302  tanSys = self.detector.makeCameraSys(cameraGeom.TAN_PIXELS)
303  if tanSys in self.detector.getTransformMap():
304  pixToTanXYTransform = self.detector.getTransformMap()[tanSys]
305  p = afwGeom.Point2D(source.getX(), source.getY())
306  linTransform = pixToTanXYTransform.linearizeForwardTransform(p).getLinear()
307  m = geomEllip.Quadrupole(ixx, iyy, ixy)
308  m.transform(linTransform)
309  ixx, iyy, ixy = m.getIxx(), m.getIyy(), m.getIxy()
310 
311  try:
312  pixel = self.momentsToPixel(ixx, iyy)
313  i = int(pixel[0])
314  j = int(pixel[1])
315  except:
316  return 0
317 
318  if i in range(0, self._xSize) and j in range(0, self._ySize):
319  if i != 0 or j != 0:
320  self._psfImage.set(i, j, self._psfImage.get(i, j) + 1)
321  self._num += 1
322  return 1 # success
323 
324  return 0 # failure
def lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram.momentsToPixel (   self,
  ixx,
  iyy 
)

Definition at line 325 of file secondMomentStarSelector.py.

326  def momentsToPixel(self, ixx, iyy):
327  #x = math.sqrt(ixx) * self._xSize / self._xMax
328  #y = math.sqrt(iyy) * self._ySize / self._yMax
329  x = ixx * self._xSize / self._xMax
330  y = iyy * self._ySize / self._yMax
331  return x, y
def lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram.pixelToMoments (   self,
  x,
  y 
)
Given a peak position in self._psfImage, return the corresponding (Ixx, Iyy)

Definition at line 332 of file secondMomentStarSelector.py.

333  def pixelToMoments(self, x, y):
334  """Given a peak position in self._psfImage, return the corresponding (Ixx, Iyy)"""
335 
336  #ixx = (x*self._xMax/self._xSize)**2
337  #iyy = (y*self._yMax/self._ySize)**2
338  ixx = x*self._xMax/self._xSize
339  iyy = y*self._yMax/self._ySize
340  return ixx, iyy

Member Data Documentation

lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram._num
private

Definition at line 289 of file secondMomentStarSelector.py.

lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram._psfImage
private

Definition at line 288 of file secondMomentStarSelector.py.

lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram._yMax
private

Definition at line 287 of file secondMomentStarSelector.py.

lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram._ySize
private

Definition at line 286 of file secondMomentStarSelector.py.

lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram.detector

Definition at line 290 of file secondMomentStarSelector.py.

lsst.meas.algorithms.secondMomentStarSelector._PsfShapeHistogram.xy0

Definition at line 291 of file secondMomentStarSelector.py.


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