LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
Functions | Variables
lsst.meas.algorithms.utils Namespace Reference

Functions

def splitId
 
def showSourceSet
 
def showPsfSpatialCells
 
def showPsfCandidates
 
def makeSubplots
 
def plotPsfSpatialModel
 
def showPsf
 
def showPsfMosaic
 
def showPsfResiduals
 
def saveSpatialCellSet
 

Variables

 keptPlots = False
 
 plt = None
 

Function Documentation

def lsst.meas.algorithms.utils.makeSubplots (   fig,
  nx = 2,
  ny = 2,
  Nx = 1,
  Ny = 1,
  plottingArea = (0.1, 0.1,
  pxgutter = 0.05,
  pygutter = 0.05,
  xgutter = 0.04,
  ygutter = 0.04,
  headroom = 0.0,
  panelBorderWeight = 0,
  panelColor = 'black' 
)
Return a generator of a set of subplots, a set of Nx*Ny panels of nx*ny plots.  Each panel is fully
filled by row (starting in the bottom left) before the next panel is started.  If panelBorderWidth is
greater than zero a border is drawn around each panel, adjusted to enclose the axis labels.

E.g.
subplots = makeSubplots(fig, 2, 2, Nx=1, Ny=1, panelColor='k')
ax = subplots.next(); ax.text(0.3, 0.5, '[0, 0] (0,0)')
ax = subplots.next(); ax.text(0.3, 0.5, '[0, 0] (1,0)')
ax = subplots.next(); ax.text(0.3, 0.5, '[0, 0] (0,1)')
ax = subplots.next(); ax.text(0.3, 0.5, '[0, 0] (1,1)')
fig.show()

@param fig    The matplotlib figure to draw
@param nx     The number of plots in each row of each panel
@param ny     The number of plots in each column of each panel
@param Nx     The number of panels in each row of the figure
@param Ny     The number of panels in each column of the figure
@param plottingArea  (x0, y0, x1, y1) for the part of the figure containing all the panels
@param pxgutter Spacing between columns of panels in units of (x1 - x0)
@param pygutter Spacing between rows of panels in units of (y1 - y0)
@param xgutter  Spacing between columns of plots within a panel in units of (x1 - x0)
@param ygutter  Spacing between rows of plots within a panel in units of (y1 - y0)
@param headroom Extra spacing above each plot for e.g. a title
@param panelBorderWeight Width of border drawn around panels
@param panelColor Colour of border around panels

Definition at line 288 of file utils.py.

289  headroom=0.0, panelBorderWeight=0, panelColor='black'):
290  """Return a generator of a set of subplots, a set of Nx*Ny panels of nx*ny plots. Each panel is fully
291  filled by row (starting in the bottom left) before the next panel is started. If panelBorderWidth is
292  greater than zero a border is drawn around each panel, adjusted to enclose the axis labels.
293 
294  E.g.
295  subplots = makeSubplots(fig, 2, 2, Nx=1, Ny=1, panelColor='k')
296  ax = subplots.next(); ax.text(0.3, 0.5, '[0, 0] (0,0)')
297  ax = subplots.next(); ax.text(0.3, 0.5, '[0, 0] (1,0)')
298  ax = subplots.next(); ax.text(0.3, 0.5, '[0, 0] (0,1)')
299  ax = subplots.next(); ax.text(0.3, 0.5, '[0, 0] (1,1)')
300  fig.show()
301 
302  @param fig The matplotlib figure to draw
303  @param nx The number of plots in each row of each panel
304  @param ny The number of plots in each column of each panel
305  @param Nx The number of panels in each row of the figure
306  @param Ny The number of panels in each column of the figure
307  @param plottingArea (x0, y0, x1, y1) for the part of the figure containing all the panels
308  @param pxgutter Spacing between columns of panels in units of (x1 - x0)
309  @param pygutter Spacing between rows of panels in units of (y1 - y0)
310  @param xgutter Spacing between columns of plots within a panel in units of (x1 - x0)
311  @param ygutter Spacing between rows of plots within a panel in units of (y1 - y0)
312  @param headroom Extra spacing above each plot for e.g. a title
313  @param panelBorderWeight Width of border drawn around panels
314  @param panelColor Colour of border around panels
315  """
316  #
317  # Make show() call canvas.draw() too so that we know how large the axis labels are. Sigh
318  try:
319  fig.__show
320  except AttributeError:
321  fig.__show = fig.show
322  def myShow(fig):
323  fig.__show()
324  fig.canvas.draw()
325 
326  import types
327  fig.show = types.MethodType(myShow, fig, fig.__class__)
328  #
329  # We can't get the axis sizes until after draw()'s been called, so use a callback Sigh^2
330  #
331  axes = {} # all axes in all the panels we're drawing: axes[panel][0] etc.
332  #
333  def on_draw(event):
334  """
335  Callback to draw the panel borders when the plots are drawn to the canvas
336  """
337  if panelBorderWeight <= 0:
338  return False
339 
340  for p in axes.keys():
341  bboxes = []
342  for ax in axes[p]:
343  bboxes.append(ax.bbox.union([label.get_window_extent() for label in
344  ax.get_xticklabels() + ax.get_yticklabels()]))
345 
346  ax = axes[p][0]
347 
348  # this is the bbox that bounds all the bboxes, again in relative
349  # figure coords
350 
351  bbox = ax.bbox.union(bboxes)
352 
353  xy0, xy1 = ax.transData.inverted().transform(bbox)
354  x0, y0 = xy0; x1, y1 = xy1
355  w, h = x1 - x0, y1 - y0
356  # allow a little space around BBox
357  x0 -= 0.02*w; w += 0.04*w
358  y0 -= 0.02*h; h += 0.04*h
359  h += h*headroom
360  # draw BBox
361  ax.patches = [] # remove old ones
362  rec = ax.add_patch(plt.Rectangle((x0, y0), w, h, fill=False,
363  lw=panelBorderWeight, edgecolor=panelColor))
364  rec.set_clip_on(False)
365 
366  return False
367 
368  fig.canvas.mpl_connect('draw_event', on_draw)
369  #
370  # Choose the plotting areas for each subplot
371  #
372  x0, y0 = plottingArea[0:2]
373  W, H = plottingArea[2:4]
374  w = (W - (Nx - 1)*pxgutter - (nx*Nx - 1)*xgutter)/float(nx*Nx)
375  h = (H - (Ny - 1)*pygutter - (ny*Ny - 1)*ygutter)/float(ny*Ny)
376  #
377  # OK! Time to create the subplots
378  #
379  for panel in range(Nx*Ny):
380  axes[panel] = []
381  px = panel%Nx
382  py = panel//Nx
383  for window in range(nx*ny):
384  x = nx*px + window%nx
385  y = ny*py + window//nx
386  ax = fig.add_axes((x0 + xgutter + pxgutter + x*w + (px - 1)*pxgutter + (x - 1)*xgutter,
387  y0 + ygutter + pygutter + y*h + (py - 1)*pygutter + (y - 1)*ygutter,
388  w, h), frame_on=True, axis_bgcolor='w')
389  axes[panel].append(ax)
390  yield ax
def lsst.meas.algorithms.utils.plotPsfSpatialModel (   exposure,
  psf,
  psfCellSet,
  showBadCandidates = True,
  numSample = 128,
  matchKernelAmplitudes = False,
  keepPlots = True 
)
Plot the PSF spatial model.

