diff --git a/docs/examples/coreshellnp.py b/docs/examples/coreshellnp.py index 3f8d5b06..a6442644 100644 --- a/docs/examples/coreshellnp.py +++ b/docs/examples/coreshellnp.py @@ -81,7 +81,7 @@ def makeRecipe(stru1, stru2, datname): # Write the fitting equation. We want to sum the PDFs from each phase and # multiply it by a scaling factor. - contribution.setEquation("scale * (f_CdS * G_CdS + f_ZnS * G_ZnS)") + contribution.set_equation("scale * (f_CdS * G_CdS + f_ZnS * G_ZnS)") # Make the FitRecipe and add the FitContribution. recipe = FitRecipe() diff --git a/docs/examples/crystalpdfall.py b/docs/examples/crystalpdfall.py index 173dfa31..f13545c0 100644 --- a/docs/examples/crystalpdfall.py +++ b/docs/examples/crystalpdfall.py @@ -94,7 +94,7 @@ def makeRecipe( "xsini", xgenerator_sini_ni, xprofile_sini ) xcontribution_sini.add_profile_generator(xgenerator_sini_si) - xcontribution_sini.setEquation("scale * (xG_sini_ni + xG_sini_si)") + xcontribution_sini.set_equation("scale * (xG_sini_ni + xG_sini_si)") # As explained in another example, we want to minimize using Rw^2. xcontribution_ni.setResidualEquation("resv") diff --git a/docs/examples/crystalpdftwophase.py b/docs/examples/crystalpdftwophase.py index bb3560d8..b9e638d9 100644 --- a/docs/examples/crystalpdftwophase.py +++ b/docs/examples/crystalpdftwophase.py @@ -80,7 +80,7 @@ def makeRecipe(niciffile, siciffile, datname): # multiply it by a scaling factor. We also want a certain phase scaling # relationship between the PDFs which we will enforce with constraints in # the FitRecipe. - contribution.setEquation("scale * (G_ni + G_si)") + contribution.set_equation("scale * (G_ni + G_si)") # Make the FitRecipe and add the FitContribution. recipe = FitRecipe() diff --git a/docs/examples/debyemodel.py b/docs/examples/debyemodel.py index d9009127..eca6f15b 100644 --- a/docs/examples/debyemodel.py +++ b/docs/examples/debyemodel.py @@ -126,7 +126,7 @@ def makeRecipe(): # the debye equation to be positive, so we specify the input as abs(thetaD) # in the equation below. Furthermore, we know 'm', the mass of lead, so we # can specify that as well. - contribution.setEquation("debye(T, 207.2, abs(thetaD)) + offset") + contribution.set_equation("debye(T, 207.2, abs(thetaD)) + offset") # The FitRecipe # The FitRecipe lets us define what we want to fit. It is where we can diff --git a/docs/examples/gaussiangenerator.py b/docs/examples/gaussiangenerator.py index c6631942..4756474e 100644 --- a/docs/examples/gaussiangenerator.py +++ b/docs/examples/gaussiangenerator.py @@ -33,8 +33,9 @@ Extensions -- Remove the amplitude from GaussianGenerator and instead use the 'setEquation' - method of the FitContribution to account for it. Note that the +- Remove the amplitude from GaussianGenerator and instead use the + 'set_equation' method of the + FitContribution to account for it. Note that the GaussianGenerator will be accessible by its name, "g". """ diff --git a/docs/examples/gaussianrecipe.py b/docs/examples/gaussianrecipe.py index c203052f..f03c9d6d 100644 --- a/docs/examples/gaussianrecipe.py +++ b/docs/examples/gaussianrecipe.py @@ -124,7 +124,7 @@ def makeRecipe(): # contribution by name. Since we told the contribution that our # independent variable is named "x", this value will be substituted into # the fitting equation whenever it is called. - contribution.setEquation("A * exp(-0.5*(x-x0)**2/sigma**2)") + contribution.set_equation("A * exp(-0.5*(x-x0)**2/sigma**2)") # To demonstrate how these parameters are used, we will give "A" an initial # value. Note that Parameters are not numbers, but are containers for diff --git a/docs/examples/interface.py b/docs/examples/interface.py index 4611ee6b..640aebc0 100644 --- a/docs/examples/interface.py +++ b/docs/examples/interface.py @@ -38,7 +38,7 @@ def main(): # "<<" - Inject a parameter value c = FitContribution("g1") c.set_profile(p) - c.setEquation("A * exp(-0.5*(x-x0)**2/sigma**2)") + c.set_equation("A * exp(-0.5*(x-x0)**2/sigma**2)") c.A << 0.5 c.x0 << 5 c.sigma << 1 diff --git a/docs/examples/npintensity.py b/docs/examples/npintensity.py index 4de6e13f..e5a50c87 100644 --- a/docs/examples/npintensity.py +++ b/docs/examples/npintensity.py @@ -256,7 +256,7 @@ def gaussian(q, q0, width): # convolve the signal with the Gaussian to broaden it. Recall that we don't # need to supply arguments to the registered functions unless we want to # make changes to their input values. - contribution.setEquation("scale * convolve(I, gaussian) + bkgd") + contribution.set_equation("scale * convolve(I, gaussian) + bkgd") # Make the FitRecipe and add the FitContribution. recipe = FitRecipe() diff --git a/docs/examples/npintensityII.py b/docs/examples/npintensityII.py index d3bd4ef5..b6713002 100644 --- a/docs/examples/npintensityII.py +++ b/docs/examples/npintensityII.py @@ -125,8 +125,8 @@ def gaussian(q, q0, width): # Now we can incorporate the scale and bkgd into our calculation. We also # convolve the signal with the gaussian to broaden it. - contribution1.setEquation("scale * convolve(I, gaussian) + bkgd") - contribution2.setEquation("scale * convolve(I, gaussian) + bkgd") + contribution1.set_equation("scale * convolve(I, gaussian) + bkgd") + contribution2.set_equation("scale * convolve(I, gaussian) + bkgd") # Make a FitRecipe and associate the FitContributions. recipe = FitRecipe() diff --git a/docs/examples/nppdfcrystal.py b/docs/examples/nppdfcrystal.py index 14751250..40c14c58 100644 --- a/docs/examples/nppdfcrystal.py +++ b/docs/examples/nppdfcrystal.py @@ -62,7 +62,7 @@ def makeRecipe(ciffile, grdata): pdfcontribution.registerFunction(sphericalCF, name="f") # Now we set up the fitting equation. - pdfcontribution.setEquation("f * G") + pdfcontribution.set_equation("f * G") # Now make the recipe. Make sure we fit the characteristic function shape # parameters, in this case 'psize', which is the diameter of the particle. diff --git a/docs/examples/nppdfsas.py b/docs/examples/nppdfsas.py index acd6fac7..a415f89e 100644 --- a/docs/examples/nppdfsas.py +++ b/docs/examples/nppdfsas.py @@ -89,7 +89,7 @@ def makeRecipe(ciffile, grdata, iqdata): pdfcontribution.registerCalculator(cfcalculator) # The PDF for a nanoscale crystalline is approximated by # Gnano = f * Gcryst - pdfcontribution.setEquation("f * G") + pdfcontribution.set_equation("f * G") # Moving on recipe = FitRecipe() diff --git a/docs/examples/simplerecipe.py b/docs/examples/simplerecipe.py index 0ec297a5..ef1f9a5e 100644 --- a/docs/examples/simplerecipe.py +++ b/docs/examples/simplerecipe.py @@ -38,7 +38,7 @@ def main(): # Set the equation. The variable "x" is taken from the data that was just # loaded. The other variables, "A", "x0" and "sigma" are turned into # attributes with an initial value of 0. - recipe.setEquation("A * exp(-0.5*(x-x0)**2/sigma**2)") + recipe.set_equation("A * exp(-0.5*(x-x0)**2/sigma**2)") # We can give them other values here. recipe.A = 1 diff --git a/docs/examples/threedoublepeaks.py b/docs/examples/threedoublepeaks.py index e336fff1..d54428da 100644 --- a/docs/examples/threedoublepeaks.py +++ b/docs/examples/threedoublepeaks.py @@ -77,7 +77,7 @@ def delta(t, mu): contribution.registerStringFunction(bkgdstr, "bkgd") # Now define our fitting equation. We will hardcode the peak ratios. - contribution.setEquation( + contribution.set_equation( "A1 * ( convolve( delta(t, mu11), peakshape(t, c, sig11) ) \ + 0.23*convolve( delta(t, mu12), peakshape(t, c, sig12) ) ) + \ A2 * ( convolve( delta(t, mu21), peakshape(t, c, sig21) ) \ diff --git a/news/setequation-dep.rst b/news/setequation-dep.rst new file mode 100644 index 00000000..cb6fe13b --- /dev/null +++ b/news/setequation-dep.rst @@ -0,0 +1,23 @@ +**Added:** + +* Added ``set_equation`` method to replace ``setEquation``. + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``setEquation`` for removal in 4.0.0. + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/srfit/fitbase/fitcontribution.py b/src/diffpy/srfit/fitbase/fitcontribution.py index bbb23fb3..9a4402ae 100644 --- a/src/diffpy/srfit/fitbase/fitcontribution.py +++ b/src/diffpy/srfit/fitbase/fitcontribution.py @@ -34,6 +34,14 @@ base = "diffpy.srfit.fitbase.FitContribution" removal_version = "4.0.0" +setequation_dep_msg = build_deprecation_message( + base, + "setEquation", + "set_equation", + removal_version, +) + + setprofile_dep_msg = build_deprecation_message( base, "setProfile", @@ -226,7 +234,7 @@ def add_profile_generator(self, gen, name=None): # Make this our equation if we don't have one. This will set the # residual equation if necessary. if self._eq is None: - self.setEquation(name) + self.set_equation(name) return @@ -242,7 +250,7 @@ def addProfileGenerator(self, gen, name=None): self.add_profile_generator(gen, name=name) return - def setEquation(self, eqstr, ns={}): + def set_equation(self, eqstr, ns={}): """Set the profile equation for the FitContribution. This sets the equation that will be used when generating the residual @@ -285,6 +293,17 @@ def setEquation(self, eqstr, ns={}): return + @deprecated(setequation_dep_msg) + def setEquation(self, eqstr, ns={}): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.srfit.fitbase.FitContribution.set_equation + instead. + """ + self.set_equation(eqstr, ns=ns) + return + def getEquation(self): """Get math expression string for the active profile equation. diff --git a/src/diffpy/srfit/fitbase/simplerecipe.py b/src/diffpy/srfit/fitbase/simplerecipe.py index 2dfbe167..f4b3347c 100644 --- a/src/diffpy/srfit/fitbase/simplerecipe.py +++ b/src/diffpy/srfit/fitbase/simplerecipe.py @@ -201,7 +201,7 @@ def loadtxt(self, *args, **kw): return self.profile.loadtxt(*args, **kw) # FitContribution - def setEquation(self, eqstr, ns={}): + def set_equation(self, eqstr, ns={}): """Set the profile equation for the FitContribution. This sets the equation that will be used when generating the residual. @@ -222,7 +222,7 @@ def setEquation(self, eqstr, ns={}): Raises ValueError if ns uses a name that is already used for a variable. """ - self.contribution.setEquation(eqstr, ns={}) + self.contribution.set_equation(eqstr, ns={}) # Extract variables for par in self.contribution: # Skip Profile Parameters diff --git a/src/diffpy/srfit/pdf/pdfcontribution.py b/src/diffpy/srfit/pdf/pdfcontribution.py index 4809676c..3f487a93 100644 --- a/src/diffpy/srfit/pdf/pdfcontribution.py +++ b/src/diffpy/srfit/pdf/pdfcontribution.py @@ -280,7 +280,7 @@ def _setup_generator(self, gen): gnames = self._generators.keys() eqstr = " + ".join(gnames) eqstr = "scale * (%s)" % eqstr - self.setEquation(eqstr) + self.set_equation(eqstr) # Update with our metadata gen.meta.update(self._meta) diff --git a/tests/conftest.py b/tests/conftest.py index 4f03b166..d60e870e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -155,7 +155,7 @@ def build_recipe_one_contribution(): profile.setObservedProfile(x, y) contribution = FitContribution("c1") contribution.set_profile(profile) - contribution.setEquation("A*sin(k*x + c)") + contribution.set_equation("A*sin(k*x + c)") recipe = FitRecipe() recipe.add_contribution(contribution) recipe.addVar(contribution.A, 1) @@ -173,14 +173,14 @@ def build_recipe_two_contributions(): profile1.setObservedProfile(x, y1) contribution1 = FitContribution("c1") contribution1.set_profile(profile1) - contribution1.setEquation("A*sin(k*x + c)") + contribution1.set_equation("A*sin(k*x + c)") profile2 = Profile() y2 = 0.5 * sin(2 * x) profile2.setObservedProfile(x, y2) contribution2 = FitContribution("c2") contribution2.set_profile(profile2) - contribution2.setEquation("B*sin(m*x + d)") + contribution2.set_equation("B*sin(m*x + d)") recipe = FitRecipe() recipe.add_contribution(contribution1) recipe.add_contribution(contribution2) diff --git a/tests/test_contribution.py b/tests/test_contribution.py index 37eae01b..7c167634 100644 --- a/tests/test_contribution.py +++ b/tests/test_contribution.py @@ -50,7 +50,7 @@ def testset_profile(self): self.assertRaises(TypeError, fc1.setProfile, "invalid") # check if residual equation is set up when possible fc2 = FitContribution("test2") - fc2.setEquation("A * x") + fc2.set_equation("A * x") fc2.set_profile(profile) self.assertFalse(fc2._reseq is None) return @@ -160,7 +160,7 @@ def test_getResidualEquation(self): fc = self.fitcontribution self.assertEqual("", fc.getResidualEquation()) fc.set_profile(self.profile) - fc.setEquation("A * x + B") + fc.set_equation("A * x + B") self.assertEqual("((eq - y) / dy)", fc.getResidualEquation()) fc.setResidualEquation("2 * (eq - y)") self.assertEqual("(2 * (eq - y))", fc.getResidualEquation()) @@ -171,7 +171,7 @@ def test_releaseOldEquations(self): fc = self.fitcontribution self.assertEqual(0, len(fc._eqfactory.equations)) for i in range(5): - fc.setEquation("A * x + B") + fc.set_equation("A * x + B") self.assertEqual(1, len(fc._eqfactory.equations)) fc.set_profile(self.profile) for i in range(5): @@ -180,15 +180,15 @@ def test_releaseOldEquations(self): return def test_registerFunction(self): - """Ensure registered function works after second setEquation call.""" + """Ensure registered function works after second set_equation call.""" fc = self.fitcontribution fc.registerFunction(_fsquare, name="fsquare") - fc.setEquation("fsquare") + fc.set_equation("fsquare") fc.x.setValue(5) self.assertEqual(25, fc.evaluate()) fc.x << 6 self.assertEqual(36, fc.evaluate()) - fc.setEquation("fsquare + 5") + fc.set_equation("fsquare + 5") self.assertEqual(41, fc.evaluate()) fc.x << -1 self.assertEqual(6, fc.evaluate()) @@ -227,7 +227,7 @@ def testResidual(noObserversInGlobalBuilders): assert dot(chiv, chiv) == pytest.approx(0) # Now change the equation - fc.setEquation("2*I") + fc.set_equation("2*I") assert fc._eq._value is None assert fc._reseq._value is None chiv = fc.residual() @@ -236,7 +236,7 @@ def testResidual(noObserversInGlobalBuilders): # Try to add a parameter c = Parameter("c", 2) fc._add_parameter(c) - fc.setEquation("c*I") + fc.set_equation("c*I") assert fc._eq._value is None assert fc._reseq._value is None chiv = fc.residual() @@ -244,7 +244,7 @@ def testResidual(noObserversInGlobalBuilders): # Try something more complex c.setValue(3) - fc.setEquation("c**2*sin(I)") + fc.set_equation("c**2*sin(I)") assert fc._eq._value is None assert fc._reseq._value is None xobs = arange(0, 10, 0.5) @@ -257,7 +257,7 @@ def testResidual(noObserversInGlobalBuilders): assert dot(chiv, chiv) == pytest.approx(0) # Choose a new residual. - fc.setEquation("2*I") + fc.set_equation("2*I") fc.setResidualEquation("resv") chiv = fc.residual() assert dot(chiv, chiv) == pytest.approx( @@ -276,7 +276,7 @@ def testResidual(noObserversInGlobalBuilders): fc1.set_profile(profile) with pytest.raises(SrFitError): fc1.setResidualEquation("chiv") - fc1.setEquation("A * x") + fc1.set_equation("A * x") fc1.setResidualEquation("chiv") assert noObserversInGlobalBuilders return @@ -296,11 +296,25 @@ def test_setEquation(noObserversInGlobalBuilders): return +def test_set_equation(noObserversInGlobalBuilders): + """Check replacement of removed parameters.""" + fc = FitContribution("test") + fc.set_equation("x + 5") + fc.x.setValue(2) + assert 7 == fc.evaluate() + fc.removeParameter(fc.x) + x = arange(0, 10, 0.5) + fc.newParameter("x", x) + assert np.array_equal(5 + x, fc.evaluate()) + assert noObserversInGlobalBuilders + return + + def test_getEquation(noObserversInGlobalBuilders): """Check getting the current profile simulation formula.""" fc = FitContribution("test") assert "" == fc.getEquation() - fc.setEquation("A * sin(x + 5)") + fc.set_equation("A * sin(x + 5)") assert "(A * sin((x + 5)))" == fc.getEquation() assert noObserversInGlobalBuilders return diff --git a/tests/test_fitrecipe.py b/tests/test_fitrecipe.py index 0f8761ac..60ed9e1f 100644 --- a/tests/test_fitrecipe.py +++ b/tests/test_fitrecipe.py @@ -46,7 +46,7 @@ def setUp(self): # Set up the FitContribution self.fitcontribution = FitContribution("cont") self.fitcontribution.set_profile(self.profile) - self.fitcontribution.setEquation("A*sin(k*x + c)") + self.fitcontribution.set_equation("A*sin(k*x + c)") self.fitcontribution.A.setValue(1) self.fitcontribution.k.setValue(1) self.fitcontribution.c.setValue(0) @@ -233,12 +233,12 @@ def testResidual(self): # Now try to use the observed profile inside of the equation # Set the equation equal to the data - self.fitcontribution.setEquation("y") + self.fitcontribution.set_equation("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") + self.fitcontribution.set_equation("y+dy") res = self.recipe.residual() self.assertAlmostEqual(len(res), dot(res, res)) @@ -263,7 +263,7 @@ def testPrintFitHook(capturestdout): # Set up the FitContribution fitcontribution = FitContribution("cont") fitcontribution.set_profile(profile) - fitcontribution.setEquation("A*sin(k*x + c)") + fitcontribution.set_equation("A*sin(k*x + c)") fitcontribution.A.setValue(1) fitcontribution.k.setValue(1) fitcontribution.c.setValue(0) @@ -311,7 +311,7 @@ def test_add_contribution(capturestdout): # Set up the FitContribution fitcontribution = FitContribution("cont") fitcontribution.set_profile(profile) - fitcontribution.setEquation("A*sin(k*x + c)") + fitcontribution.set_equation("A*sin(k*x + c)") fitcontribution.A.setValue(1) fitcontribution.k.setValue(1) fitcontribution.c.setValue(0) @@ -373,7 +373,7 @@ def build_recipe_from_datafile(datafile): contribution = FitContribution("c") contribution.set_profile(profile) - contribution.setEquation("m*x + b") + contribution.set_equation("m*x + b") recipe = FitRecipe() recipe.add_contribution(contribution) recipe.addVar(contribution.m, 1) diff --git a/tests/test_weakrefcallable.py b/tests/test_weakrefcallable.py index 5d44d18b..fd3488ac 100644 --- a/tests/test_weakrefcallable.py +++ b/tests/test_weakrefcallable.py @@ -29,7 +29,7 @@ class TestWeakBoundMethod(unittest.TestCase): def setUp(self): self.f = FitContribution("f") - self.f.setEquation("7") + self.f.set_equation("7") self.w = weak_ref(self.f._eq._flush, fallback=_fallback_example) return @@ -112,7 +112,7 @@ def test_observable_deregistration(self): """Check if Observable drops dead Observer.""" f = self.f x = f.newParameter("x", 5) - f.setEquation("3 * x") + f.set_equation("3 * x") self.assertEqual(15, f.evaluate()) self.assertEqual(15, f._eq._value) # get one of the observer callables that are associated with f