441 matchKernelAmplitudes=
False, keepPlots=
True):
442 """Plot the PSF spatial model."""
445 print >> sys.stderr,
"Unable to import matplotlib"
448 noSpatialKernel = afwMath.cast_LinearCombinationKernel(psf.getKernel())
455 for cell
in psfCellSet.getCellList():
456 for cand
in cell.begin(
False):
457 cand = algorithmsLib.cast_PsfCandidateF(cand)
458 if not showBadCandidates
and cand.isBad():
462 im = cand.getMaskedImage()
466 fit = algorithmsLib.fitKernelParamsToImage(noSpatialKernel, im, candCenter)
470 for p, k
in zip(params, kernels):
471 amp += p * afwMath.cast_FixedKernel(k).getSum()
473 targetFits = badFits
if cand.isBad()
else candFits
474 targetPos = badPos
if cand.isBad()
else candPos
475 targetAmps = badAmps
if cand.isBad()
else candAmps
477 targetFits.append([x / amp
for x
in params])
478 targetPos.append(candCenter)
479 targetAmps.append(amp)
481 numCandidates = len(candFits)
482 numBasisFuncs = noSpatialKernel.getNBasisKernels()
484 xGood = numpy.array([pos.getX()
for pos
in candPos]) - exposure.getX0()
485 yGood = numpy.array([pos.getY()
for pos
in candPos]) - exposure.getY0()
486 zGood = numpy.array(candFits)
487 ampGood = numpy.array(candAmps)
489 xBad = numpy.array([pos.getX()
for pos
in badPos]) - exposure.getX0()
490 yBad = numpy.array([pos.getY()
for pos
in badPos]) - exposure.getY0()
491 zBad = numpy.array(badFits)
492 ampBad = numpy.array(badAmps)
495 xRange = numpy.linspace(0, exposure.getWidth(), num=numSample)
496 yRange = numpy.linspace(0, exposure.getHeight(), num=numSample)
498 kernel = psf.getKernel()
499 nKernelComponents = kernel.getNKernelParameters()
503 nPanelX = int(math.sqrt(nKernelComponents))
504 nPanelY = nKernelComponents//nPanelX
505 while nPanelY*nPanelX < nKernelComponents:
511 fig.canvas._tkcanvas._root().lift()
517 subplots =
makeSubplots(fig, 2, 2, Nx=nPanelX, Ny=nPanelY, xgutter=0.06, ygutter=0.06, pygutter=0.04)
519 for k
in range(nKernelComponents):
520 func = kernel.getSpatialFunction(k)
521 dfGood = zGood[:,k] - numpy.array([func(pos.getX(), pos.getY())
for pos
in candPos])
525 dfBad = zBad[:,k] - numpy.array([func(pos.getX(), pos.getY())
for pos
in badPos])
526 yMin = min([yMin, dfBad.min()])
527 yMax = max([yMax, dfBad.max()])
528 yMin -= 0.05 * (yMax - yMin)
529 yMax += 0.05 * (yMax - yMin)
534 fRange = numpy.ndarray((len(xRange), len(yRange)))
535 for j, yVal
in enumerate(yRange):
536 for i, xVal
in enumerate(xRange):
537 fRange[j][i] = func(xVal, yVal)
543 ax.set_autoscale_on(
False)
544 ax.set_xbound(lower=0, upper=exposure.getHeight())
545 ax.set_ybound(lower=yMin, upper=yMax)
546 ax.plot(yGood, dfGood,
'b+')
548 ax.plot(yBad, dfBad,
'r+')
550 ax.set_title(
'Residuals(y)')
556 if matchKernelAmplitudes
and k == 0:
563 norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
564 im = ax.imshow(fRange, aspect=
'auto', origin=
"lower", norm=norm,
565 extent=[0, exposure.getWidth()-1, 0, exposure.getHeight()-1])
566 ax.set_title(
'Spatial poly')
567 plt.colorbar(im, orientation=
'horizontal', ticks=[vmin, vmax])
572 ax.set_autoscale_on(
False)
573 ax.set_xbound(lower=0, upper=exposure.getWidth())
574 ax.set_ybound(lower=yMin, upper=yMax)
575 ax.plot(xGood, dfGood,
'b+')
577 ax.plot(xBad, dfBad,
'r+')
579 ax.set_title(
'K%d Residuals(x)' % k)
586 ax.scatter(xGood, yGood, c=dfGood, marker=
'o')
587 ax.scatter(xBad, yBad, c=dfBad, marker=
'x')
588 ax.set_xbound(lower=0, upper=exposure.getWidth())
589 ax.set_ybound(lower=0, upper=exposure.getHeight())
590 ax.set_title(
'Spatial residuals')
591 plt.colorbar(im, orientation=
'horizontal')
593 calib = exposure.getCalib()
594 if calib.getFluxMag0()[0] <= 0:
595 calib = type(calib)()
596 calib.setFluxMag0(1.0)
599 ax.plot(calib.getMagnitude(candAmps), zGood[:,k],
'b+')
601 ax.plot(calib.getMagnitude(badAmps), zBad[:,k],
'r+')
603 ax.set_title(
'Flux variation')
608 if keepPlots
and not keptPlots:
611 print "%s: Please close plots when done." % __name__
616 print "Plots closed, exiting..."
618 atexit.register(show)