예제 #1
0
    def __init__(self, name="fit", conclass=FitContribution):
        """Initialization."""
        FitRecipe.__init__(self, name)
        self.fithooks[0].verbose = 3
        contribution = conclass("contribution")
        self.profile = Profile()
        contribution.setProfile(self.profile)
        self.addContribution(contribution)
        self.results = FitResults(self, update=False)

        # Adopt all the FitContribution methods
        public = [
            aname for aname in dir(contribution)
            if aname not in dir(self) and not aname.startswith("_")
        ]
        for mname in public:
            method = getattr(contribution, mname)
            setattr(self, mname, method)
        return
예제 #2
0
    def setUp(self):
        self.recipe = FitRecipe("recipe")
        self.recipe.fithooks[0].verbose = 0

        # Set up the Profile
        self.profile = Profile()
        x = linspace(0, pi, 10)
        y = sin(x)
        self.profile.setObservedProfile(x, y)

        # Set up the FitContribution
        self.fitcontribution = FitContribution("cont")
        self.fitcontribution.setProfile(self.profile)
        self.fitcontribution.setEquation("A*sin(k*x + c)")
        self.fitcontribution.A.setValue(1)
        self.fitcontribution.k.setValue(1)
        self.fitcontribution.c.setValue(0)

        self.recipe.addContribution(self.fitcontribution)
        return
예제 #3
0
    def setUp(self):
        self.recipe = recipe = FitRecipe("recipe")
        recipe.newVar("A", 0)
        recipe.newVar("sig", 0)
        recipe.newVar("x0", 0)
        self.filename = datafile("results.res")

        self.Aval = 5.77619823e-01
        self.sigval = -9.22758690e-01
        self.x0val = 6.12422115e+00
        return
예제 #4
0
    def testConstrainSpaceGroup(self):
        """Make sure that all Parameters are constrained properly.

        This tests constrainSpaceGroup from
        diffpy.srfit.structure.sgconstraints, which is performed automatically
        when an ObjCrystCrystalParSet is created.

        """
        pi = numpy.pi

        occryst = makeLaMnO3()
        stru = ObjCrystCrystalParSet(occryst.GetName(), occryst)
        # Make sure we actually create the constraints
        stru._constrainSpaceGroup()
        # Make the space group parameters individually
        stru.sgpars.latpars
        stru.sgpars.xyzpars
        stru.sgpars.adppars

        # Check the orthorhombic lattice
        l = stru.getLattice()
        self.assertTrue( l.alpha.const )
        self.assertTrue( l.beta.const )
        self.assertTrue( l.gamma.const )
        self.assertEquals(pi/2, l.alpha.getValue())
        self.assertEquals(pi/2, l.beta.getValue())
        self.assertEquals(pi/2, l.gamma.getValue())

        self.assertFalse( l.a.const )
        self.assertFalse( l.b.const )
        self.assertFalse( l.c.const )
        self.assertEquals(0, len(l._constraints))

        # Now make sure the scatterers are constrained properly
        scatterers = stru.getScatterers()
        la = scatterers[0]
        self.assertFalse(la.x.const)
        self.assertFalse(la.y.const)
        self.assertTrue(la.z.const)
        self.assertEquals(0, len(la._constraints))

        mn = scatterers[1]
        self.assertTrue(mn.x.const)
        self.assertTrue(mn.y.const)
        self.assertTrue(mn.z.const)
        self.assertEquals(0, len(mn._constraints))

        o1 = scatterers[2]
        self.assertFalse(o1.x.const)
        self.assertFalse(o1.y.const)
        self.assertTrue(o1.z.const)
        self.assertEquals(0, len(o1._constraints))

        o2 = scatterers[3]
        self.assertFalse(o2.x.const)
        self.assertFalse(o2.y.const)
        self.assertFalse(o2.z.const)
        self.assertEquals(0, len(o2._constraints))

        # Make sure we can't constrain these
        self.assertRaises(ValueError, mn.constrain, mn.x, "y")
        self.assertRaises(ValueError, mn.constrain, mn.y, "z")
        self.assertRaises(ValueError, mn.constrain, mn.z, "x")

        # Nor can we make them into variables
        from diffpy.srfit.fitbase.fitrecipe import FitRecipe
        f = FitRecipe()
        self.assertRaises(ValueError, f.addVar, mn.x)

        return