Definition at line 392 of file utils.py.

393  matchKernelAmplitudes=False, keepPlots=True):
394  """Plot the PSF spatial model."""
395 
396  if not plt:
397  print >> sys.stderr, "Unable to import matplotlib"
398  return
399 
400  noSpatialKernel = afwMath.cast_LinearCombinationKernel(psf.getKernel())
401  candPos = list()
402  candFits = list()
403  badPos = list()
404  badFits = list()
405  candAmps = list()
406  badAmps = list()
407  for cell in psfCellSet.getCellList():
408  for cand in cell.begin(False):
409  cand = algorithmsLib.cast_PsfCandidateF(cand)
410  if not showBadCandidates and cand.isBad():
411  continue
412  candCenter = afwGeom.PointD(cand.getXCenter(), cand.getYCenter())
413  try:
414  im = cand.getMaskedImage()
415  except Exception:
416  continue
417 
418  fit = algorithmsLib.fitKernelParamsToImage(noSpatialKernel, im, candCenter)
419  params = fit[0]
420  kernels = fit[1]
421  amp = 0.0
422  for p, k in zip(params, kernels):
423  amp += p * afwMath.cast_FixedKernel(k).getSum()
424 
425  targetFits = badFits if cand.isBad() else candFits
426  targetPos = badPos if cand.isBad() else candPos
427  targetAmps = badAmps if cand.isBad() else candAmps
428 
429  targetFits.append([x / amp for x in params])
430  targetPos.append(candCenter)
431  targetAmps.append(amp)
432 
433  numCandidates = len(candFits)
434  numBasisFuncs = noSpatialKernel.getNBasisKernels()
435 
436  xGood = numpy.array([pos.getX() for pos in candPos]) - exposure.getX0()
437  yGood = numpy.array([pos.getY() for pos in candPos]) - exposure.getY0()
438  zGood = numpy.array(candFits)
439  ampGood = numpy.array(candAmps)
440 
441  xBad = numpy.array([pos.getX() for pos in badPos]) - exposure.getX0()
442  yBad = numpy.array([pos.getY() for pos in badPos]) - exposure.getY0()
443  zBad = numpy.array(badFits)
444  ampBad = numpy.array(badAmps)
445  numBad = len(badPos)
446 
447  xRange = numpy.linspace(0, exposure.getWidth(), num=numSample)
448  yRange = numpy.linspace(0, exposure.getHeight(), num=numSample)
449 
450  kernel = psf.getKernel()
451  nKernelComponents = kernel.getNKernelParameters()
452  #
453  # Figure out how many panels we'll need
454  #
455  nPanelX = int(math.sqrt(nKernelComponents))
456  nPanelY = nKernelComponents//nPanelX
457  while nPanelY*nPanelX < nKernelComponents:
458  nPanelX += 1
459 
460  fig = plt.figure(1)
461  fig.clf()
462  try:
463  fig.canvas._tkcanvas._root().lift() # == Tk's raise, but raise is a python reserved word
464  except: # protect against API changes
465  pass
466  #
467  # Generator for axes arranged in panels
468  #
469  subplots = makeSubplots(fig, 2, 2, Nx=nPanelX, Ny=nPanelY, xgutter=0.06, ygutter=0.06, pygutter=0.04)
470 
471  for k in range(nKernelComponents):
472  func = kernel.getSpatialFunction(k)
473  dfGood = zGood[:,k] - numpy.array([func(pos.getX(), pos.getY()) for pos in candPos])
474  yMin = dfGood.min()
475  yMax = dfGood.max()
476  if numBad > 0:
477  dfBad = zBad[:,k] - numpy.array([func(pos.getX(), pos.getY()) for pos in badPos])
478  yMin = min([yMin, dfBad.min()])
479  yMax = max([yMax, dfBad.max()])
480  yMin -= 0.05 * (yMax - yMin)
481  yMax += 0.05 * (yMax - yMin)
482 
483  yMin = -0.01
484  yMax = 0.01
485 
486  fRange = numpy.ndarray((len(xRange), len(yRange)))
487  for j, yVal in enumerate(yRange):
488  for i, xVal in enumerate(xRange):
489  fRange[j][i] = func(xVal, yVal)
490 
491  #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
492 
493  ax = subplots.next()
494 
495  ax.set_autoscale_on(False)
496  ax.set_xbound(lower=0, upper=exposure.getHeight())
497  ax.set_ybound(lower=yMin, upper=yMax)
498  ax.plot(yGood, dfGood, 'b+')
499  if numBad > 0:
500  ax.plot(yBad, dfBad, 'r+')
501  ax.axhline(0.0)
502  ax.set_title('Residuals(y)')
503 
504  #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
505 
506  ax = subplots.next()
507 
508  if matchKernelAmplitudes and k == 0:
509  vmin = 0.0
510  vmax = 1.1
511  else:
512  vmin = fRange.min()
513  vmax = fRange.max()
514 
515  norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
516  im = ax.imshow(fRange, aspect='auto', origin="lower", norm=norm,
517  extent=[0, exposure.getWidth()-1, 0, exposure.getHeight()-1])
518  ax.set_title('Spatial poly')
519  plt.colorbar(im, orientation='horizontal', ticks=[vmin, vmax])
520 
521  #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
522 
523  ax = subplots.next()
524  ax.set_autoscale_on(False)
525  ax.set_xbound(lower=0, upper=exposure.getWidth())
526  ax.set_ybound(lower=yMin, upper=yMax)
527  ax.plot(xGood, dfGood, 'b+')
528  if numBad > 0:
529  ax.plot(xBad, dfBad, 'r+')
530  ax.axhline(0.0)
531  ax.set_title('K%d Residuals(x)' % k)
532 
533  #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
534 
535  ax = subplots.next()
536 
537  if False:
538  ax.scatter(xGood, yGood, c=dfGood, marker='o')
539  ax.scatter(xBad, yBad, c=dfBad, marker='x')
540  ax.set_xbound(lower=0, upper=exposure.getWidth())
541  ax.set_ybound(lower=0, upper=exposure.getHeight())
542  ax.set_title('Spatial residuals')
543  plt.colorbar(im, orientation='horizontal')
544  else:
545  calib = exposure.getCalib()
546  if calib.getFluxMag0()[0] <= 0:
547  calib = type(calib)()
548  calib.setFluxMag0(1.0)
549 
550  with CalibNoThrow():
551  ax.plot(calib.getMagnitude(candAmps), zGood[:,k], 'b+')
552  if numBad > 0:
553  ax.plot(calib.getMagnitude(badAmps), zBad[:,k], 'r+')
554 
555  ax.set_title('Flux variation')
556 
557  fig.show()
558 
559  global keptPlots
560  if keepPlots and not keptPlots:
561  # Keep plots open when done
562  def show():
563  print "%s: Please close plots when done." % __name__
564  try:
565  plt.show()
566  except:
567  pass
568  print "Plots closed, exiting..."
569  import atexit
570  atexit.register(show)
571  keptPlots = True
def lsst.meas.algorithms.utils.saveSpatialCellSet (   psfCellSet,
  fileName = "foo.fits",
  frame = None 
)
Write the contents of a SpatialCellSet to a many-MEF fits file

