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 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 testModel1(self): builder = ms.GaussianModelBuilder(self.x, self.y) builder.update(self.ellipse) mgc = ms.GaussianComponent() shapelet = mgc.makeShapelet(ellipses.Ellipse(self.ellipse)) z0 = builder.getModel() z1 = self.buildModel(self.ellipse) z2 = self.evalShapelets(shapelet) self.assertClose(z0, z1) self.assertClose(z0, z2)
def testModel2(self): amplitude = 3.2 radius = 2.7 mgc = ms.GaussianComponent(amplitude, radius) shapelet = mgc.makeShapelet(ellipses.Ellipse(self.ellipse)) builder = ms.GaussianModelBuilder(self.x, self.y, amplitude, radius) builder.update(self.ellipse) self.ellipse.scale(radius) z0 = builder.getModel() z1 = amplitude * self.buildModel(self.ellipse) z2 = self.evalShapelets(shapelet) self.assertClose(z0, z1) self.assertClose(z0, z2)
def testDerivative1(self): builder = ms.GaussianModelBuilder(self.x, self.y) a = numpy.zeros((3, builder.getSize()), dtype=float).transpose() builder.update(self.ellipse) builder.computeDerivative(a) def makeEllipse(p): return ellipses.Axes(*p) n = self.buildNumericalDerivative(builder, self.ellipse.getParameterVector(), makeEllipse) # no hard requirement for tolerances here, but I've dialed them to the max to avoid regressions self.assertClose(a, n, rtol=1E-15, atol=1E-9)
def testDerivative3(self): amplitude = 3.2 radius = 2.7 psfEllipse = ellipses.Quadrupole(2.3, 1.8, 0.6) psfAmplitude = 5.3 builder = ms.GaussianModelBuilder(self.x, self.y, amplitude, radius, psfEllipse, psfAmplitude) a = numpy.zeros((3, builder.getSize()), dtype=float).transpose() builder.update(self.ellipse) builder.computeDerivative(a) def makeEllipse(p): return ellipses.Axes(*p) n = self.buildNumericalDerivative(builder, self.ellipse.getParameterVector(), makeEllipse) # no hard requirement for tolerances here, but I've dialed them to the max to avoid regressions self.assertClose(a, n, rtol=1E-15, atol=1E-9)
def testModel3(self): amplitude = 3.2 radius = 2.7 psfEllipse = ellipses.Quadrupole(2.3, 1.8, 0.6) psfAmplitude = 5.3 mgc = ms.GaussianComponent(amplitude, radius) shapelet = mgc.makeShapelet(ellipses.Ellipse(self.ellipse)) psf = ms.GaussianComponent(psfAmplitude, 1.0).makeShapelet( ellipses.Ellipse(psfEllipse)) shapelet = shapelet.convolve(psf) builder = ms.GaussianModelBuilder(self.x, self.y, amplitude, radius, psfEllipse, psfAmplitude) builder.update(self.ellipse) self.ellipse.scale(radius) ellipse = self.ellipse.convolve(psfEllipse) self.assertClose(builder.getModel(), amplitude * psfAmplitude * self.buildModel(ellipse)) z0 = builder.getModel() z1 = psfAmplitude * amplitude * self.buildModel(ellipse) z2 = self.evalShapelets(shapelet) self.assertClose(z0, z1) self.assertClose(z0, z2)
def testModel(self): multiGaussian = ms.MultiGaussianRegistry.lookup(self.ctrl.profile) self.assertClose(multiGaussian.integrate(), 1.0) parameters = numpy.array([[0.0, 0.0, 1.0], [0.0, 0.0, -16], [0.2, -0.8, 2.3]]) sImage = lsst.afw.image.ImageD(self.bbox) builders = [ ms.GaussianModelBuilder(self.x, self.y, c.flux, c.radius) for c in multiGaussian ] for row in parameters: model = ms.FitProfileModel(self.ctrl, 1.0, row) msf = model.asMultiShapelet(self.center) self.assertClose(msf.evaluate().integrate(), 1.0) 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())