예제 #5
0
class TestFitRecipe(unittest.TestCase):
    def setUp(self):
        self.recipe = FitRecipe("recipe")
        self.recipe.fithooks[0].verbose = 0

        # Set up the Profile
        self.profile = Profile()
        x = linspace(0, pi, 10)
        y = sin(x)
        self.profile.setObservedProfile(x, y)

        # Set up the FitContribution
        self.fitcontribution = FitContribution("cont")
        self.fitcontribution.setProfile(self.profile)
        self.fitcontribution.setEquation("A*sin(k*x + c)")
        self.fitcontribution.A.setValue(1)
        self.fitcontribution.k.setValue(1)
        self.fitcontribution.c.setValue(0)

        self.recipe.addContribution(self.fitcontribution)
        return

    def testFixFree(self):
        recipe = self.recipe
        con = self.fitcontribution

        recipe.addVar(con.A, 2, tag="tagA")
        recipe.addVar(con.k, 1, tag="tagk")
        recipe.addVar(con.c, 0)
        recipe.newVar("B", 0)

        self.assertTrue(recipe.isFree(recipe.A))
        recipe.fix("tagA")
        self.assertFalse(recipe.isFree(recipe.A))
        recipe.free("tagA")
        self.assertTrue(recipe.isFree(recipe.A))
        recipe.fix("A")
        self.assertFalse(recipe.isFree(recipe.A))
        recipe.free("A")
        self.assertTrue(recipe.isFree(recipe.A))
        recipe.fix(recipe.A)
        self.assertFalse(recipe.isFree(recipe.A))
        recipe.free(recipe.A)
        self.assertTrue(recipe.isFree(recipe.A))
        recipe.fix(recipe.A)
        self.assertFalse(recipe.isFree(recipe.A))
        recipe.free("all")
        self.assertTrue(recipe.isFree(recipe.A))
        self.assertTrue(recipe.isFree(recipe.k))
        self.assertTrue(recipe.isFree(recipe.c))
        self.assertTrue(recipe.isFree(recipe.B))
        recipe.fix(recipe.A, "tagk", c=3)
        self.assertFalse(recipe.isFree(recipe.A))
        self.assertFalse(recipe.isFree(recipe.k))
        self.assertFalse(recipe.isFree(recipe.c))
        self.assertTrue(recipe.isFree(recipe.B))
        self.assertEquals(3, recipe.c.value)
        recipe.fix("all")
        self.assertFalse(recipe.isFree(recipe.A))
        self.assertFalse(recipe.isFree(recipe.k))
        self.assertFalse(recipe.isFree(recipe.c))
        self.assertFalse(recipe.isFree(recipe.B))

        self.assertRaises(ValueError, recipe.free, "junk")
        self.assertRaises(ValueError, recipe.fix, tagA=1)
        self.assertRaises(ValueError, recipe.fix, "junk")
        return

    def testVars(self):
        """Test to see if variables are added and removed properly."""
        recipe = self.recipe
        con = self.fitcontribution

        recipe.addVar(con.A, 2)
        recipe.addVar(con.k, 1)
        recipe.addVar(con.c, 0)
        recipe.newVar("B", 0)

        names = recipe.getNames()
        self.assertEquals(names, ["A", "k", "c", "B"])
        values = recipe.getValues()
        self.assertTrue((values == [2, 1, 0, 0]).all())

        # Constrain a parameter to the B-variable to give it a value
        p = Parameter("Bpar", -1)
        recipe.constrain(recipe.B, p)
        values = recipe.getValues()
        self.assertTrue((values == [2, 1, 0]).all())
        recipe.delVar(recipe.B)

        recipe.fix(recipe.k)

        names = recipe.getNames()
        self.assertEquals(names, ["A", "c"])
        values = recipe.getValues()
        self.assertTrue((values == [2, 0]).all())

        recipe.fix("all")
        names = recipe.getNames()
        self.assertEquals(names, [])
        values = recipe.getValues()
        self.assertTrue((values == []).all())

        recipe.free("all")
        names = recipe.getNames()
        self.assertEquals(3, len(names))
        self.assertTrue("A" in names)
        self.assertTrue("k" in names)
        self.assertTrue("c" in names)
        values = recipe.getValues()
        self.assertEquals(3, len(values))
        self.assertTrue(0 in values)
        self.assertTrue(1 in values)
        self.assertTrue(2 in values)
        return

    def testResidual(self):
        """Test the residual and everything that can change it."""

        # With thing set up as they are, the residual should be 0
        res = self.recipe.residual()
        self.assertAlmostEquals(0, dot(res, res))

        # Change the c value to 1 so that the equation evaluates as sin(x+1)
        x = self.profile.x
        y = sin(x + 1)
        self.recipe.cont.c.setValue(1)
        res = self.recipe.residual()
        self.assertTrue(array_equal(y - self.profile.y, res))

        # Try some constraints
        # Make c = 2*A, A = Avar
        var = self.recipe.newVar("Avar")
        self.recipe.constrain(self.fitcontribution.c, "2*A",
                              {"A": self.fitcontribution.A})
        self.assertEquals(2, self.fitcontribution.c.value)
        self.recipe.constrain(self.fitcontribution.A, var)
        self.assertEquals(1, var.getValue())
        self.assertEquals(self.recipe.cont.A.getValue(), var.getValue())
        # c is constrained to a constrained parameter.
        self.assertEquals(2, self.fitcontribution.c.value)
        # The equation should evaluate to sin(x+2)
        x = self.profile.x
        y = sin(x + 2)
        res = self.recipe.residual()
        self.assertTrue(array_equal(y - self.profile.y, res))

        # Now try some restraints. We want c to be exactly zero. It should give
        # a penalty of (c-0)**2, which is 4 in this case
        r1 = self.recipe.restrain(self.fitcontribution.c, 0, 0, 1)
        self.recipe._ready = False
        res = self.recipe.residual()
        chi2 = 4 + dot(y - self.profile.y, y - self.profile.y)
        self.assertAlmostEqual(chi2, dot(res, res))

        # Clear the constraint and restore the value of c to 0. This should
        # give us chi2 = 0 again.
        self.recipe.unconstrain(self.fitcontribution.c)
        self.fitcontribution.c.setValue(0)
        res = self.recipe.residual([self.recipe.cont.A.getValue()])
        chi2 = 0
        self.assertAlmostEqual(chi2, dot(res, res))

        # Remove the restraint and variable
        self.recipe.unrestrain(r1)
        self.recipe.delVar(self.recipe.Avar)
        self.recipe._ready = False
        res = self.recipe.residual()
        chi2 = 0
        self.assertAlmostEqual(chi2, dot(res, res))

        # Add constraints at the fitcontribution level.
        self.fitcontribution.constrain(self.fitcontribution.c, "2*A")
        # This should evaluate to sin(x+2)
        x = self.profile.x
        y = sin(x + 2)
        res = self.recipe.residual()
        self.assertTrue(array_equal(y - self.profile.y, res))

        # Add a restraint at the fitcontribution level.
        r1 = self.fitcontribution.restrain(self.fitcontribution.c, 0, 0, 1)
        self.recipe._ready = False
        # The chi2 is the same as above, plus 4
        res = self.recipe.residual()
        x = self.profile.x
        y = sin(x + 2)
        chi2 = 4 + dot(y - self.profile.y, y - self.profile.y)
        self.assertAlmostEqual(chi2, dot(res, res))

        # Remove those
        self.fitcontribution.unrestrain(r1)
        self.recipe._ready = False
        self.fitcontribution.unconstrain(self.fitcontribution.c)
        self.fitcontribution.c.setValue(0)
        res = self.recipe.residual()
        chi2 = 0
        self.assertAlmostEqual(chi2, dot(res, res))

        # Now try to use the observed profile inside of the equation
        # Set the equation equal to the data
        self.fitcontribution.setEquation("y")
        res = self.recipe.residual()
        self.assertAlmostEquals(0, dot(res, res))

        # Now add the uncertainty. This should give dy/dy = 1 for the residual
        self.fitcontribution.setEquation("y+dy")
        res = self.recipe.residual()
        self.assertAlmostEquals(len(res), dot(res, res))

        return