393 matchKernelAmplitudes=
False, keepPlots=
True):
394 """Plot the PSF spatial model."""
397 print >> sys.stderr,
"Unable to import matplotlib"
400 noSpatialKernel = afwMath.cast_LinearCombinationKernel(psf.getKernel())
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():
414 im = cand.getMaskedImage()
418 fit = algorithmsLib.fitKernelParamsToImage(noSpatialKernel, im, candCenter)
422 for p, k
in zip(params, kernels):
423 amp += p * afwMath.cast_FixedKernel(k).getSum()
425 targetFits = badFits
if cand.isBad()
else candFits
426 targetPos = badPos
if cand.isBad()
else candPos
427 targetAmps = badAmps
if cand.isBad()
else candAmps
429 targetFits.append([x / amp
for x
in params])
430 targetPos.append(candCenter)
431 targetAmps.append(amp)
433 numCandidates = len(candFits)
434 numBasisFuncs = noSpatialKernel.getNBasisKernels()
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)
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)
447 xRange = numpy.linspace(0, exposure.getWidth(), num=numSample)
448 yRange = numpy.linspace(0, exposure.getHeight(), num=numSample)
450 kernel = psf.getKernel()
451 nKernelComponents = kernel.getNKernelParameters()
455 nPanelX = int(math.sqrt(nKernelComponents))
456 nPanelY = nKernelComponents//nPanelX
457 while nPanelY*nPanelX < nKernelComponents:
463 fig.canvas._tkcanvas._root().lift()
469 subplots =
makeSubplots(fig, 2, 2, Nx=nPanelX, Ny=nPanelY, xgutter=0.06, ygutter=0.06, pygutter=0.04)
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])
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)
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)
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+')
500 ax.plot(yBad, dfBad,
'r+')
502 ax.set_title(
'Residuals(y)')
508 if matchKernelAmplitudes
and k == 0:
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])
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+')
529 ax.plot(xBad, dfBad,
'r+')
531 ax.set_title(
'K%d Residuals(x)' % k)
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')
545 calib = exposure.getCalib()
546 if calib.getFluxMag0()[0] <= 0:
547 calib = type(calib)()
548 calib.setFluxMag0(1.0)
551 ax.plot(calib.getMagnitude(candAmps), zGood[:,k],
'b+')
553 ax.plot(calib.getMagnitude(badAmps), zBad[:,k],
'r+')
555 ax.set_title(
'Flux variation')
560 if keepPlots
and not keptPlots:
563 print "%s: Please close plots when done." % __name__
568 print "Plots closed, exiting..."
570 atexit.register(show)