Definition at line 773 of file utils.py.

774 def saveSpatialCellSet(psfCellSet, fileName="foo.fits", frame=None):
775  """Write the contents of a SpatialCellSet to a many-MEF fits file"""
776 
777  mode = "w"
778  for cell in psfCellSet.getCellList():
779  for cand in cell.begin(False): # include bad candidates
780  cand = algorithmsLib.cast_PsfCandidateF(cand)
781 
782  dx = afwImage.positionToIndex(cand.getXCenter(), True)[1]
783  dy = afwImage.positionToIndex(cand.getYCenter(), True)[1]
784  im = afwMath.offsetImage(cand.getMaskedImage(), -dx, -dy, "lanczos5")
785 
786  md = dafBase.PropertySet()
787  md.set("CELL", cell.getLabel())
788  md.set("ID", cand.getId())
789  md.set("XCENTER", cand.getXCenter())
790  md.set("YCENTER", cand.getYCenter())
791  md.set("BAD", cand.isBad())
792  md.set("AMPL", cand.getAmplitude())
793  md.set("FLUX", cand.getSource().getPsfFlux())
794  md.set("CHI2", cand.getSource().getChi2())
795 
796  im.writeFits(fileName, md, mode)
797  mode = "a"
798 
799  if frame is not None:
800  ds9.mtv(im, frame=frame)
std::pair< int, double > positionToIndex(double const pos, bool)
Convert image position to index (nearest integer and fractional parts)
Definition: ImageUtils.h:100
ImageT::Ptr offsetImage(ImageT const &image, float dx, float dy, std::string const &algorithmName="lanczos5", unsigned int buffer=0)
Return an image offset by (dx, dy) using the specified algorithm.
Definition: offsetImage.cc:55
Class for storing generic metadata.
Definition: PropertySet.h:82
def lsst.meas.algorithms.utils.showPsf (   psf,
  eigenValues = None,
  XY = None,
  normalize = True,
  frame = None 
)
Display a PSF's eigen images

