def testObjective(self): eps = 1E-6 psfModel = ms.FitPsfModel(ms.FitPsfControl(), 1.0, numpy.array([0.1, -0.05, 1.0])) obj = ms.FitProfileAlgorithm.makeObjective(self.ctrl, psfModel, self.inputs) resolved = geom.ellipses.Quadrupole(15.0, 12.0, 0.23) circle = geom.ellipses.Quadrupole(1.0, 1.0, 0.0) deltafn = geom.ellipses.Quadrupole(0.0, 0.0, 0.0) for q in (resolved, circle, deltafn): e = ms.MultiGaussianObjective.EllipseCore(q) ms.MultiGaussianObjective.constrainEllipse(e, self.ctrl.minRadius, self.ctrl.minAxisRatio) parameters = numpy.zeros(3, dtype=float) ms.MultiGaussianObjective.writeParameters(e, parameters) f0 = numpy.zeros(self.inputs.getSize(), dtype=float) obj.computeFunction(parameters, f0) d0 = numpy.zeros((parameters.size, self.inputs.getSize()), dtype=float).transpose() d1 = numpy.zeros((parameters.size, self.inputs.getSize()), dtype=float).transpose() obj.computeDerivative(parameters, f0, d0) for i in range(parameters.size): parameters[i] += eps f1a = numpy.zeros(self.inputs.getSize(), dtype=float) obj.computeFunction(parameters, f1a) parameters[i] -= 2.0 * eps f1b = numpy.zeros(self.inputs.getSize(), dtype=float) obj.computeFunction(parameters, f1b) parameters[i] -= eps d1[:, i] = (f1a - f1b) / (2.0 * eps) self.assertClose(d0, d1, atol=1E-4, rtol=1E-10) print d0
def testConvolvedModel(self): psfModel = ms.FitPsfModel(ms.FitPsfControl(), 1.0, numpy.array([0.1, -0.05, 1.0])) psfMultiGaussian = psfModel.getMultiGaussian() multiGaussian = ms.MultiGaussianRegistry.lookup(self.ctrl.profile) parameters = numpy.array([[0.0, 0.0, 0.0], [0.0, 0.0, -16], [0.2, -0.8, 2.3]]) sImage = lsst.afw.image.ImageD(self.bbox) builders = [] for p in psfMultiGaussian: psfEllipse = psfModel.ellipse.clone() psfEllipse.scale(p.radius) builders.extend( ms.GaussianModelBuilder(self.x, self.y, c.flux, c.radius, psfEllipse, p.flux) for c in multiGaussian) psfShapelets = psfModel.asMultiShapelet() for row in parameters: model = ms.FitProfileModel(self.ctrl, 1.0, row) msf = model.asMultiShapelet(self.center).convolve(psfShapelets) z0 = sImage.getArray() z0[:, :] = 0.0 msf.evaluate().addToImage(sImage) z1 = numpy.zeros(z0.shape, dtype=float) for b in builders: b.update(ms.MultiGaussianObjective.readParameters(row)) z1 += b.getModel().reshape(*z1.shape) self.assertClose(z0, z1) self.assert_(numpy.isfinite(z0).all()) self.assert_(numpy.isfinite(z1).all())
def testObjective(self): eps = 1E-6 ctrl = ms.FitPsfControl() image = lsst.afw.image.ImageD(5, 5) nParameters = 3 nData = image.getBBox().getArea() nTests = 10 center = geom.Point2D(2.0, 2.0) xGrid, yGrid = numpy.meshgrid(numpy.arange(-2, 3), numpy.arange(-2, 3)) image.getArray()[:, :] = 1.0 * numpy.exp(-0.5 * (xGrid**2 + yGrid**2)) image.getArray()[:, :] += numpy.random.randn(5, 5) * 0.1 inputs = ms.ModelInputHandler(image, center, image.getBBox(lsst.afw.image.PARENT)) obj = ms.FitPsfAlgorithm.makeObjective(ctrl, inputs) parameters = numpy.random.rand(nTests, nParameters) * 0.5 for i in range(nTests): f0 = numpy.zeros(nData, dtype=float) obj.computeFunction(parameters[i, :], f0) f1 = obj.getModel() * obj.getAmplitude() - inputs.getData() model = ms.FitPsfModel(ctrl, obj.getAmplitude(), parameters[i, :]) self.assertClose( model.outer[0], ctrl.peakRatio * model.inner[0] * ctrl.radiusRatio**2) self.assertEqual(model.radiusRatio, ctrl.radiusRatio) image2 = lsst.afw.image.ImageD(5, 5) multiShapeletFunc = model.asMultiShapelet(center) multiShapeletFunc.evaluate().addToImage(image2) f2 = (image2.getArray().ravel() - inputs.getData()) multiGaussian = model.getMultiGaussian() builder1 = ms.GaussianModelBuilder(inputs.getX(), inputs.getY(), multiGaussian[0].flux, multiGaussian[0].radius) builder2 = ms.GaussianModelBuilder(inputs.getX(), inputs.getY(), multiGaussian[1].flux, multiGaussian[1].radius) builder1.update(model.ellipse) builder2.update(model.ellipse) f3 = builder1.getModel() + builder2.getModel() - inputs.getData() self.assertClose(f0, f1) self.assertClose(f0, f2) self.assertClose(f0, f3) d0 = numpy.zeros((nParameters, nData), dtype=float).transpose() d1 = numpy.zeros((nParameters, nData), dtype=float).transpose() obj.computeDerivative(parameters[i, :], f0, d0) for j in range(nParameters): parameters[i, j] += eps f1a = numpy.zeros(nData, dtype=float) obj.computeFunction(parameters[i, :], f1a) parameters[i, j] -= 2.0 * eps f1b = numpy.zeros(nData, dtype=float) obj.computeFunction(parameters[i, :], f1b) d1[:, j] = (f1a - f1b) / (2.0 * eps) parameters[i, j] += eps self.assertClose(d0, d1, rtol=1E-10, atol=1E-8)
def __init__(self, source, exposure, name="exp", psfCtrl=None, ctrl=None): if ctrl is None: if name == "exp": config = ms.FitExponentialConfig() else: config = ms.FitDeVaucouleurConfig() ctrl = config.makeControl() if psfCtrl is None: psfCtrl = ms.FitPsfControl() self.ctrl = ctrl self.ctrl.name = "multishapelet." + name self.psfModel = ms.FitPsfModel(psfCtrl, source) self.saved = self.Model(self.ctrl, source) self.center = source.getCentroid() self.shape = source.getShape() self.inputs = self.Algorithm.adjustInputs(self.ctrl, self.psfModel, self.shape, source.getFootprint(), exposure, self.center) self.footprint = self.inputs.getFootprint() self.bbox = self.footprint.getBBox() self.image = lsst.afw.image.ImageD(self.bbox) self.image.getArray()[:, :] = exposure.getMaskedImage().getImage( ).getArray()[self.bbox.getSlices()] initialEllipse = ms.MultiGaussianObjective.EllipseCore(self.shape) opt = self.Algorithm.makeOptimizer(self.ctrl, self.psfModel, initialEllipse, self.inputs) maxIter = opt.getControl().maxIter self.iterations = [self.Iteration(opt, self)] for self.iterCount in range(maxIter): opt.step() self.iterations.append(self.Iteration(opt, self)) if opt.getState() & ms.HybridOptimizer.FINISHED: break self.model = self.Model(self.iterations[-1].model) self.Algorithm.fitShapeletTerms(self.ctrl, self.psfModel, self.inputs, self.model)