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
utils.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008, 2009, 2010 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 
23 """Support utilities for Measuring sources"""
24 import numpy as np
25 import lsst.pex.logging as pexLog
26 import lsst.afw.detection as afwDet
27 import lsst.afw.geom as afwGeom
28 import lsst.afw.image as afwImage
29 import lsst.afw.math as afwMath
30 import lsst.afw.table as afwTable
31 import lsst.afw.display.ds9 as ds9
32 import lsst.afw.display.utils as displayUtils
33 import lsst.meas.algorithms as measAlg
34 from . import diffimLib
35 from . import diffimTools
36 
37 keptPlots = False # Have we arranged to keep spatial plots open?
38 
39 def showSourceSet(sSet, xy0=(0, 0), frame=0, ctype=ds9.GREEN, symb="+", size=2):
40  """Draw the (XAstrom, YAstrom) positions of a set of Sources. Image has the given XY0"""
41 
42  with ds9.Buffering():
43  for s in sSet:
44  xc, yc = s.getXAstrom() - xy0[0], s.getYAstrom() - xy0[1]
45 
46  if symb == "id":
47  ds9.dot(str(s.getId()), xc, yc, frame=frame, ctype=ctype, size=size)
48  else:
49  ds9.dot(symb, xc, yc, frame=frame, ctype=ctype, size=size)
50 
51 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
52 #
53 # Kernel display utilities
54 #
55 def showKernelSpatialCells(maskedIm, kernelCellSet, showChi2=False, symb="o",
56  ctype=None, ctypeUnused=None, ctypeBad=None, size=3,
57  frame=None, title="Spatial Cells"):
58  """Show the SpatialCells. If symb is something that ds9.dot
59  understands (e.g. "o"), the top nMaxPerCell candidates will be
60  indicated with that symbol, using ctype and size"""
61 
62  ds9.mtv(maskedIm, frame=frame, title=title)
63  with ds9.Buffering():
64  origin = [-maskedIm.getX0(), -maskedIm.getY0()]
65  for cell in kernelCellSet.getCellList():
66  displayUtils.drawBBox(cell.getBBox(), origin=origin, frame=frame)
67 
68  goodies = ctypeBad is None
69  for cand in cell.begin(goodies):
70  cand = diffimLib.cast_KernelCandidateF(cand)
71  xc, yc = cand.getXCenter() + origin[0], cand.getYCenter() + origin[1]
72  if cand.getStatus() == afwMath.SpatialCellCandidate.BAD:
73  color = ctypeBad
74  elif cand.getStatus() == afwMath.SpatialCellCandidate.GOOD:
75  color = ctype
76  elif cand.getStatus() == afwMath.SpatialCellCandidate.UNKNOWN:
77  color = ctypeUnused
78  else:
79  continue
80 
81  if color:
82  ds9.dot(symb, xc, yc, frame=frame, ctype=color, size=size)
83 
84  if showChi2:
85  rchi2 = cand.getChi2()
86  if rchi2 > 1e100:
87  rchi2 = np.nan
88  ds9.dot("%d %.1f" % (cand.getId(), rchi2),
89  xc - size, yc - size - 4, frame=frame, ctype=color, size=size)
90 
91 
92 def showDiaSources(sources, exposure, isFlagged, isDipole, frame=None):
93  """Display Dia Sources
94  """
95  #
96  # Show us the ccandidates
97  #
98  # Too many mask planes in diffims
99  for plane in ("BAD", "CR", "EDGE", "INTERPOlATED", "INTRP", "SAT", "SATURATED"):
100  ds9.setMaskPlaneVisibility(plane, False)
101 
102  mos = displayUtils.Mosaic()
103  for i in range(len(sources)):
104  source = sources[i]
105  badFlag = isFlagged[i]
106  dipoleFlag = isDipole[i]
107  bbox = source.getFootprint().getBBox()
108  stamp = exposure.Factory(exposure, bbox, True)
109  im = displayUtils.Mosaic(gutter=1, background=0, mode="x")
110  im.append(stamp.getMaskedImage())
111  lab = "%.1f,%.1f:" % (source.getX(), source.getY())
112  if badFlag:
113  ctype = ds9.RED
114  lab += "BAD"
115  if dipoleFlag:
116  ctype = ds9.YELLOW
117  lab += "DIPOLE"
118  if not badFlag and not dipoleFlag:
119  ctype = ds9.GREEN
120  lab += "OK"
121  mos.append(im.makeMosaic(), lab, ctype)
122  #print source.getId()
123  title = "Dia Sources"
124  mosaicImage = mos.makeMosaic(frame=frame, title=title)
125  return mosaicImage
126 
127 def showKernelCandidates(kernelCellSet, kernel, background, frame=None, showBadCandidates=True,
128  resids=False, kernels=False):
129  """Display the Kernel candidates.
130  If kernel is provided include spatial model and residuals;
131  If chi is True, generate a plot of residuals/sqrt(variance), i.e. chi
132  """
133 
134  #
135  # Show us the ccandidates
136  #
137  if kernels:
138  mos = displayUtils.Mosaic(gutter=5, background=0)
139  else:
140  mos = displayUtils.Mosaic(gutter=5, background=-1)
141  #
142  candidateCenters = []
143  candidateCentersBad = []
144  candidateIndex = 0
145  for cell in kernelCellSet.getCellList():
146  for cand in cell.begin(False): # include bad candidates
147  cand = diffimLib.cast_KernelCandidateF(cand)
148 
149  # Original difference image; if does not exist, skip candidate
150  try:
151  resid = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
152  except Exception:
153  continue
154 
155  rchi2 = cand.getChi2()
156  if rchi2 > 1e100:
157  rchi2 = np.nan
158 
159  if not showBadCandidates and cand.isBad():
160  continue
161 
162  im_resid = displayUtils.Mosaic(gutter=1, background=-0.5, mode="x")
163 
164  try:
165  im = cand.getScienceMaskedImage()
166  im = im.Factory(im, True)
167  im.setXY0(cand.getScienceMaskedImage().getXY0())
168  except Exception:
169  continue
170  if (not resids and not kernels):
171  im_resid.append(im.Factory(im, True))
172  try:
173  im = cand.getTemplateMaskedImage()
174  im = im.Factory(im, True)
175  im.setXY0(cand.getTemplateMaskedImage().getXY0())
176  except Exception:
177  continue
178  if (not resids and not kernels):
179  im_resid.append(im.Factory(im, True))
180 
181  # Difference image with original basis
182  if resids:
183  var = resid.getVariance()
184  var = var.Factory(var, True)
185  np.sqrt(var.getArray(), var.getArray()) # inplace sqrt
186  resid = resid.getImage()
187  resid /= var
188  bbox = kernel.shrinkBBox(resid.getBBox())
189  resid = resid.Factory(resid, bbox, True)
190  elif kernels:
191  kim = cand.getKernelImage(diffimLib.KernelCandidateF.ORIG).convertF()
192  resid = kim.Factory(kim, True)
193  im_resid.append(resid)
194 
195  # residuals using spatial model
196  ski = afwImage.ImageD(kernel.getDimensions())
197  kernel.computeImage(ski, False, int(cand.getXCenter()), int(cand.getYCenter()))
198  sk = afwMath.FixedKernel(ski)
199  sbg = 0.0
200  if background:
201  sbg = background(int(cand.getXCenter()), int(cand.getYCenter()))
202  sresid = cand.getDifferenceImage(sk, sbg)
203  resid = sresid
204  if resids:
205  resid = sresid.getImage()
206  resid /= var
207  bbox = kernel.shrinkBBox(resid.getBBox())
208  resid = resid.Factory(resid, bbox, True)
209  elif kernels:
210  kim = ski.convertF()
211  resid = kim.Factory(kim, True)
212  im_resid.append(resid)
213 
214  im = im_resid.makeMosaic()
215 
216  lab = "%d chi^2 %.1f" % (cand.getId(), rchi2)
217  ctype = ds9.RED if cand.isBad() else ds9.GREEN
218 
219  mos.append(im, lab, ctype)
220 
221  if False and np.isnan(rchi2):
222  ds9.mtv(cand.getScienceMaskedImage.getImage(), title="candidate", frame=1)
223  print "rating", cand.getCandidateRating()
224 
225  im = cand.getScienceMaskedImage()
226  center = (candidateIndex, cand.getXCenter() - im.getX0(), cand.getYCenter() - im.getY0())
227  candidateIndex += 1
228  if cand.isBad():
229  candidateCentersBad.append(center)
230  else:
231  candidateCenters.append(center)
232 
233  if resids:
234  title = "chi Diffim"
235  elif kernels:
236  title = "Kernels"
237  else:
238  title = "Candidates & residuals"
239  mosaicImage = mos.makeMosaic(frame=frame, title=title)
240 
241  return mosaicImage
242 
243 def showKernelBasis(kernel, frame=None):
244  """Display a Kernel's basis images
245  """
246  mos = displayUtils.Mosaic()
247 
248  for k in kernel.getKernelList():
249  im = afwImage.ImageD(k.getDimensions())
250  k.computeImage(im, False)
251  mos.append(im)
252  mos.makeMosaic(frame=frame, title="Kernel Basis Images")
253 
254  return mos
255 
256 ###############
257 
258 def plotKernelSpatialModel(kernel, kernelCellSet, showBadCandidates=True,
259  numSample=128, keepPlots=True, maxCoeff = 10):
260  """Plot the Kernel spatial model."""
261 
262  try:
263  import matplotlib.pyplot as plt
264  import matplotlib.colors
265  except ImportError, e:
266  print "Unable to import numpy and matplotlib: %s" % e
267  return
268 
269  x0 = kernelCellSet.getBBox().getBeginX()
270  y0 = kernelCellSet.getBBox().getBeginY()
271 
272  candPos = list()
273  candFits = list()
274  badPos = list()
275  badFits = list()
276  candAmps = list()
277  badAmps = list()
278  for cell in kernelCellSet.getCellList():
279  for cand in cell.begin(False):
280  cand = diffimLib.cast_KernelCandidateF(cand)
281  if not showBadCandidates and cand.isBad():
282  continue
283  candCenter = afwGeom.PointD(cand.getXCenter(), cand.getYCenter())
284  try:
285  im = cand.getTemplateMaskedImage()
286  except Exception, e:
287  continue
288 
289  targetFits = badFits if cand.isBad() else candFits
290  targetPos = badPos if cand.isBad() else candPos
291  targetAmps = badAmps if cand.isBad() else candAmps
292 
293  # compare original and spatial kernel coefficients
294  kp0 = np.array(cand.getKernel(diffimLib.KernelCandidateF.ORIG).getKernelParameters())
295  amp = cand.getCandidateRating()
296 
297  targetFits = badFits if cand.isBad() else candFits
298  targetPos = badPos if cand.isBad() else candPos
299  targetAmps = badAmps if cand.isBad() else candAmps
300 
301  targetFits.append(kp0)
302  targetPos.append(candCenter)
303  targetAmps.append(amp)
304 
305  xGood = np.array([pos.getX() for pos in candPos]) - x0
306  yGood = np.array([pos.getY() for pos in candPos]) - y0
307  zGood = np.array(candFits)
308 
309  xBad = np.array([pos.getX() for pos in badPos]) - x0
310  yBad = np.array([pos.getY() for pos in badPos]) - y0
311  zBad = np.array(badFits)
312  numBad = len(badPos)
313 
314  xRange = np.linspace(0, kernelCellSet.getBBox().getWidth(), num=numSample)
315  yRange = np.linspace(0, kernelCellSet.getBBox().getHeight(), num=numSample)
316 
317  if maxCoeff:
318  maxCoeff = min(maxCoeff, kernel.getNKernelParameters())
319  else:
320  maxCoeff = kernel.getNKernelParameters()
321 
322  for k in range(maxCoeff):
323  func = kernel.getSpatialFunction(k)
324  dfGood = zGood[:,k] - np.array([func(pos.getX(), pos.getY()) for pos in candPos])
325  yMin = dfGood.min()
326  yMax = dfGood.max()
327  if numBad > 0:
328  dfBad = zBad[:,k] - np.array([func(pos.getX(), pos.getY()) for pos in badPos])
329  # Can really screw up the range...
330  yMin = min([yMin, dfBad.min()])
331  yMax = max([yMax, dfBad.max()])
332  yMin -= 0.05 * (yMax - yMin)
333  yMax += 0.05 * (yMax - yMin)
334 
335  fRange = np.ndarray((len(xRange), len(yRange)))
336  for j, yVal in enumerate(yRange):
337  for i, xVal in enumerate(xRange):
338  fRange[j][i] = func(xVal, yVal)
339 
340  fig = plt.figure(k)
341 
342  fig.clf()
343  try:
344  fig.canvas._tkcanvas._root().lift() # == Tk's raise, but raise is a python reserved word
345  except Exception: # protect against API changes
346  pass
347 
348  fig.suptitle('Kernel component %d' % k)
349 
350  # LL
351  ax = fig.add_axes((0.1, 0.05, 0.35, 0.35))
352  vmin = fRange.min() # - 0.05 * np.fabs(fRange.min())
353  vmax = fRange.max() # + 0.05 * np.fabs(fRange.max())
354  norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
355  im = ax.imshow(fRange, aspect='auto', norm=norm,
356  extent=[0, kernelCellSet.getBBox().getWidth()-1,
357  0, kernelCellSet.getBBox().getHeight()-1])
358  ax.set_title('Spatial polynomial')
359  plt.colorbar(im, orientation='horizontal', ticks=[vmin, vmax])
360 
361  # UL
362  ax = fig.add_axes((0.1, 0.55, 0.35, 0.35))
363  ax.plot(-2.5*np.log10(candAmps), zGood[:,k], 'b+')
364  if numBad > 0:
365  ax.plot(-2.5*np.log10(badAmps), zBad[:,k], 'r+')
366  ax.set_title("Basis Coefficients")
367  ax.set_xlabel("Instr mag")
368  ax.set_ylabel("Coeff")
369 
370  # LR
371  ax = fig.add_axes((0.55, 0.05, 0.35, 0.35))
372  ax.set_autoscale_on(False)
373  ax.set_xbound(lower=0, upper=kernelCellSet.getBBox().getHeight())
374  ax.set_ybound(lower=yMin, upper=yMax)
375  ax.plot(yGood, dfGood, 'b+')
376  if numBad > 0:
377  ax.plot(yBad, dfBad, 'r+')
378  ax.axhline(0.0)
379  ax.set_title('dCoeff (indiv-spatial) vs. y')
380 
381  # UR
382  ax = fig.add_axes((0.55, 0.55, 0.35, 0.35))
383  ax.set_autoscale_on(False)
384  ax.set_xbound(lower=0, upper=kernelCellSet.getBBox().getWidth())
385  ax.set_ybound(lower=yMin, upper=yMax)
386  ax.plot(xGood, dfGood, 'b+')
387  if numBad > 0:
388  ax.plot(xBad, dfBad, 'r+')
389  ax.axhline(0.0)
390  ax.set_title('dCoeff (indiv-spatial) vs. x')
391 
392  fig.show()
393 
394  global keptPlots
395  if keepPlots and not keptPlots:
396  # Keep plots open when done
397  def show():
398  print "%s: Please close plots when done." % __name__
399  try:
400  plt.show()
401  except Exception:
402  pass
403  print "Plots closed, exiting..."
404  import atexit
405  atexit.register(show)
406  keptPlots = True
407 
408 
409 def showKernelMosaic(bbox, kernel, nx=7, ny=None, frame=None, title=None,
410  showCenter=True, showEllipticity=True):
411  """Show a mosaic of Kernel images.
412  """
413  mos = displayUtils.Mosaic()
414 
415  x0 = bbox.getBeginX()
416  y0 = bbox.getBeginY()
417  width = bbox.getWidth()
418  height = bbox.getHeight()
419 
420  if not ny:
421  ny = int(nx*float(height)/width + 0.5)
422  if not ny:
423  ny = 1
424 
425  schema = afwTable.SourceTable.makeMinimalSchema()
426  control = measAlg.GaussianCentroidControl()
427  centroider = measAlg.MeasureSourcesBuilder().addAlgorithm(control).build(schema)
428  sdssShape = measAlg.SdssShapeControl()
429  shaper = measAlg.MeasureSourcesBuilder().addAlgorithm(sdssShape).build(schema)
430  table = afwTable.SourceTable.make(schema)
431  table.defineCentroid(control.name)
432  table.defineShape(sdssShape.name)
433 
434  centers = []
435  shapes = []
436  for iy in range(ny):
437  for ix in range(nx):
438  x = int(ix*(width-1)/(nx-1)) + x0
439  y = int(iy*(height-1)/(ny-1)) + y0
440 
441  im = afwImage.ImageD(kernel.getDimensions())
442  ksum = kernel.computeImage(im, False, x, y)
443  lab = "Kernel(%d,%d)=%.2f" % (x, y, ksum) if False else ""
444  mos.append(im, lab)
445 
447  w, h = im.getWidth(), im.getHeight()
448  cen = afwGeom.PointD(w//2, h//2)
449  src = table.makeRecord()
450  foot = afwDet.Footprint(exp.getBBox())
451  src.setFootprint(foot)
452 
453  centroider.apply(src, exp, cen)
454  centers.append((src.getX(), src.getY()))
455 
456  shaper.apply(src, exp, cen)
457  shapes.append((src.getIxx(), src.getIxy(), src.getIyy()))
458 
459  mos.makeMosaic(frame=frame, title=title if title else "Model Kernel", mode=nx)
460 
461  if centers and frame is not None:
462  i = 0
463  with ds9.Buffering():
464  for cen, shape in zip(centers, shapes):
465  bbox = mos.getBBox(i); i += 1
466  xc, yc = cen[0] + bbox.getMinX(), cen[1] + bbox.getMinY()
467  if showCenter:
468  ds9.dot("+", xc, yc, ctype=ds9.BLUE, frame=frame)
469 
470  if showEllipticity:
471  ixx, ixy, iyy = shape
472  ds9.dot("@:%g,%g,%g" % (ixx, ixy, iyy), xc, yc, frame=frame, ctype=ds9.RED)
473 
474  return mos
475 
476 def plotPixelResiduals(exposure, warpedTemplateExposure, diffExposure, kernelCellSet,
477  kernel, background, testSources, config,
478  origVariance = False, nptsFull = 1e6, keepPlots = True, titleFs=14):
479  """Plot diffim residuals for LOCAL and SPATIAL models"""
480  candidateResids = []
481  spatialResids = []
482  nonfitResids = []
483 
484  for cell in kernelCellSet.getCellList():
485  for cand in cell.begin(True): # only look at good ones
486  # Be sure
487  if not (cand.getStatus() == afwMath.SpatialCellCandidate.GOOD):
488  continue
489 
490  cand = diffimLib.cast_KernelCandidateF(cand)
491  diffim = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
492  orig = cand.getScienceMaskedImage()
493 
494  ski = afwImage.ImageD(kernel.getDimensions())
495  kernel.computeImage(ski, False, int(cand.getXCenter()), int(cand.getYCenter()))
496  sk = afwMath.FixedKernel(ski)
497  sbg = background(int(cand.getXCenter()), int(cand.getYCenter()))
498  sdiffim = cand.getDifferenceImage(sk, sbg)
499 
500  # trim edgs due to convolution
501  bbox = kernel.shrinkBBox(diffim.getBBox())
502  tdiffim = diffim.Factory(diffim, bbox)
503  torig = orig.Factory(orig, bbox)
504  tsdiffim = sdiffim.Factory(sdiffim, bbox)
505 
506  if origVariance:
507  candidateResids.append(np.ravel(tdiffim.getImage().getArray() /
508  np.sqrt(torig.getVariance().getArray())))
509  spatialResids.append(np.ravel(tsdiffim.getImage().getArray() /
510  np.sqrt(torig.getVariance().getArray())))
511  else:
512  candidateResids.append(np.ravel(tdiffim.getImage().getArray() /
513  np.sqrt(tdiffim.getVariance().getArray())))
514  spatialResids.append(np.ravel(tsdiffim.getImage().getArray() /
515  np.sqrt(tsdiffim.getVariance().getArray())))
516 
517  fullIm = diffExposure.getMaskedImage().getImage().getArray()
518  fullMask = diffExposure.getMaskedImage().getMask().getArray()
519  if origVariance:
520  fullVar = exposure.getMaskedImage().getVariance().getArray()
521  else:
522  fullVar = diffExposure.getMaskedImage().getVariance().getArray()
523 
524  bitmaskBad = 0
525  bitmaskBad |= afwImage.MaskU.getPlaneBitMask('NO_DATA')
526  bitmaskBad |= afwImage.MaskU.getPlaneBitMask('SAT')
527  idx = np.where((fullMask & bitmaskBad) == 0)
528  stride = int(len(idx[0]) // nptsFull)
529  sidx = idx[0][::stride], idx[1][::stride]
530  allResids = fullIm[sidx] / np.sqrt(fullVar[sidx])
531 
532  testFootprints = diffimTools.sourceToFootprintList(testSources, warpedTemplateExposure,
533  exposure, config, pexLog.getDefaultLog())
534  for fp in testFootprints:
535  subexp = diffExposure.Factory(diffExposure, fp["footprint"].getBBox())
536  subim = subexp.getMaskedImage().getImage()
537  if origVariance:
538  subvar = afwImage.ExposureF(exposure, fp["footprint"].getBBox()).getMaskedImage().getVariance()
539  else:
540  subvar = subexp.getMaskedImage().getVariance()
541  nonfitResids.append(np.ravel(subim.getArray() / np.sqrt(subvar.getArray())))
542 
543  candidateResids = np.ravel(np.array(candidateResids))
544  spatialResids = np.ravel(np.array(spatialResids))
545  nonfitResids = np.ravel(np.array(nonfitResids))
546 
547  try:
548  import pylab
549  from matplotlib.font_manager import FontProperties
550  except ImportError, e:
551  print "Unable to import pylab: %s" % e
552  return
553 
554  fig = pylab.figure()
555  fig.clf()
556  try:
557  fig.canvas._tkcanvas._root().lift() # == Tk's raise, but raise is a python reserved word
558  except Exception: # protect against API changes
559  pass
560  if origVariance:
561  fig.suptitle("Diffim residuals: Normalized by sqrt(input variance)", fontsize=titleFs)
562  else:
563  fig.suptitle("Diffim residuals: Normalized by sqrt(diffim variance)", fontsize=titleFs)
564 
565  sp1 = pylab.subplot(221)
566  sp2 = pylab.subplot(222, sharex=sp1, sharey=sp1)
567  sp3 = pylab.subplot(223, sharex=sp1, sharey=sp1)
568  sp4 = pylab.subplot(224, sharex=sp1, sharey=sp1)
569  xs = np.arange(-5, 5.05, 0.1)
570  ys = 1. / np.sqrt(2 * np.pi) * np.exp( -0.5 * xs**2 )
571 
572  sp1.hist(candidateResids, bins=xs, normed=True, alpha=0.5, label="N(%.2f, %.2f)"
573  % (np.mean(candidateResids), np.var(candidateResids)))
574  sp1.plot(xs, ys, "r-", lw=2, label="N(0,1)")
575  sp1.set_title("Candidates: basis fit", fontsize=titleFs-2)
576  sp1.legend(loc=1, fancybox=True, shadow=True, prop = FontProperties(size=titleFs-6))
577 
578  sp2.hist(spatialResids, bins=xs, normed=True, alpha=0.5, label="N(%.2f, %.2f)"
579  % (np.mean(spatialResids), np.var(spatialResids)))
580  sp2.plot(xs, ys, "r-", lw=2, label="N(0,1)")
581  sp2.set_title("Candidates: spatial fit", fontsize=titleFs-2)
582  sp2.legend(loc=1, fancybox=True, shadow=True, prop = FontProperties(size=titleFs-6))
583 
584  sp3.hist(nonfitResids, bins=xs, normed=True, alpha=0.5, label="N(%.2f, %.2f)"
585  % (np.mean(nonfitResids), np.var(nonfitResids)))
586  sp3.plot(xs, ys, "r-", lw=2, label="N(0,1)")
587  sp3.set_title("Control sample: spatial fit", fontsize=titleFs-2)
588  sp3.legend(loc=1, fancybox=True, shadow=True, prop = FontProperties(size=titleFs-6))
589 
590  sp4.hist(allResids, bins=xs, normed=True, alpha=0.5, label="N(%.2f, %.2f)"
591  % (np.mean(allResids), np.var(allResids)))
592  sp4.plot(xs, ys, "r-", lw=2, label="N(0,1)")
593  sp4.set_title("Full image (subsampled)", fontsize=titleFs-2)
594  sp4.legend(loc=1, fancybox=True, shadow=True, prop = FontProperties(size=titleFs-6))
595 
596  pylab.setp(sp1.get_xticklabels()+sp1.get_yticklabels(), fontsize=titleFs-4)
597  pylab.setp(sp2.get_xticklabels()+sp2.get_yticklabels(), fontsize=titleFs-4)
598  pylab.setp(sp3.get_xticklabels()+sp3.get_yticklabels(), fontsize=titleFs-4)
599  pylab.setp(sp4.get_xticklabels()+sp4.get_yticklabels(), fontsize=titleFs-4)
600 
601  sp1.set_xlim(-5, 5)
602  sp1.set_ylim(0, 0.5)
603  fig.show()
604 
605  global keptPlots
606  if keepPlots and not keptPlots:
607  # Keep plots open when done
608  def show():
609  print "%s: Please close plots when done." % __name__
610  try:
611  pylab.show()
612  except Exception:
613  pass
614  print "Plots closed, exiting..."
615  import atexit
616  atexit.register(show)
617  keptPlots = True
618 
619 def calcCentroid(arr):
620  """Calculate first moment of a (kernel) image"""
621  y, x = arr.shape
622  sarr = arr*arr
623  xarr = np.asarray([[el for el in range(x)] for el2 in range(y)])
624  yarr = np.asarray([[el2 for el in range(x)] for el2 in range(y)])
625  narr = xarr*sarr
626  sarrSum = sarr.sum()
627  centx = narr.sum()/sarrSum
628  narr = yarr*sarr
629  centy = narr.sum()/sarrSum
630  return centx, centy
631 
632 def calcWidth(arr, centx, centy):
633  """Calculate second moment of a (kernel) image"""
634  y, x = arr.shape
635  #Square the flux so we don't have to deal with negatives
636  sarr = arr*arr
637  xarr = np.asarray([[el for el in range(x)] for el2 in range(y)])
638  yarr = np.asarray([[el2 for el in range(x)] for el2 in range(y)])
639  narr = sarr*np.power((xarr - centx), 2.)
640  sarrSum = sarr.sum()
641  xstd = np.sqrt(narr.sum()/sarrSum)
642  narr = sarr*np.power((yarr - centy), 2.)
643  ystd = np.sqrt(narr.sum()/sarrSum)
644  return xstd, ystd
645 
646 def printSkyDiffs(sources, wcs):
647  """Print differences in sky coordinates between source Position and its Centroid mapped through Wcs"""
648  for s in sources:
649  sCentroid = s.getCentroid()
650  sPosition = s.getCoord().getPosition()
651  dra = 3600*(sPosition.getX() - wcs.pixelToSky(sCentroid.getX(),
652  sCentroid.getY()).getPosition().getX())/0.2
653  ddec = 3600*(sPosition.getY() - wcs.pixelToSky(sCentroid.getX(),
654  sCentroid.getY()).getPosition().getY())/0.2
655  if np.isfinite(dra) and np.isfinite(ddec):
656  print dra, ddec
657 
658 def makeRegions(sources, outfilename, wcs=None):
659  """Create regions file for ds9 from input source list"""
660  fh = open(outfilename, "w")
661  fh.write("global color=red font=\"helvetica 10 normal\" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source\nfk5\n")
662  for s in sources:
663  if wcs:
664  (ra, dec) = wcs.pixelToSky(s.getCentroid().getX(), s.getCentroid().getY()).getPosition()
665  else:
666  (ra, dec) = s.getCoord().getPosition()
667  if np.isfinite(ra) and np.isfinite(dec):
668  fh.write("circle(%f,%f,2\")\n"%(ra,dec))
669  fh.flush()
670  fh.close()
671 
672 def showSourceSetSky(sSet, wcs, xy0, frame=0, ctype=ds9.GREEN, symb="+", size=2):
673  """Draw the (RA, Dec) positions of a set of Sources. Image has the XY0."""
674  with ds9.Buffering():
675  for s in sSet:
676  (xc, yc) = wcs.skyToPixel(s.getCoord().getRa(), s.getCoord().getDec())
677  xc -= xy0[0]
678  yc -= xy0[1]
679  ds9.dot(symb, xc, yc, frame=frame, ctype=ctype, size=size)
680 
681 def plotWhisker(results, newWcs):
682  """Plot whisker diagram of astromeric offsets between results.matches"""
683  refCoordKey = results.matches[0].first.getTable().getCoordKey()
684  inCentroidKey = results.matches[0].second.getTable().getCentroidKey()
685  positions = [m.first.get(refCoordKey) for m in results.matches]
686  residuals = [m.first.get(refCoordKey).getOffsetFrom(
687  newWcs.pixelToSky(m.second.get(inCentroidKey))) for
688  m in results.matches]
689  import matplotlib.pyplot as plt
690  fig = plt.figure()
691  sp = fig.add_subplot(1, 1, 0)
692  xpos = [x[0].asDegrees() for x in positions]
693  ypos = [x[1].asDegrees() for x in positions]
694  xpos.append(0.02*(max(xpos) - min(xpos)) + min(xpos))
695  ypos.append(0.98*(max(ypos) - min(ypos)) + min(ypos))
696  xidxs = np.isfinite(xpos)
697  yidxs = np.isfinite(ypos)
698  X = np.asarray(xpos)[xidxs]
699  Y = np.asarray(ypos)[yidxs]
700  distance = [x[1].asArcseconds() for x in residuals]
701  distance.append(0.2)
702  distance = np.asarray(distance)[xidxs]
703  #NOTE: This assumes that the bearing is measured positive from +RA through North.
704  #From the documentation this is not clear.
705  bearing = [x[0].asRadians() for x in residuals]
706  bearing.append(0)
707  bearing = np.asarray(bearing)[xidxs]
708  U = (distance*np.cos(bearing))
709  V = (distance*np.sin(bearing))
710  sp.quiver(X, Y, U, V)
711  sp.set_title("WCS Residual")
712  plt.show()
713 
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
def showKernelSpatialCells
Definition: utils.py:57
def plotKernelSpatialModel
Definition: utils.py:259
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
A kernel created from an Image.
Definition: Kernel.h:551