If normalize is True, set the largest absolute value of each eigenimage to 1.0 (n.b. sum == 0.0 for i > 0)

Definition at line 572 of file utils.py.

573 def showPsf(psf, eigenValues=None, XY=None, normalize=True, frame=None):
574  """Display a PSF's eigen images
575 
576  If normalize is True, set the largest absolute value of each eigenimage to 1.0 (n.b. sum == 0.0 for i > 0)
577  """
578 
579  if eigenValues:
580  coeffs = eigenValues
581  elif XY is not None:
582  coeffs = psf.getLocalKernel(afwGeom.PointD(XY[0], XY[1])).getKernelParameters()
583  else:
584  coeffs = None
585 
586  mos = displayUtils.Mosaic()
587  i = 0
588  for k in afwMath.cast_LinearCombinationKernel(psf.getKernel()).getKernelList():
589  im = afwImage.ImageD(k.getDimensions())
590  k.computeImage(im, False)
591  if normalize:
592  im /= numpy.max(numpy.abs(im.getArray()))
593 
594  if coeffs:
595  mos.append(im, "%g" % (coeffs[i]/coeffs[0]))
596  i += 1
597  else:
598  mos.append(im)
599 
600  mos.makeMosaic(frame=frame, title="Eigen Images")
601 
602  return mos
def lsst.meas.algorithms.utils.showPsfCandidates (   exposure,
  psfCellSet,
  psf = None,
  frame = None,
  normalize = True,
  showBadCandidates = True,
  variance = None,
  chi = None 
)
Display the PSF candidates.
If psf is provided include PSF model and residuals;  if normalize is true normalize the PSFs (and residuals)
If chi is True, generate a plot of residuals/sqrt(variance), i.e. chi

