Example #1
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
 def testSetProfile(self):
     fc = self.fitcontribution
     profile = self.profile
     fc.setProfile(self.profile)
     # verify standard profile setup
     self.assertTrue(fc.profile is profile)
     self.assertTrue(fc.x.par is profile.xpar)
     self.assertTrue(fc.y.par is profile.ypar)
     self.assertTrue(fc.dy.par is profile.dypar)
     self.assertTrue(fc._eq is None)
     self.assertTrue(fc._reseq is None)
     # check type checking
     fc1 = FitContribution('test1')
     self.assertRaises(TypeError, fc1.setProfile, 'invalid')
     # check if residual equation is set up when possible
     fc2 = FitContribution('test2')
     fc2.setEquation('A * x')
     fc2.setProfile(profile)
     self.assertFalse(fc2._reseq is None)
     return
Example #3
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
Example #4
0
 def testSetProfile(self):
     fc = self.fitcontribution
     profile = self.profile
     fc.setProfile(self.profile)
     # verify standard profile setup
     self.assertTrue(fc.profile is profile)
     self.assertTrue(fc.x.par is profile.xpar)
     self.assertTrue(fc.y.par is profile.ypar)
     self.assertTrue(fc.dy.par is profile.dypar)
     self.assertTrue(fc._eq is None)
     self.assertTrue(fc._reseq is None)
     # check type checking
     fc1 = FitContribution('test1')
     self.assertRaises(TypeError, fc1.setProfile, 'invalid')
     # check if residual equation is set up when possible
     fc2 = FitContribution('test2')
     fc2.setEquation('A * x')
     fc2.setProfile(profile)
     self.assertFalse(fc2._reseq is None)
     return
 def setUp(self):
     self.gen = ProfileGenerator("test")
     self.profile = Profile()
     self.fitcontribution = FitContribution("test")
     return
Example #6
0
    def testResidual(self):
        """Test the residual, which requires all other methods."""
        fc = self.fitcontribution
        profile = self.profile
        gen = self.gen

        # Add the calculator and profile
        fc.setProfile(profile)
        self.assertTrue(fc.profile is profile)
        fc.addProfileGenerator(gen, "I")
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)
        self.assertEqual(1, len(fc._generators))
        self.assertTrue(gen.name in fc._generators)

        # Let's create some data
        xobs = arange(0, 10, 0.5)
        yobs = xobs
        profile.setObservedProfile(xobs, yobs)

        # Check our fitting equation.
        self.assertTrue(array_equal(fc._eq(), gen(xobs)))

        # Now calculate the residual
        chiv = fc.residual()
        self.assertAlmostEqual(0, dot(chiv, chiv))

        # Now change the equation
        fc.setEquation("2*I")
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)
        chiv = fc.residual()
        self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv))

        # Try to add a parameter
        c = Parameter("c", 2)
        fc._addParameter(c)
        fc.setEquation("c*I")
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)
        chiv = fc.residual()
        self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv))

        # Try something more complex
        c.setValue(3)
        fc.setEquation("c**2*sin(I)")
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)
        xobs = arange(0, 10, 0.5)
        yobs = 9 * sin(xobs)
        profile.setObservedProfile(xobs, yobs)
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)

        chiv = fc.residual()
        self.assertAlmostEqual(0, dot(chiv, chiv))

        # Choose a new residual.
        fc.setEquation("2*I")
        fc.setResidualEquation("resv")
        chiv = fc.residual()
        self.assertAlmostEqual(
            sum((2 * xobs - yobs)**2) / sum(yobs**2), dot(chiv, chiv))

        # Make a custom residual.
        fc.setResidualEquation("abs(eq-y)**0.5")
        chiv = fc.residual()
        self.assertAlmostEqual(sum(abs(2 * xobs - yobs)), dot(chiv, chiv))

        # Test configuration checks
        fc1 = FitContribution('test1')
        self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv')
        fc1.setProfile(self.profile)
        self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv')
        fc1.setEquation('A * x')
        fc1.setResidualEquation('chiv')
        self.assertTrue(noObserversInGlobalBuilders())
        return
