23 """Support utilities for Measuring sources"""
34 from .
import diffimLib
35 from .
import diffimTools
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"""
44 xc, yc = s.getXAstrom() - xy0[0], s.getYAstrom() - xy0[1]
47 ds9.dot(str(s.getId()), xc, yc, frame=frame, ctype=ctype, size=size)
49 ds9.dot(symb, xc, yc, frame=frame, ctype=ctype, size=size)
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"""
62 ds9.mtv(maskedIm, frame=frame, title=title)
64 origin = [-maskedIm.getX0(), -maskedIm.getY0()]
65 for cell
in kernelCellSet.getCellList():
66 displayUtils.drawBBox(cell.getBBox(), origin=origin, frame=frame)
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:
74 elif cand.getStatus() == afwMath.SpatialCellCandidate.GOOD:
76 elif cand.getStatus() == afwMath.SpatialCellCandidate.UNKNOWN:
82 ds9.dot(symb, xc, yc, frame=frame, ctype=color, size=size)
85 rchi2 = cand.getChi2()
88 ds9.dot(
"%d %.1f" % (cand.getId(), rchi2),
89 xc - size, yc - size - 4, frame=frame, ctype=color, size=size)
93 """Display Dia Sources
99 for plane
in (
"BAD",
"CR",
"EDGE",
"INTERPOlATED",
"INTRP",
"SAT",
"SATURATED"):
100 ds9.setMaskPlaneVisibility(plane,
False)
102 mos = displayUtils.Mosaic()
103 for i
in range(len(sources)):
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())
118 if not badFlag
and not dipoleFlag:
121 mos.append(im.makeMosaic(), lab, ctype)
123 title =
"Dia Sources"
124 mosaicImage = mos.makeMosaic(frame=frame, title=title)
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
138 mos = displayUtils.Mosaic(gutter=5, background=0)
140 mos = displayUtils.Mosaic(gutter=5, background=-1)
142 candidateCenters = []
143 candidateCentersBad = []
145 for cell
in kernelCellSet.getCellList():
146 for cand
in cell.begin(
False):
147 cand = diffimLib.cast_KernelCandidateF(cand)
151 resid = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
155 rchi2 = cand.getChi2()
159 if not showBadCandidates
and cand.isBad():
162 im_resid = displayUtils.Mosaic(gutter=1, background=-0.5, mode=
"x")
165 im = cand.getScienceMaskedImage()
166 im = im.Factory(im,
True)
167 im.setXY0(cand.getScienceMaskedImage().getXY0())
170 if (
not resids
and not kernels):
171 im_resid.append(im.Factory(im,
True))
173 im = cand.getTemplateMaskedImage()
174 im = im.Factory(im,
True)
175 im.setXY0(cand.getTemplateMaskedImage().getXY0())
178 if (
not resids
and not kernels):
179 im_resid.append(im.Factory(im,
True))
183 var = resid.getVariance()
184 var = var.Factory(var,
True)
185 np.sqrt(var.getArray(), var.getArray())
186 resid = resid.getImage()
188 bbox = kernel.shrinkBBox(resid.getBBox())
189 resid = resid.Factory(resid, bbox,
True)
191 kim = cand.getKernelImage(diffimLib.KernelCandidateF.ORIG).convertF()
192 resid = kim.Factory(kim,
True)
193 im_resid.append(resid)
196 ski = afwImage.ImageD(kernel.getDimensions())
197 kernel.computeImage(ski,
False, int(cand.getXCenter()), int(cand.getYCenter()))
201 sbg =
background(int(cand.getXCenter()), int(cand.getYCenter()))
202 sresid = cand.getDifferenceImage(sk, sbg)
205 resid = sresid.getImage()
207 bbox = kernel.shrinkBBox(resid.getBBox())
208 resid = resid.Factory(resid, bbox,
True)
211 resid = kim.Factory(kim,
True)
212 im_resid.append(resid)
214 im = im_resid.makeMosaic()
216 lab =
"%d chi^2 %.1f" % (cand.getId(), rchi2)
217 ctype = ds9.RED
if cand.isBad()
else ds9.GREEN
219 mos.append(im, lab, ctype)
221 if False and np.isnan(rchi2):
222 ds9.mtv(cand.getScienceMaskedImage.getImage(), title=
"candidate", frame=1)
223 print "rating", cand.getCandidateRating()
225 im = cand.getScienceMaskedImage()
226 center = (candidateIndex, cand.getXCenter() - im.getX0(), cand.getYCenter() - im.getY0())
229 candidateCentersBad.append(center)
231 candidateCenters.append(center)
238 title =
"Candidates & residuals"
239 mosaicImage = mos.makeMosaic(frame=frame, title=title)
244 """Display a Kernel's basis images
246 mos = displayUtils.Mosaic()
248 for k
in kernel.getKernelList():
249 im = afwImage.ImageD(k.getDimensions())
250 k.computeImage(im,
False)
252 mos.makeMosaic(frame=frame, title=
"Kernel Basis Images")
259 numSample=128, keepPlots=
True, maxCoeff = 10):
260 """Plot the Kernel spatial model."""
263 import matplotlib.pyplot
as plt
264 import matplotlib.colors
265 except ImportError, e:
266 print "Unable to import numpy and matplotlib: %s" % e
269 x0 = kernelCellSet.getBBox().getBeginX()
270 y0 = kernelCellSet.getBBox().getBeginY()
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():
285 im = cand.getTemplateMaskedImage()
289 targetFits = badFits
if cand.isBad()
else candFits
290 targetPos = badPos
if cand.isBad()
else candPos
291 targetAmps = badAmps
if cand.isBad()
else candAmps
294 kp0 = np.array(cand.getKernel(diffimLib.KernelCandidateF.ORIG).getKernelParameters())
295 amp = cand.getCandidateRating()
297 targetFits = badFits
if cand.isBad()
else candFits
298 targetPos = badPos
if cand.isBad()
else candPos
299 targetAmps = badAmps
if cand.isBad()
else candAmps
301 targetFits.append(kp0)
302 targetPos.append(candCenter)
303 targetAmps.append(amp)
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)
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)
314 xRange = np.linspace(0, kernelCellSet.getBBox().getWidth(), num=numSample)
315 yRange = np.linspace(0, kernelCellSet.getBBox().getHeight(), num=numSample)
318 maxCoeff = min(maxCoeff, kernel.getNKernelParameters())
320 maxCoeff = kernel.getNKernelParameters()
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])
328 dfBad = zBad[:,k] - np.array([func(pos.getX(), pos.getY())
for pos
in badPos])
330 yMin = min([yMin, dfBad.min()])
331 yMax = max([yMax, dfBad.max()])
332 yMin -= 0.05 * (yMax - yMin)
333 yMax += 0.05 * (yMax - yMin)
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)
344 fig.canvas._tkcanvas._root().lift()
348 fig.suptitle(
'Kernel component %d' % k)
351 ax = fig.add_axes((0.1, 0.05, 0.35, 0.35))
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])
362 ax = fig.add_axes((0.1, 0.55, 0.35, 0.35))
363 ax.plot(-2.5*np.log10(candAmps), zGood[:,k],
'b+')
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")
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+')
377 ax.plot(yBad, dfBad,
'r+')
379 ax.set_title(
'dCoeff (indiv-spatial) vs. y')
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+')
388 ax.plot(xBad, dfBad,
'r+')
390 ax.set_title(
'dCoeff (indiv-spatial) vs. x')
395 if keepPlots
and not keptPlots:
398 print "%s: Please close plots when done." % __name__
403 print "Plots closed, exiting..."
405 atexit.register(show)
410 showCenter=
True, showEllipticity=
True):
411 """Show a mosaic of Kernel images.
413 mos = displayUtils.Mosaic()
415 x0 = bbox.getBeginX()
416 y0 = bbox.getBeginY()
417 width = bbox.getWidth()
418 height = bbox.getHeight()
421 ny = int(nx*float(height)/width + 0.5)
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)
438 x = int(ix*(width-1)/(nx-1)) + x0
439 y = int(iy*(height-1)/(ny-1)) + y0
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 ""
447 w, h = im.getWidth(), im.getHeight()
449 src = table.makeRecord()
451 src.setFootprint(foot)
453 centroider.apply(src, exp, cen)
454 centers.append((src.getX(), src.getY()))
456 shaper.apply(src, exp, cen)
457 shapes.append((src.getIxx(), src.getIxy(), src.getIyy()))
459 mos.makeMosaic(frame=frame, title=title
if title
else "Model Kernel", mode=nx)
461 if centers
and frame
is not None:
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()
468 ds9.dot(
"+", xc, yc, ctype=ds9.BLUE, frame=frame)
471 ixx, ixy, iyy = shape
472 ds9.dot(
"@:%g,%g,%g" % (ixx, ixy, iyy), xc, yc, frame=frame, ctype=ds9.RED)
477 kernel, background, testSources, config,
478 origVariance =
False, nptsFull = 1e6, keepPlots =
True, titleFs=14):
479 """Plot diffim residuals for LOCAL and SPATIAL models"""
484 for cell
in kernelCellSet.getCellList():
485 for cand
in cell.begin(
True):
487 if not (cand.getStatus() == afwMath.SpatialCellCandidate.GOOD):
490 cand = diffimLib.cast_KernelCandidateF(cand)
491 diffim = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
492 orig = cand.getScienceMaskedImage()
494 ski = afwImage.ImageD(kernel.getDimensions())
495 kernel.computeImage(ski,
False, int(cand.getXCenter()), int(cand.getYCenter()))
497 sbg =
background(int(cand.getXCenter()), int(cand.getYCenter()))
498 sdiffim = cand.getDifferenceImage(sk, sbg)
501 bbox = kernel.shrinkBBox(diffim.getBBox())
502 tdiffim = diffim.Factory(diffim, bbox)
503 torig = orig.Factory(orig, bbox)
504 tsdiffim = sdiffim.Factory(sdiffim, bbox)
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())))
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())))
517 fullIm = diffExposure.getMaskedImage().getImage().getArray()
518 fullMask = diffExposure.getMaskedImage().getMask().getArray()
520 fullVar = exposure.getMaskedImage().getVariance().getArray()
522 fullVar = diffExposure.getMaskedImage().getVariance().getArray()
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])
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()
538 subvar = afwImage.ExposureF(exposure, fp[
"footprint"].getBBox()).getMaskedImage().getVariance()
540 subvar = subexp.getMaskedImage().getVariance()
541 nonfitResids.append(np.ravel(subim.getArray() / np.sqrt(subvar.getArray())))
543 candidateResids = np.ravel(np.array(candidateResids))
544 spatialResids = np.ravel(np.array(spatialResids))
545 nonfitResids = np.ravel(np.array(nonfitResids))
549 from matplotlib.font_manager
import FontProperties
550 except ImportError, e:
551 print "Unable to import pylab: %s" % e
557 fig.canvas._tkcanvas._root().lift()
561 fig.suptitle(
"Diffim residuals: Normalized by sqrt(input variance)", fontsize=titleFs)
563 fig.suptitle(
"Diffim residuals: Normalized by sqrt(diffim variance)", fontsize=titleFs)
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 )
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))
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))
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))
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))
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)
606 if keepPlots
and not keptPlots:
609 print "%s: Please close plots when done." % __name__
614 print "Plots closed, exiting..."
616 atexit.register(show)
620 """Calculate first moment of a (kernel) image"""
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)])
627 centx = narr.sum()/sarrSum
629 centy = narr.sum()/sarrSum
633 """Calculate second moment of a (kernel) image"""
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.)
641 xstd = np.sqrt(narr.sum()/sarrSum)
642 narr = sarr*np.power((yarr - centy), 2.)
643 ystd = np.sqrt(narr.sum()/sarrSum)
647 """Print differences in sky coordinates between source Position and its Centroid mapped through Wcs"""
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):
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")
664 (ra, dec) = wcs.pixelToSky(s.getCentroid().getX(), s.getCentroid().getY()).getPosition()
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))
673 """Draw the (RA, Dec) positions of a set of Sources. Image has the XY0."""
674 with ds9.Buffering():
676 (xc, yc) = wcs.skyToPixel(s.getCoord().getRa(), s.getCoord().getDec())
679 ds9.dot(symb, xc, yc, frame=frame, ctype=ctype, size=size)
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
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]
702 distance = np.asarray(distance)[xidxs]
705 bearing = [x[0].asRadians()
for x
in residuals]
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")
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())
def showKernelSpatialCells
def plotKernelSpatialModel
Exposure< ImagePixelT, MaskPixelT, VariancePixelT >::Ptr makeExposure(MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > &mimage, boost::shared_ptr< Wcs const > wcs=boost::shared_ptr< Wcs const >())
A kernel created from an Image.