Definition at line 120 of file utils.py.

121  variance=None, chi=None):
122  """Display the PSF candidates.
123 If psf is provided include PSF model and residuals; if normalize is true normalize the PSFs (and residuals)
124 If chi is True, generate a plot of residuals/sqrt(variance), i.e. chi
125 """
126  if chi is None:
127  if variance is not None: # old name for chi
128  chi = variance
129  #
130  # Show us the ccandidates
131  #
132  mos = displayUtils.Mosaic()
133  #
134  candidateCenters = []
135  candidateCentersBad = []
136  candidateIndex = 0
137 
138  for cell in psfCellSet.getCellList():
139  for cand in cell.begin(False): # include bad candidates
140  cand = algorithmsLib.cast_PsfCandidateF(cand)
141 
142  rchi2 = cand.getChi2()
143  if rchi2 > 1e100:
144  rchi2 = numpy.nan
145 
146  if not showBadCandidates and cand.isBad():
147  continue
148 
149  if psf:
150  im_resid = displayUtils.Mosaic(gutter=0, background=-5, mode="x")
151 
152  try:
153  im = cand.getMaskedImage() # copy of this object's image
154  xc, yc = cand.getXCenter(), cand.getYCenter()
155 
156  margin = 0 if True else 5
157  w, h = im.getDimensions()
158  bbox = afwGeom.BoxI(afwGeom.PointI(margin, margin), im.getDimensions())
159 
160  if margin > 0:
161  bim = im.Factory(w + 2*margin, h + 2*margin)
162 
163  stdev = numpy.sqrt(afwMath.makeStatistics(im.getVariance(), afwMath.MEAN).getValue())
165  bim *= stdev
166  var = bim.getVariance(); var.set(stdev**2); del var
167 
168  sbim = im.Factory(bim, bbox)
169  sbim <<= im
170  del sbim
171  im = bim
172  xc += margin; yc += margin
173 
174  im = im.Factory(im, True)
175  im.setXY0(cand.getMaskedImage().getXY0())
176  except:
177  continue
178 
179  if not variance:
180  im_resid.append(im.Factory(im, True))
181 
182  # residuals using spatial model
183  try:
184  chi2 = algorithmsLib.subtractPsf(psf, im, xc, yc)
185  except:
186  chi2 = numpy.nan
187 
188  resid = im
189  if variance:
190  resid = resid.getImage()
191  var = im.getVariance()
192  var = var.Factory(var, True)
193  numpy.sqrt(var.getArray(), var.getArray()) # inplace sqrt
194  resid /= var
195 
196  im_resid.append(resid)
197 
198  # Fit the PSF components directly to the data (i.e. ignoring the spatial model)
199  im = cand.getMaskedImage()
200 
201  im = im.Factory(im, True)
202  im.setXY0(cand.getMaskedImage().getXY0())
203 
204  try:
205  noSpatialKernel = afwMath.cast_LinearCombinationKernel(psf.getKernel())
206  except:
207  noSpatialKernel = None
208 
209  if noSpatialKernel:
210  candCenter = afwGeom.PointD(cand.getXCenter(), cand.getYCenter())
211  fit = algorithmsLib.fitKernelParamsToImage(noSpatialKernel, im, candCenter)
212  params = fit[0]
213  kernels = afwMath.KernelList(fit[1])
214  outputKernel = afwMath.LinearCombinationKernel(kernels, params)
215 
216  outImage = afwImage.ImageD(outputKernel.getDimensions())
217  outputKernel.computeImage(outImage, False)
218 
219  im -= outImage.convertF()
220  resid = im
221 
222  if margin > 0:
223  bim = im.Factory(w + 2*margin, h + 2*margin)
225  bim *= stdev
226 
227  sbim = im.Factory(bim, bbox)
228  sbim <<= resid
229  del sbim
230  resid = bim
231 
232  if variance:
233  resid = resid.getImage()
234  resid /= var
235 
236  im_resid.append(resid)
237 
238  im = im_resid.makeMosaic()
239  else:
240  im = cand.getMaskedImage()
241 
242  if normalize:
243  im /= afwMath.makeStatistics(im, afwMath.MAX).getValue()
244 
245  objId = splitId(cand.getSource().getId(), True)["objId"]
246  if psf:
247  lab = "%d chi^2 %.1f" % (objId, rchi2)
248  ctype = ds9.RED if cand.isBad() else ds9.GREEN
249  else:
250  lab = "%d flux %8.3g" % (objId, cand.getSource().getPsfFlux())
251  ctype = ds9.GREEN
252 
253  mos.append(im, lab, ctype)
254 
255  if False and numpy.isnan(rchi2):
256  ds9.mtv(cand.getMaskedImage().getImage(), title="candidate", frame=1)
257  print "amp", cand.getAmplitude()
258 
259  im = cand.getMaskedImage()
260  center = (candidateIndex, xc - im.getX0(), yc - im.getY0())
261  candidateIndex += 1
262  if cand.isBad():
263  candidateCentersBad.append(center)
264  else:
265  candidateCenters.append(center)
266 
267  if variance:
268  title = "chi(Psf fit)"
269  else:
270  title = "Stars & residuals"
271  mosaicImage = mos.makeMosaic(frame=frame, title=title)
272 
273  with ds9.Buffering():
274  for centers, color in ((candidateCenters, ds9.GREEN), (candidateCentersBad, ds9.RED)):
275  for cen in centers:
276  bbox = mos.getBBox(cen[0])
277  ds9.dot("+", cen[1] + bbox.getMinX(), cen[2] + bbox.getMinY(), frame=frame, ctype=color)
278 
279  return mosaicImage
280 
281 try:
282  import matplotlib.pyplot as plt
import matplotlib.colors
An integer coordinate rectangle.
Definition: Box.h:53
A kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:814
void randomGaussianImage(ImageT *image, Random &rand)
Definition: RandomImage.cc:155
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Definition: Statistics.cc:1082
std::vector< boost::shared_ptr< Kernel > > KernelList
Definition: Kernel.h:542
def lsst.meas.algorithms.utils.showPsfMosaic (   exposure,
  psf = None,
  nx = 7,
  ny = None,
  showCenter = True,
  showEllipticity = False,
  showFwhm = False,
  stampSize = 0,
  frame = None,
  title = None 
)
Show a mosaic of Psf images.  exposure may be an Exposure (optionally with PSF), or a tuple (width, height)