Example #7
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
Example #8
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.assertEqual(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.assertEqual(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.assertEqual(names, ["A", "c"])
        values = recipe.getValues()
        self.assertTrue((values == [2, 0]).all())

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

        recipe.free("all")
        names = recipe.getNames()
        self.assertEqual(3, len(names))
        self.assertTrue("A" in names)
        self.assertTrue("k" in names)
        self.assertTrue("c" in names)
        values = recipe.getValues()
        self.assertEqual(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.assertAlmostEqual(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.assertEqual(2, self.fitcontribution.c.value)
        self.recipe.constrain(self.fitcontribution.A, var)
        self.assertEqual(1, var.getValue())
        self.assertEqual(self.recipe.cont.A.getValue(), var.getValue())
        # c is constrained to a constrained parameter.
        self.assertEqual(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.assertAlmostEqual(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.assertAlmostEqual(len(res), dot(res, res))

        return


    def testPrintFitHook(self):
        "check output from default PrintFitHook."
        self.recipe.addVar(self.fitcontribution.c)
        self.recipe.restrain('c', lb=5)
        pfh, = self.recipe.getFitHooks()
        out = capturestdout(self.recipe.scalarResidual)
        self.assertEqual('', out)
        pfh.verbose = 1
        out = capturestdout(self.recipe.scalarResidual)
        self.assertTrue(out.strip().isdigit())
        self.assertFalse('\nRestraints:' in out)
        pfh.verbose = 2
        out = capturestdout(self.recipe.scalarResidual)
        self.assertTrue('\nResidual:' in out)
        self.assertTrue('\nRestraints:' in out)
        self.assertFalse('\nVariables' in out)
        pfh.verbose = 3
        out = capturestdout(self.recipe.scalarResidual)
        self.assertTrue('\nVariables' in out)
        self.assertTrue('c = ' in out)
        return
    def testResidual(self):
        """Test the residual, which requires all other methods."""
        fc = self.fitcontribution
        profile = self.profile
        gen = self.gen

        # Add the calculator and profile
        fc.setProfile(profile)
        self.assertTrue(fc.profile is profile)
        fc.addProfileGenerator(gen, "I")
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)
        self.assertEqual(1, len(fc._generators))
        self.assertTrue(gen.name in fc._generators)

        # Let's create some data
        xobs = arange(0, 10, 0.5)
        yobs = xobs
        profile.setObservedProfile(xobs, yobs)

        # Check our fitting equation.
        self.assertTrue(array_equal(fc._eq(), gen(xobs)))

        # Now calculate the residual
        chiv = fc.residual()
        self.assertAlmostEqual(0, dot(chiv, chiv))

        # Now change the equation
        fc.setEquation("2*I")
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)
        chiv = fc.residual()
        self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv))

        # Try to add a parameter
        c = Parameter("c", 2)
        fc._addParameter(c)
        fc.setEquation("c*I")
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)
        chiv = fc.residual()
        self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv))

        # Try something more complex
        c.setValue(3)
        fc.setEquation("c**2*sin(I)")
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)
        xobs = arange(0, 10, 0.5)
        yobs = 9*sin(xobs)
        profile.setObservedProfile(xobs, yobs)
        self.assertTrue(fc._eq._value is None)
        self.assertTrue(fc._reseq._value is None)

        chiv = fc.residual()
        self.assertAlmostEqual(0, dot(chiv, chiv))

        # Choose a new residual.
        fc.setEquation("2*I")
        fc.setResidualEquation("resv")
        chiv = fc.residual()
        self.assertAlmostEqual(sum((2*xobs-yobs)**2)/sum(yobs**2),
                dot(chiv, chiv))

        # Make a custom residual.
        fc.setResidualEquation("abs(eq-y)**0.5")
        chiv = fc.residual()
        self.assertAlmostEqual(sum(abs(2*xobs-yobs)), dot(chiv, chiv))

        # Test configuration checks
        fc1 = FitContribution('test1')
        self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv')
        fc1.setProfile(self.profile)
        self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv')
        fc1.setEquation('A * x')
        fc1.setResidualEquation('chiv')
        self.assertTrue(noObserversInGlobalBuilders())
        return