If stampSize is > 0, the psf images will be trimmed to stampSize*stampSize

Definition at line 605 of file utils.py.

606  stampSize=0, frame=None, title=None):
607  """Show a mosaic of Psf images. exposure may be an Exposure (optionally with PSF), or a tuple (width, height)
608 
609  If stampSize is > 0, the psf images will be trimmed to stampSize*stampSize
610  """
611 
612  scale = 1.0
613  if showFwhm:
614  showEllipticity = True
615  scale = 2*math.log(2) # convert sigma^2 to HWHM^2 for a Gaussian
616 
617  mos = displayUtils.Mosaic()
618 
619  try: # maybe it's a real Exposure
620  width, height = exposure.getWidth(), exposure.getHeight()
621  x0, y0 = exposure.getXY0()
622  if not psf:
623  psf = exposure.getPsf()
624  except AttributeError:
625  try: # OK, maybe a list [width, height]
626  width, height = exposure[0], exposure[1]
627  x0, y0 = 0, 0
628  except TypeError: # I guess not
629  raise RuntimeError, ("Unable to extract width/height from object of type %s" % type(exposure))
630 
631  if not ny:
632  ny = int(nx*float(height)/width + 0.5)
633  if not ny:
634  ny = 1
635 
636  schema = afwTable.SourceTable.makeMinimalSchema()
637 
638  control = algorithmsLib.GaussianCentroidControl()
639  centroider = algorithmsLib.MeasureSourcesBuilder().addAlgorithm(control).build(schema)
640 
641  sdssShape = algorithmsLib.SdssShapeControl()
642  shaper = algorithmsLib.MeasureSourcesBuilder().addAlgorithm(sdssShape).build(schema)
643 
644  table = afwTable.SourceTable.make(schema)
645 
646  table.defineCentroid(control.name)
647  table.defineShape(sdssShape.name)
648 
649  bbox = None
650  if stampSize > 0:
651  w, h = psf.computeImage(afwGeom.PointD(0, 0)).getDimensions()
652  if stampSize <= w and stampSize <= h:
653  bbox = afwGeom.BoxI(afwGeom.PointI((w - stampSize)//2, (h - stampSize)//2),
654  afwGeom.ExtentI(stampSize, stampSize))
655 
656  centers = []
657  shapes = []
658  for iy in range(ny):
659  for ix in range(nx):
660  x = int(ix*(width-1)/(nx-1)) + x0
661  y = int(iy*(height-1)/(ny-1)) + y0
662 
663  im = psf.computeImage(afwGeom.PointD(x, y)).convertF()
664  imPeak = psf.computePeak(afwGeom.PointD(x, y))
665  im /= imPeak
666  if bbox:
667  im = im.Factory(im, bbox)
668  lab = "PSF(%d,%d)" % (x, y) if False else ""
669  mos.append(im, lab)
670 
672  w, h = im.getWidth(), im.getHeight()
673  cen = afwGeom.PointD(im.getX0() + w//2, im.getY0() + h//2)
674  src = table.makeRecord()
675  foot = afwDet.Footprint(exp.getBBox())
676  src.setFootprint(foot)
677 
678  centroider.apply(src, exp, cen)
679  centers.append((src.getX() - im.getX0(), src.getY() - im.getY0()))
680 
681  shaper.apply(src, exp, cen)
682  shapes.append((src.getIxx(), src.getIxy(), src.getIyy()))
683 
684  mos.makeMosaic(frame=frame, title=title if title else "Model Psf", mode=nx)
685 
686  if centers and frame is not None:
687  i = 0
688  with ds9.Buffering():
689  for cen, shape in zip(centers, shapes):
690  bbox = mos.getBBox(i); i += 1
691  xc, yc = cen[0] + bbox.getMinX(), cen[1] + bbox.getMinY()
692  if showCenter:
693  ds9.dot("+", xc, yc, ctype=ds9.BLUE, frame=frame)
694 
695  if showEllipticity:
696  ixx, ixy, iyy = shape
697  ixx *= scale; ixy *= scale; iyy *= scale
698  ds9.dot("@:%g,%g,%g" % (ixx, ixy, iyy), xc, yc, frame=frame, ctype=ds9.RED)
699 
700  return mos
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > * makeMaskedImage(typename Image< ImagePixelT >::Ptr image, typename Mask< MaskPixelT >::Ptr mask=typename Mask< MaskPixelT >::Ptr(), typename Image< VariancePixelT >::Ptr variance=typename Image< VariancePixelT >::Ptr())
Definition: MaskedImage.h:1067
An integer coordinate rectangle.
Definition: Box.h:53
A set of pixels in an Image.
Definition: Footprint.h:62
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.utils.showPsfResiduals (   exposure,
  sourceSet,
  magType = "psf",
  scale = 10,
  frame = None,
  showAmps = False 
)

Definition at line 701 of file utils.py.

702 def showPsfResiduals(exposure, sourceSet, magType="psf", scale=10, frame=None, showAmps=False):
703  mimIn = exposure.getMaskedImage()
704  mimIn = mimIn.Factory(mimIn, True) # make a copy to subtract from
705 
706  psf = exposure.getPsf()
707  psfWidth, psfHeight = psf.getLocalKernel().getDimensions()
708  #
709  # Make the image that we'll paste our residuals into. N.b. they can overlap the edges
710  #
711  w, h = int(mimIn.getWidth()/scale), int(mimIn.getHeight()/scale)
712 
713  im = mimIn.Factory(w + psfWidth, h + psfHeight)
714 
715  cenPos = []
716  for s in sourceSet:
717  x, y = s.getX(), s.getY()
718 
719  sx, sy = int(x/scale + 0.5), int(y/scale + 0.5)
720 
721  smim = im.Factory(im, afwGeom.BoxI(afwGeom.PointI(sx, sy), afwGeom.ExtentI(psfWidth, psfHeight)))
722  sim = smim.getImage()
723 
724  try:
725  if magType == "ap":
726  flux = s.getApFlux()
727  elif magType == "model":
728  flux = s.getModelFlux()
729  elif magType == "psf":
730  flux = s.getPsfFlux()
731  else:
732  raise RuntimeError("Unknown flux type %s" % magType)
733 
734  algorithmsLib.subtractPsf(psf, mimIn, x, y, flux)
735  except Exception, e:
736  print e
737 
738  try:
739  expIm = mimIn.getImage().Factory(mimIn.getImage(),
740  afwGeom.BoxI(afwGeom.PointI(int(x) - psfWidth//2,
741  int(y) - psfHeight//2),
742  afwGeom.ExtentI(psfWidth, psfHeight)),
743  )
744  except pexExcept.Exception:
745  continue
746 
747  cenPos.append([x - expIm.getX0() + sx, y - expIm.getY0() + sy])
748 
749  sim += expIm
750 
751  if frame is not None:
752  ds9.mtv(im, frame=frame)
753  with ds9.Buffering():
754  for x, y in cenPos:
755  ds9.dot("+", x, y, frame=frame)
756 
757  if showAmps:
758  nx, ny = namp
759  for i in range(nx):
760  for j in range(ny):
761  xc = numpy.array([0, 1, 1, 0, 0])
762  yc = numpy.array([0, 0, 1, 1, 0])
763 
764  corners = []
765  for k in range(len(xc)):
766  corners.append([psfWidth//2 + w/nx*(i + xc[k]), psfHeight//2 + h/ny*(j + yc[k])])
767 
768  ds9.line(corners, frame=frame)
769 
770  return im
771 
772 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
An integer coordinate rectangle.
Definition: Box.h:53
def lsst.meas.algorithms.utils.showPsfSpatialCells (   exposure,
  psfCellSet,
  nMaxPerCell = -1,
  showChi2 = False,
  showMoments = False,
  symb = None,
  ctype = None,
  ctypeUnused = None,
  ctypeBad = None,
  size = 2,
  frame = None 
)
Show the SpatialCells.  If symb is something that ds9.dot understands (e.g. "o"), the top nMaxPerCell candidates will be indicated with that symbol, using ctype and size

Definition at line 71 of file utils.py.

71 
72  symb=None, ctype=None, ctypeUnused=None, ctypeBad=None, size=2, frame=None):
73  """Show the SpatialCells. If symb is something that ds9.dot understands (e.g. "o"), the top nMaxPerCell candidates will be indicated with that symbol, using ctype and size"""
74 
75  with ds9.Buffering():
76  origin = [-exposure.getMaskedImage().getX0(), -exposure.getMaskedImage().getY0()]
77  for cell in psfCellSet.getCellList():
78  displayUtils.drawBBox(cell.getBBox(), origin=origin, frame=frame)
79 
80  if nMaxPerCell < 0:
81  nMaxPerCell = 0
82 
83  i = 0
84  goodies = ctypeBad is None
85  for cand in cell.begin(goodies):
86  if nMaxPerCell > 0:
87  i += 1
88 
89  cand = algorithmsLib.cast_PsfCandidateF(cand)
90 
91  xc, yc = cand.getXCenter() + origin[0], cand.getYCenter() + origin[1]
92 
93  if i > nMaxPerCell:
94  if not ctypeUnused:
95  continue
96 
97  color = ctypeBad if cand.isBad() else ctype
98 
99  if symb:
100  if i > nMaxPerCell:
101  ct = ctypeUnused
102  else:
103  ct = ctype
104 
105  ds9.dot(symb, xc, yc, frame=frame, ctype=ct, size=size)
106 
107  source = cand.getSource()
108 
109  if showChi2:
110  rchi2 = cand.getChi2()
111  if rchi2 > 1e100:
112  rchi2 = numpy.nan
113  ds9.dot("%d %.1f" % (splitId(source.getId(), True)["objId"], rchi2),
114  xc - size, yc - size - 4, frame=frame, ctype=color, size=2)
115 
116  if showMoments:
117  ds9.dot("%.2f %.2f %.2f" % (source.getIxx(), source.getIxy(), source.getIyy()),
118  xc-size, yc + size + 4, frame=frame, ctype=color, size=size)
def lsst.meas.algorithms.utils.showSourceSet (   sSet,
  xy0 = (0, 0,
  frame = 0,
  ctype = ds9.GREEN,
  symb = "+",
  size = 2 
)
Draw the (XAstrom, YAstrom) positions of a set of Sources.  Image has the given XY0

Definition at line 54 of file utils.py.

54 
55 def showSourceSet(sSet, xy0=(0, 0), frame=0, ctype=ds9.GREEN, symb="+", size=2):
56  """Draw the (XAstrom, YAstrom) positions of a set of Sources. Image has the given XY0"""
57 
58  with ds9.Buffering():
59  for s in sSet:
60  xc, yc = s.getXAstrom() - xy0[0], s.getYAstrom() - xy0[1]
61 
62  if symb == "id":
63  ds9.dot(str(splitId(s.getId(), True)["objId"]), xc, yc, frame=frame, ctype=ctype, size=size)
64  else:
65  ds9.dot(symb, xc, yc, frame=frame, ctype=ctype, size=size)
66 
67 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
68 #
69 # PSF display utilities
#
def lsst.meas.algorithms.utils.splitId (   oid,
  asDict = True 
)

Definition at line 45 of file utils.py.

45 
46 def splitId(oid, asDict=True):
47 
48  objId = int((oid & 0xffff) - 1) # Should be the value set by apps code
49 
50  if asDict:
51  return dict(objId=objId)
52  else:
53  return [objId]

Variable Documentation

lsst.meas.algorithms.utils.keptPlots = False

Definition at line 40 of file utils.py.

lsst.meas.algorithms.utils.plt = None

Definition at line 284 of file utils.py.