From 0adb573aac2975c291909764f0f79ab2ebc64768 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 19 Feb 2026 12:47:00 -0500 Subject: [PATCH 1/8] deprecate SimpleRecipe.loadParsedData --- src/diffpy/srfit/fitbase/simplerecipe.py | 26 ++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/diffpy/srfit/fitbase/simplerecipe.py b/src/diffpy/srfit/fitbase/simplerecipe.py index f4b3347c..10bec267 100644 --- a/src/diffpy/srfit/fitbase/simplerecipe.py +++ b/src/diffpy/srfit/fitbase/simplerecipe.py @@ -18,6 +18,17 @@ from diffpy.srfit.fitbase.fitrecipe import FitRecipe from diffpy.srfit.fitbase.fitresults import FitResults from diffpy.srfit.fitbase.profile import Profile +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.srfit.fitbase.simplerecipe.SimpleRecipe" +removal_version = "4.0.0" + +loadParsedData_dep_msg = build_deprecation_message( + base, + "loadParsedData", + "load_parsed_data", + removal_version, +) class SimpleRecipe(FitRecipe): @@ -109,12 +120,23 @@ def __init__(self, name="fit", conclass=FitContribution): return # Profile methods - def loadParsedData(self, parser): + def load_parsed_data(self, parser): """Load parsed data from a ProfileParser. This sets the xobs, yobs, dyobs arrays as well as the metadata. """ - return self.profile.loadParsedData(parser) + return self.profile.load_parsed_data(parser) + + @deprecated(loadParsedData_dep_msg) + def loadParsedData(self, parser): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use + diffpy.srfit.fitbase.simplerecipe.SimpleRecipe.load_parsed_data + instead. + """ + return self.load_parsed_data(parser) def setObservedProfile(self, xobs, yobs, dyobs=None): """Set the observed profile. From a8fb4889281d5944ef68937a56c1d5ebee390e60 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 19 Feb 2026 12:54:24 -0500 Subject: [PATCH 2/8] deprecate Profile.loadParsedData --- docs/examples/coreshellnp.py | 2 +- docs/examples/crystalpdf.py | 2 +- docs/examples/crystalpdfall.py | 2 +- docs/examples/crystalpdfobjcryst.py | 2 +- docs/examples/crystalpdftwodata.py | 4 +-- docs/examples/crystalpdftwophase.py | 2 +- docs/examples/ellipsoidsas.py | 2 +- docs/examples/nppdfcrystal.py | 2 +- docs/examples/nppdfsas.py | 4 +-- src/diffpy/srfit/fitbase/profile.py | 23 ++++++++++++++- src/diffpy/srfit/pdf/pdfcontribution.py | 4 +-- tests/test_fitrecipe.py | 38 +++++++++++++++++++++++++ 12 files changed, 73 insertions(+), 14 deletions(-) diff --git a/docs/examples/coreshellnp.py b/docs/examples/coreshellnp.py index 84d4f62f..51860f3e 100644 --- a/docs/examples/coreshellnp.py +++ b/docs/examples/coreshellnp.py @@ -44,7 +44,7 @@ def makeRecipe(stru1, stru2, datname): # Load data and add it to the profile parser = PDFParser() parser.parseFile(datname) - profile.loadParsedData(parser) + profile.load_parsed_data(parser) profile.setCalculationRange(xmin=1.5, xmax=45, dx=0.1) # The ProfileGenerator diff --git a/docs/examples/crystalpdf.py b/docs/examples/crystalpdf.py index 2a011e87..3fd9666e 100644 --- a/docs/examples/crystalpdf.py +++ b/docs/examples/crystalpdf.py @@ -55,7 +55,7 @@ def makeRecipe(ciffile, datname): # configuration steps. parser = PDFParser() parser.parseFile(datname) - profile.loadParsedData(parser) + profile.load_parsed_data(parser) profile.setCalculationRange(xmax=20) # The ProfileGenerator diff --git a/docs/examples/crystalpdfall.py b/docs/examples/crystalpdfall.py index f13545c0..8946dfe0 100644 --- a/docs/examples/crystalpdfall.py +++ b/docs/examples/crystalpdfall.py @@ -39,7 +39,7 @@ def makeProfile(datafile): profile = Profile() parser = PDFParser() parser.parseFile(datafile) - profile.loadParsedData(parser) + profile.load_parsed_data(parser) profile.setCalculationRange(xmax=20) return profile diff --git a/docs/examples/crystalpdfobjcryst.py b/docs/examples/crystalpdfobjcryst.py index 6f4d6fef..70ef78d7 100644 --- a/docs/examples/crystalpdfobjcryst.py +++ b/docs/examples/crystalpdfobjcryst.py @@ -48,7 +48,7 @@ def makeRecipe(ciffile, datname): # structure being refined. parser = PDFParser() parser.parseFile(datname) - profile.loadParsedData(parser) + profile.load_parsed_data(parser) profile.setCalculationRange(xmax=20) # The ProfileGenerator diff --git a/docs/examples/crystalpdftwodata.py b/docs/examples/crystalpdftwodata.py index f44beb1c..679dc693 100644 --- a/docs/examples/crystalpdftwodata.py +++ b/docs/examples/crystalpdftwodata.py @@ -48,12 +48,12 @@ def makeRecipe(ciffile, xdatname, ndatname): # Load data and add it to the proper Profile. parser = PDFParser() parser.parseFile(xdatname) - xprofile.loadParsedData(parser) + xprofile.load_parsed_data(parser) xprofile.setCalculationRange(xmax=20) parser = PDFParser() parser.parseFile(ndatname) - nprofile.loadParsedData(parser) + nprofile.load_parsed_data(parser) nprofile.setCalculationRange(xmax=20) # The ProfileGenerators diff --git a/docs/examples/crystalpdftwophase.py b/docs/examples/crystalpdftwophase.py index b9e638d9..59a85743 100644 --- a/docs/examples/crystalpdftwophase.py +++ b/docs/examples/crystalpdftwophase.py @@ -45,7 +45,7 @@ def makeRecipe(niciffile, siciffile, datname): # Load data and add it to the profile parser = PDFParser() parser.parseFile(datname) - profile.loadParsedData(parser) + profile.load_parsed_data(parser) profile.setCalculationRange(xmax=20) # The ProfileGenerator diff --git a/docs/examples/ellipsoidsas.py b/docs/examples/ellipsoidsas.py index c7fd391b..bac18dde 100644 --- a/docs/examples/ellipsoidsas.py +++ b/docs/examples/ellipsoidsas.py @@ -39,7 +39,7 @@ def makeRecipe(datname): # properly and pass the metadata along. parser = SASParser() parser.parseFile(datname) - profile.loadParsedData(parser) + profile.load_parsed_data(parser) # The ProfileGenerator # The SASGenerator is for configuring and calculating a SAS profile. We use diff --git a/docs/examples/nppdfcrystal.py b/docs/examples/nppdfcrystal.py index 40c14c58..c4bffaa1 100644 --- a/docs/examples/nppdfcrystal.py +++ b/docs/examples/nppdfcrystal.py @@ -44,7 +44,7 @@ def makeRecipe(ciffile, grdata): pdfparser = PDFParser() pdfparser.parseFile(grdata) - pdfprofile.loadParsedData(pdfparser) + pdfprofile.load_parsed_data(pdfparser) pdfprofile.setCalculationRange(xmin=0.1, xmax=20) pdfcontribution = FitContribution("pdf") diff --git a/docs/examples/nppdfsas.py b/docs/examples/nppdfsas.py index c655939d..6eff4b31 100644 --- a/docs/examples/nppdfsas.py +++ b/docs/examples/nppdfsas.py @@ -48,7 +48,7 @@ def makeRecipe(ciffile, grdata, iqdata): pdfprofile = Profile() pdfparser = PDFParser() pdfparser.parseFile(grdata) - pdfprofile.loadParsedData(pdfparser) + pdfprofile.load_parsed_data(pdfparser) pdfprofile.setCalculationRange(xmin=0.1, xmax=20) pdfcontribution = FitContribution("pdf") @@ -66,7 +66,7 @@ def makeRecipe(ciffile, grdata, iqdata): sasprofile = Profile() sasparser = SASParser() sasparser.parseFile(iqdata) - sasprofile.loadParsedData(sasparser) + sasprofile.load_parsed_data(sasparser) if all(sasprofile.dy == 0): sasprofile.dy[:] = 1 diff --git a/src/diffpy/srfit/fitbase/profile.py b/src/diffpy/srfit/fitbase/profile.py index 2600fb8f..98b40b80 100644 --- a/src/diffpy/srfit/fitbase/profile.py +++ b/src/diffpy/srfit/fitbase/profile.py @@ -29,9 +29,19 @@ from diffpy.srfit.fitbase.parameter import Parameter from diffpy.srfit.fitbase.validatable import Validatable from diffpy.srfit.util.observable import Observable +from diffpy.utils._deprecator import build_deprecation_message, deprecated # This is the roundoff tolerance for selecting bounds on arrays. epsilon = 1e-8 +base = "diffpy.srfit.fitbase.profile.Profile" +removal_version = "4.0.0" + +loadParsedData_dep_msg = build_deprecation_message( + base, + "loadParsedData", + "load_parsed_data", + removal_version, +) class Profile(Observable, Validatable): @@ -125,7 +135,7 @@ def __init__(self): yobs = property(lambda self: self._yobs) dyobs = property(lambda self: self._dyobs) - def loadParsedData(self, parser): + def load_parsed_data(self, parser): """Load parsed data from a ProfileParser. This sets the xobs, yobs, dyobs arrays as well as the metadata. @@ -135,6 +145,17 @@ def loadParsedData(self, parser): self.setObservedProfile(x, y, dy) return + @deprecated(loadParsedData_dep_msg) + def loadParsedData(self, parser): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.srfit.fitbase.profile.Profile.load_parsed_data + instead. + """ + self.load_parsed_data(parser) + return + def setObservedProfile(self, xobs, yobs, dyobs=None): """Set the observed profile. diff --git a/src/diffpy/srfit/pdf/pdfcontribution.py b/src/diffpy/srfit/pdf/pdfcontribution.py index 3f487a93..44083452 100644 --- a/src/diffpy/srfit/pdf/pdfcontribution.py +++ b/src/diffpy/srfit/pdf/pdfcontribution.py @@ -109,7 +109,7 @@ def loadData(self, data): """Load the data in various formats. This uses the PDFParser to load the data and then passes it to the - built-in profile with loadParsedData. + built-in profile with load_parsed_data. Attributes ---------- @@ -129,7 +129,7 @@ def loadData(self, data): parser.parseString(datstr) # Pass it to the profile - self.profile.loadParsedData(parser) + self.profile.load_parsed_data(parser) return def setCalculationRange(self, xmin=None, xmax=None, dx=None): diff --git a/tests/test_fitrecipe.py b/tests/test_fitrecipe.py index 571b0dab..5d419494 100644 --- a/tests/test_fitrecipe.py +++ b/tests/test_fitrecipe.py @@ -369,6 +369,27 @@ def build_recipe_from_datafile(datafile): profile = Profile() parser = PDFParser() parser.parseFile(str(datafile)) + profile.load_parsed_data(parser) + + contribution = FitContribution("c") + contribution.set_profile(profile) + contribution.set_equation("m*x + b") + recipe = FitRecipe() + recipe.add_contribution(contribution) + recipe.addVar(contribution.m, 1) + recipe.addVar(contribution.b, 0) + return recipe + + +def build_recipe_from_datafile_deprecated(datafile): + """Duplicate of build_recipe_from_datafile to use deprecated loadParsedData + method. + + Remove in version 4.0.0. + """ + profile = Profile() + parser = PDFParser() + parser.parseFile(str(datafile)) profile.loadParsedData(parser) contribution = FitContribution("c") @@ -647,6 +668,23 @@ def test_plot_recipe_labels_from_gr_file_overwrite(temp_data_files): assert actual_ylabel == expected_ylabel +def test_plot_recipe_labels_from_gr_file_overwrite_deprecated(temp_data_files): + "Remove this test with version 4.0.0." + gr_file = temp_data_files / "gr_file.gr" + recipe = build_recipe_from_datafile_deprecated(gr_file) + optimize_recipe(recipe) + plt.close("all") + fig, ax = recipe.plot_recipe( + return_fig=True, show=False, xlabel="My X", ylabel="My Y" + ) + actual_xlabel = ax.get_xlabel() + actual_ylabel = ax.get_ylabel() + expected_xlabel = "My X" + expected_ylabel = "My Y" + assert actual_xlabel == expected_xlabel + assert actual_ylabel == expected_ylabel + + def test_plot_recipe_reset_all_defaults(build_recipe_one_contribution): expected_defaults = { "show_observed": True, From bdd82f12524e1b312e9ee6bfb04084a467e21bcb Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 19 Feb 2026 16:20:16 -0500 Subject: [PATCH 3/8] deprecate Profile.setObservedProfile and SimpleRecipe.setObservedProfile --- docs/examples/debyemodel.py | 2 +- docs/source/extending.rst | 2 +- src/diffpy/srfit/fitbase/profile.py | 27 +++++++++++--- src/diffpy/srfit/fitbase/simplerecipe.py | 22 ++++++++++-- tests/conftest.py | 6 ++-- tests/test_contribution.py | 10 +++--- tests/test_fitrecipe.py | 6 ++-- tests/test_profile.py | 46 +++++++++++++++++++++--- 8 files changed, 97 insertions(+), 24 deletions(-) diff --git a/docs/examples/debyemodel.py b/docs/examples/debyemodel.py index eca6f15b..6a029998 100644 --- a/docs/examples/debyemodel.py +++ b/docs/examples/debyemodel.py @@ -93,7 +93,7 @@ def makeRecipe(): # data into the profile. xydy = numpy.array(data.split(), dtype=float).reshape(-1, 3) x, y, dy = xydy.T - profile.setObservedProfile(x, y, dy) + profile.set_observed_profile(x, y, dy) # The FitContribution # The FitContribution associates the profile with the Debye function. diff --git a/docs/source/extending.rst b/docs/source/extending.rst index a7a10be8..582add1d 100644 --- a/docs/source/extending.rst +++ b/docs/source/extending.rst @@ -185,7 +185,7 @@ customized Profile is the ``SASProfile`` class in the The ``__init__`` method sets the ``xobs``, ``yobs`` and ``dyobs`` attributes of the ``SASProfile`` to the associated arrays within the ``_datainfo`` attribute. -The ``setObservedProfile`` method is overloaded to modify the ``_datainfo`` +The ``set_observed_profile`` method is overloaded to modify the ``_datainfo`` arrays when their corresponding attributes are modified. This keeps the arrays in sync. diff --git a/src/diffpy/srfit/fitbase/profile.py b/src/diffpy/srfit/fitbase/profile.py index 98b40b80..13ed5dab 100644 --- a/src/diffpy/srfit/fitbase/profile.py +++ b/src/diffpy/srfit/fitbase/profile.py @@ -43,6 +43,13 @@ removal_version, ) +setObservedProfile_dep_msg = build_deprecation_message( + base, + "setObservedProfile", + "set_observed_profile", + removal_version, +) + class Profile(Observable, Validatable): """Observed and calculated profile container. @@ -142,7 +149,7 @@ def load_parsed_data(self, parser): """ x, y, junk, dy = parser.getData() self.meta = dict(parser.getMetaData()) - self.setObservedProfile(x, y, dy) + self.set_observed_profile(x, y, dy) return @deprecated(loadParsedData_dep_msg) @@ -156,7 +163,7 @@ def loadParsedData(self, parser): self.load_parsed_data(parser) return - def setObservedProfile(self, xobs, yobs, dyobs=None): + def set_observed_profile(self, xobs, yobs, dyobs=None): """Set the observed profile. Parameters @@ -194,6 +201,18 @@ def setObservedProfile(self, xobs, yobs, dyobs=None): return + @deprecated(setObservedProfile_dep_msg) + def setObservedProfile(self, xobs, yobs, dyobs=None): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use + diffpy.srfit.fitbase.profile.Profile.set_observed_profile + instead. + """ + self.set_observed_profile(xobs, yobs, dyobs) + return + def setCalculationRange(self, xmin=None, xmax=None, dx=None): """Set epsilon-inclusive calculation range. @@ -335,7 +354,7 @@ def loadtxt(self, *args, **kw): enforced. The first two arrays returned by numpy.loadtxt are assumed to be x and y. If there is a third array, it is assumed to by dy. Any other arrays are ignored. These are passed to - setObservedProfile. + set_observed_profile. Raises ValueError if the call to numpy.loadtxt returns fewer than 2 arrays. @@ -366,7 +385,7 @@ def loadtxt(self, *args, **kw): if len(cols) > 2: dy = cols[2] - self.setObservedProfile(x, y, dy) + self.set_observed_profile(x, y, dy) return x, y, dy def savetxt(self, fname, **kwargs): diff --git a/src/diffpy/srfit/fitbase/simplerecipe.py b/src/diffpy/srfit/fitbase/simplerecipe.py index 10bec267..5fc533a3 100644 --- a/src/diffpy/srfit/fitbase/simplerecipe.py +++ b/src/diffpy/srfit/fitbase/simplerecipe.py @@ -30,6 +30,13 @@ removal_version, ) +setObservedProfile_dep_msg = build_deprecation_message( + base, + "setObservedProfile", + "set_observed_profile", + removal_version, +) + class SimpleRecipe(FitRecipe): """SimpleRecipe class. @@ -138,7 +145,7 @@ def loadParsedData(self, parser): """ return self.load_parsed_data(parser) - def setObservedProfile(self, xobs, yobs, dyobs=None): + def set_observed_profile(self, xobs, yobs, dyobs=None): """Set the observed profile. Parameters @@ -158,6 +165,17 @@ def setObservedProfile(self, xobs, yobs, dyobs=None): """ return self.profile.setObservedProfile(xobs, yobs, dyobs) + @deprecated(setObservedProfile_dep_msg) + def setObservedProfile(self, xobs, yobs, dyobs=None): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use + diffpy.srfit.fitbase.simplerecipe.SimpleRecipe.set_observed_profile + instead. + """ + return self.set_observed_profile(xobs, yobs, dyobs) + def setCalculationRange(self, xmin=None, xmax=None, dx=None): """Set epsilon-inclusive calculation range. @@ -213,7 +231,7 @@ def loadtxt(self, *args, **kw): enforced. The first two arrays returned by numpy.loadtxt are assumed to be x and y. If there is a third array, it is assumed to by dy. Any other arrays are ignored. These are passed to - setObservedProfile. + set_observed_profile. Raises ValueError if the call to numpy.loadtxt returns fewer than 2 arrays. diff --git a/tests/conftest.py b/tests/conftest.py index d60e870e..5aec22ec 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -152,7 +152,7 @@ def build_recipe_one_contribution(): profile = Profile() x = linspace(0, pi, 10) y = sin(x) - profile.setObservedProfile(x, y) + profile.set_observed_profile(x, y) contribution = FitContribution("c1") contribution.set_profile(profile) contribution.set_equation("A*sin(k*x + c)") @@ -170,14 +170,14 @@ def build_recipe_two_contributions(): profile1 = Profile() x = linspace(0, pi, 10) y1 = sin(x) - profile1.setObservedProfile(x, y1) + profile1.set_observed_profile(x, y1) contribution1 = FitContribution("c1") contribution1.set_profile(profile1) contribution1.set_equation("A*sin(k*x + c)") profile2 = Profile() y2 = 0.5 * sin(2 * x) - profile2.setObservedProfile(x, y2) + profile2.set_observed_profile(x, y2) contribution2 = FitContribution("c2") contribution2.set_profile(profile2) contribution2.set_equation("B*sin(m*x + d)") diff --git a/tests/test_contribution.py b/tests/test_contribution.py index 2863ac62..1e7cabd2 100644 --- a/tests/test_contribution.py +++ b/tests/test_contribution.py @@ -101,7 +101,7 @@ def testInteraction(self): # create some data xobs = arange(0, 10, 0.5) yobs = xobs - profile.setObservedProfile(xobs, yobs) + profile.set_observed_profile(xobs, yobs) # Make sure this is where it's supposed to be self.assertTrue(gen.profile.xobs is xobs) @@ -123,11 +123,11 @@ def testReplacements(self): xobs = arange(0, 10, 0.5) yobs = xobs profile = self.profile - profile.setObservedProfile(xobs, yobs) + profile.set_observed_profile(xobs, yobs) xobs2 = arange(0, 10, 0.8) yobs2 = 0.5 * xobs2 profile2 = Profile() - profile2.setObservedProfile(xobs2, yobs2) + profile2.set_observed_profile(xobs2, yobs2) gen = self.gen # Validate equations @@ -217,7 +217,7 @@ def testResidual(noObserversInGlobalBuilders): # Let's create some data) xobs = arange(0, 10, 0.5) yobs = xobs - profile.setObservedProfile(xobs, yobs) + profile.set_observed_profile(xobs, yobs) # Check our fitting equation. assert np.array_equal(fc._eq(), gen(xobs)) @@ -249,7 +249,7 @@ def testResidual(noObserversInGlobalBuilders): assert fc._reseq._value is None xobs = arange(0, 10, 0.5) yobs = 9 * sin(xobs) - profile.setObservedProfile(xobs, yobs) + profile.set_observed_profile(xobs, yobs) assert fc._eq._value is None assert fc._reseq._value is None diff --git a/tests/test_fitrecipe.py b/tests/test_fitrecipe.py index 5d419494..2b0d1e1c 100644 --- a/tests/test_fitrecipe.py +++ b/tests/test_fitrecipe.py @@ -41,7 +41,7 @@ def setUp(self): self.profile = Profile() x = linspace(0, pi, 10) y = sin(x) - self.profile.setObservedProfile(x, y) + self.profile.set_observed_profile(x, y) # Set up the FitContribution self.fitcontribution = FitContribution("cont") @@ -258,7 +258,7 @@ def testPrintFitHook(capturestdout): profile = Profile() x = linspace(0, pi, 10) y = sin(x) - profile.setObservedProfile(x, y) + profile.set_observed_profile(x, y) # Set up the FitContribution fitcontribution = FitContribution("cont") @@ -306,7 +306,7 @@ def test_add_contribution(capturestdout): profile = Profile() x = linspace(0, pi, 10) y = sin(x) - profile.setObservedProfile(x, y) + profile.set_observed_profile(x, y) # Set up the FitContribution fitcontribution = FitContribution("cont") diff --git a/tests/test_profile.py b/tests/test_profile.py index 29da2162..30c95c53 100644 --- a/tests/test_profile.py +++ b/tests/test_profile.py @@ -43,8 +43,44 @@ def testInit(self): self.assertEqual(profile.meta, {}) return + def test_set_observed_profile(self): + """Test the set_observed_profile method.""" + # Make a profile with defined dy + + x = arange(0, 10, 0.1) + y = x + dy = x + + prof = self.profile + prof.set_observed_profile(x, y, dy) + + self.assertTrue(array_equal(x, prof.xobs)) + self.assertTrue(array_equal(y, prof.yobs)) + self.assertTrue(array_equal(dy, prof.dyobs)) + + # Make a profile with undefined dy + x = arange(0, 10, 0.1) + y = x + dy = None + + self.profile.set_observed_profile(x, y, dy) + + self.assertTrue(array_equal(x, prof.xobs)) + self.assertTrue(array_equal(y, prof.yobs)) + self.assertTrue(array_equal(ones_like(prof.xobs), prof.dyobs)) + + # Get the ranged profile to make sure its the same + self.assertTrue(array_equal(x, prof.x)) + self.assertTrue(array_equal(y, prof.y)) + self.assertTrue(array_equal(ones_like(prof.xobs), prof.dy)) + + return + def testSetObservedProfile(self): - """Test the setObservedProfile method.""" + """Test the deprecated setObservedProfile method. + + Remove this test when setObservedProfile is removed in 4.0.0. + """ # Make a profile with defined dy x = arange(0, 10, 0.1) @@ -52,7 +88,7 @@ def testSetObservedProfile(self): dy = x prof = self.profile - prof.setObservedProfile(x, y, dy) + prof.set_observed_profile(x, y, dy) self.assertTrue(array_equal(x, prof.xobs)) self.assertTrue(array_equal(y, prof.yobs)) @@ -88,7 +124,7 @@ def testSetCalculationRange(self): self.assertRaises(AttributeError, prof.setCalculationRange, 0, 5) self.assertRaises(AttributeError, prof.setCalculationRange, 0, 5, 0.2) # assign data - prof.setObservedProfile(x, y, dy) + prof.set_observed_profile(x, y, dy) # Test normal execution w/o arguments self.assertTrue(array_equal(x, prof.x)) self.assertTrue(array_equal(y, prof.y)) @@ -172,7 +208,7 @@ def testSetCalculationPoints(self): self.assertTrue(array_equal(xcalc, prof.x)) # Add the data. This should change the bounds of the calculation array. - prof.setObservedProfile(x, y, dy) + prof.set_observed_profile(x, y, dy) self.assertTrue(array_equal(arange(3, 10.1, 0.2), prof.x)) return @@ -183,7 +219,7 @@ def test_savetxt(self): self.assertRaises(SrFitError, prof.savetxt, "foo") xobs = arange(-2, 3.01, 0.25) yobs = xobs**2 - prof.setObservedProfile(xobs, yobs) + prof.set_observed_profile(xobs, yobs) prof.ycalc = yobs.copy() fp = io.BytesIO() prof.savetxt(fp) From 64ba047e343485739b42a765ba123f647302eb3f Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 19 Feb 2026 16:23:19 -0500 Subject: [PATCH 4/8] news --- news/profile-dep.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 news/profile-dep.rst diff --git a/news/profile-dep.rst b/news/profile-dep.rst new file mode 100644 index 00000000..d915194c --- /dev/null +++ b/news/profile-dep.rst @@ -0,0 +1,25 @@ +**Added:** + +* Added ``load_parsed_data`` in replace of ``loadParsedData`` in ``Profile`` and ``SimpleRecipe``. +* Added ``set_observed_profile`` in replace of ``setObservedProfile`` in ``Profile`` and ``SimpleRecipe``. + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``loadParsedData`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. +* Deprecated ``setObservedProfile`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From eef57415ab147112f695acbcf5a164211769ceca Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 19 Feb 2026 16:49:58 -0500 Subject: [PATCH 5/8] setCalculationRange --- docs/examples/coreshellnp.py | 2 +- docs/examples/crystalpdf.py | 2 +- docs/examples/crystalpdfall.py | 2 +- docs/examples/crystalpdfobjcryst.py | 2 +- docs/examples/crystalpdftwodata.py | 4 +- docs/examples/crystalpdftwophase.py | 2 +- docs/examples/debyemodelII.py | 8 +-- docs/examples/nppdfcrystal.py | 2 +- docs/examples/nppdfobjcryst.py | 2 +- docs/examples/nppdfsas.py | 2 +- docs/examples/simplepdf.py | 2 +- docs/examples/simplepdftwophase.py | 2 +- src/diffpy/srfit/fitbase/profile.py | 21 ++++++- src/diffpy/srfit/fitbase/simplerecipe.py | 23 +++++++- tests/test_profile.py | 73 ++++++++++++++++-------- 15 files changed, 104 insertions(+), 45 deletions(-) diff --git a/docs/examples/coreshellnp.py b/docs/examples/coreshellnp.py index 51860f3e..0ab04609 100644 --- a/docs/examples/coreshellnp.py +++ b/docs/examples/coreshellnp.py @@ -45,7 +45,7 @@ def makeRecipe(stru1, stru2, datname): parser = PDFParser() parser.parseFile(datname) profile.load_parsed_data(parser) - profile.setCalculationRange(xmin=1.5, xmax=45, dx=0.1) + profile.set_calculation_range(xmin=1.5, xmax=45, dx=0.1) # The ProfileGenerator # In order to fit the core and shell phases simultaneously, we must use two diff --git a/docs/examples/crystalpdf.py b/docs/examples/crystalpdf.py index 3fd9666e..4fbc50e4 100644 --- a/docs/examples/crystalpdf.py +++ b/docs/examples/crystalpdf.py @@ -56,7 +56,7 @@ def makeRecipe(ciffile, datname): parser = PDFParser() parser.parseFile(datname) profile.load_parsed_data(parser) - profile.setCalculationRange(xmax=20) + profile.set_calculation_range(xmax=20) # The ProfileGenerator # The PDFGenerator is for configuring and calculating a PDF profile. Here, diff --git a/docs/examples/crystalpdfall.py b/docs/examples/crystalpdfall.py index 8946dfe0..de325719 100644 --- a/docs/examples/crystalpdfall.py +++ b/docs/examples/crystalpdfall.py @@ -40,7 +40,7 @@ def makeProfile(datafile): parser = PDFParser() parser.parseFile(datafile) profile.load_parsed_data(parser) - profile.setCalculationRange(xmax=20) + profile.set_calculation_range(xmax=20) return profile diff --git a/docs/examples/crystalpdfobjcryst.py b/docs/examples/crystalpdfobjcryst.py index 70ef78d7..a4fdf23c 100644 --- a/docs/examples/crystalpdfobjcryst.py +++ b/docs/examples/crystalpdfobjcryst.py @@ -49,7 +49,7 @@ def makeRecipe(ciffile, datname): parser = PDFParser() parser.parseFile(datname) profile.load_parsed_data(parser) - profile.setCalculationRange(xmax=20) + profile.set_calculation_range(xmax=20) # The ProfileGenerator # This time we use the CreateCrystalFromCIF method of pyobjcryst.crystal to diff --git a/docs/examples/crystalpdftwodata.py b/docs/examples/crystalpdftwodata.py index 679dc693..eef737f0 100644 --- a/docs/examples/crystalpdftwodata.py +++ b/docs/examples/crystalpdftwodata.py @@ -49,12 +49,12 @@ def makeRecipe(ciffile, xdatname, ndatname): parser = PDFParser() parser.parseFile(xdatname) xprofile.load_parsed_data(parser) - xprofile.setCalculationRange(xmax=20) + xprofile.set_calculation_range(xmax=20) parser = PDFParser() parser.parseFile(ndatname) nprofile.load_parsed_data(parser) - nprofile.setCalculationRange(xmax=20) + nprofile.set_calculation_range(xmax=20) # The ProfileGenerators # We need one of these for the x-ray data. diff --git a/docs/examples/crystalpdftwophase.py b/docs/examples/crystalpdftwophase.py index 59a85743..7087a4db 100644 --- a/docs/examples/crystalpdftwophase.py +++ b/docs/examples/crystalpdftwophase.py @@ -46,7 +46,7 @@ def makeRecipe(niciffile, siciffile, datname): parser = PDFParser() parser.parseFile(datname) profile.load_parsed_data(parser) - profile.setCalculationRange(xmax=20) + profile.set_calculation_range(xmax=20) # The ProfileGenerator # In order to fit two phases simultaneously, we must use two PDFGenerators. diff --git a/docs/examples/debyemodelII.py b/docs/examples/debyemodelII.py index bc50fe54..fe686f0b 100644 --- a/docs/examples/debyemodelII.py +++ b/docs/examples/debyemodelII.py @@ -77,8 +77,8 @@ def makeRecipeII(): # Change the fit ranges of the Profiles embedded within the # FitContributions. We want to fit one of the contributions at low # temperature, and one at high. - lowT.profile.setCalculationRange(0, 150) - highT.profile.setCalculationRange(400, 500) + lowT.profile.set_calculation_range(0, 150) + highT.profile.set_calculation_range(400, 500) # Vary the offset from each FitContribution separately, while keeping the # Debye temperatures the same. We give each offset variable a different @@ -102,8 +102,8 @@ def plotResults(recipe): # We want to extend the fitting range to its full extent so we can get a # nice full plot. - recipe.lowT.profile.setCalculationRange(xmin="obs", xmax="obs") - recipe.highT.profile.setCalculationRange(xmin="obs", xmax="obs") + recipe.lowT.profile.set_calculation_range(xmin="obs", xmax="obs") + recipe.highT.profile.set_calculation_range(xmin="obs", xmax="obs") T = recipe.lowT.profile.x U = recipe.lowT.profile.y # We can use a FitContribution's 'evaluateEquation' method to evaluate diff --git a/docs/examples/nppdfcrystal.py b/docs/examples/nppdfcrystal.py index c4bffaa1..df64c109 100644 --- a/docs/examples/nppdfcrystal.py +++ b/docs/examples/nppdfcrystal.py @@ -45,7 +45,7 @@ def makeRecipe(ciffile, grdata): pdfparser = PDFParser() pdfparser.parseFile(grdata) pdfprofile.load_parsed_data(pdfparser) - pdfprofile.setCalculationRange(xmin=0.1, xmax=20) + pdfprofile.set_calculation_range(xmin=0.1, xmax=20) pdfcontribution = FitContribution("pdf") pdfcontribution.set_profile(pdfprofile, xname="r") diff --git a/docs/examples/nppdfobjcryst.py b/docs/examples/nppdfobjcryst.py index e77a5a95..45ac1be6 100644 --- a/docs/examples/nppdfobjcryst.py +++ b/docs/examples/nppdfobjcryst.py @@ -40,7 +40,7 @@ def makeRecipe(molecule, datname): # Load data and add it to the profile profile.loadtxt(datname) - profile.setCalculationRange(xmin=1.2, xmax=8) + profile.set_calculation_range(xmin=1.2, xmax=8) # The ProfileGenerator # Create a DebyePDFGenerator named "G". diff --git a/docs/examples/nppdfsas.py b/docs/examples/nppdfsas.py index 6eff4b31..77688709 100644 --- a/docs/examples/nppdfsas.py +++ b/docs/examples/nppdfsas.py @@ -49,7 +49,7 @@ def makeRecipe(ciffile, grdata, iqdata): pdfparser = PDFParser() pdfparser.parseFile(grdata) pdfprofile.load_parsed_data(pdfparser) - pdfprofile.setCalculationRange(xmin=0.1, xmax=20) + pdfprofile.set_calculation_range(xmin=0.1, xmax=20) pdfcontribution = FitContribution("pdf") pdfcontribution.set_profile(pdfprofile, xname="r") diff --git a/docs/examples/simplepdf.py b/docs/examples/simplepdf.py index 4574a5d7..ffe69dd4 100644 --- a/docs/examples/simplepdf.py +++ b/docs/examples/simplepdf.py @@ -35,7 +35,7 @@ def makeRecipe(ciffile, datname): # Work directly with a custom PDFContribution to load the data contribution = PDFContribution("nickel") contribution.loadData(datname) - contribution.setCalculationRange(xmin=1, xmax=20, dx=0.1) + contribution.set_calculation_range(xmin=1, xmax=20, dx=0.1) # and the phase stru = Structure() diff --git a/docs/examples/simplepdftwophase.py b/docs/examples/simplepdftwophase.py index e00ae302..134d8855 100644 --- a/docs/examples/simplepdftwophase.py +++ b/docs/examples/simplepdftwophase.py @@ -31,7 +31,7 @@ def makeRecipe(niciffile, siciffile, datname): # Load data and add it to the profile contribution = PDFContribution("nisi") contribution.loadData(datname) - contribution.setCalculationRange(xmax=20) + contribution.set_calculation_range(xmax=20) stru = loadCrystal(niciffile) contribution.addStructure("ni", stru) diff --git a/src/diffpy/srfit/fitbase/profile.py b/src/diffpy/srfit/fitbase/profile.py index 13ed5dab..aaf13a44 100644 --- a/src/diffpy/srfit/fitbase/profile.py +++ b/src/diffpy/srfit/fitbase/profile.py @@ -50,6 +50,13 @@ removal_version, ) +setCalculationRange_dep_msg = build_deprecation_message( + base, + "setCalculationRange", + "set_calculation_range", + removal_version, +) + class Profile(Observable, Validatable): """Observed and calculated profile container. @@ -213,7 +220,7 @@ def setObservedProfile(self, xobs, yobs, dyobs=None): self.set_observed_profile(xobs, yobs, dyobs) return - def setCalculationRange(self, xmin=None, xmax=None, dx=None): + def set_calculation_range(self, xmin=None, xmax=None, dx=None): """Set epsilon-inclusive calculation range. Adhere to the observed ``xobs`` points when ``dx`` is the same @@ -317,6 +324,18 @@ def _isobs(a): self.setCalculationPoints(x1) return + @deprecated(setCalculationRange_dep_msg) + def setCalculationRange(self, xmin=None, xmax=None, dx=None): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use + diffpy.srfit.fitbase.profile.Profile.set_calculation_range + instead. + """ + self.set_calculation_range(xmin, xmax, dx) + return + def setCalculationPoints(self, x): """Set the calculation points. diff --git a/src/diffpy/srfit/fitbase/simplerecipe.py b/src/diffpy/srfit/fitbase/simplerecipe.py index 5fc533a3..6e9b7919 100644 --- a/src/diffpy/srfit/fitbase/simplerecipe.py +++ b/src/diffpy/srfit/fitbase/simplerecipe.py @@ -37,6 +37,13 @@ removal_version, ) +setCalculationRange_dep_msg = build_deprecation_message( + base, + "setCalculationRange", + "set_calculation_range", + removal_version, +) + class SimpleRecipe(FitRecipe): """SimpleRecipe class. @@ -163,7 +170,7 @@ def set_observed_profile(self, xobs, yobs, dyobs=None): Raises ValueError if len(yobs) != len(xobs) Raises ValueError if dyobs != None and len(dyobs) != len(xobs) """ - return self.profile.setObservedProfile(xobs, yobs, dyobs) + return self.profile.set_observed_profile(xobs, yobs, dyobs) @deprecated(setObservedProfile_dep_msg) def setObservedProfile(self, xobs, yobs, dyobs=None): @@ -176,7 +183,7 @@ def setObservedProfile(self, xobs, yobs, dyobs=None): """ return self.set_observed_profile(xobs, yobs, dyobs) - def setCalculationRange(self, xmin=None, xmax=None, dx=None): + def set_calculation_range(self, xmin=None, xmax=None, dx=None): """Set epsilon-inclusive calculation range. Adhere to the observed ``xobs`` points when ``dx`` is the same @@ -208,7 +215,17 @@ def setCalculationRange(self, xmin=None, xmax=None, dx=None): ValueError When xmin > xmax or if dx <= 0. Also if dx > xmax - xmin. """ - return self.profile.setCalculationRange(xmin, xmax, dx) + return self.profile.set_calculation_range(xmin, xmax, dx) + + def setCalculationRange(self, xmin=None, xmax=None, dx=None): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use + diffpy.srfit.fitbase.simplerecipe.SimpleRecipe.set_calculation_range + instead. + """ + return self.set_calculation_range(xmin, xmax, dx) def setCalculationPoints(self, x): """Set the calculation points. diff --git a/tests/test_profile.py b/tests/test_profile.py index 30c95c53..25722dad 100644 --- a/tests/test_profile.py +++ b/tests/test_profile.py @@ -112,88 +112,111 @@ def testSetObservedProfile(self): return - def testSetCalculationRange(self): - """Test the setCalculationRange method.""" + def test_set_calculation_range(self): + """Test the set_calculation_range method.""" x = arange(2, 9.6, 0.5) y = array(x) dy = array(x) prof = self.profile # Check call before data arrays are present - self.assertRaises(AttributeError, prof.setCalculationRange) - self.assertRaises(AttributeError, prof.setCalculationRange, 0) - self.assertRaises(AttributeError, prof.setCalculationRange, 0, 5) - self.assertRaises(AttributeError, prof.setCalculationRange, 0, 5, 0.2) + self.assertRaises(AttributeError, prof.set_calculation_range) + self.assertRaises(AttributeError, prof.set_calculation_range, 0) + self.assertRaises(AttributeError, prof.set_calculation_range, 0, 5) + self.assertRaises( + AttributeError, prof.set_calculation_range, 0, 5, 0.2 + ) # assign data prof.set_observed_profile(x, y, dy) # Test normal execution w/o arguments self.assertTrue(array_equal(x, prof.x)) self.assertTrue(array_equal(y, prof.y)) self.assertTrue(array_equal(dy, prof.dy)) - prof.setCalculationRange() + prof.set_calculation_range() self.assertTrue(array_equal(x, prof.x)) self.assertTrue(array_equal(y, prof.y)) self.assertTrue(array_equal(dy, prof.dy)) # Test a lower bound < xmin - prof.setCalculationRange(xmin=0) + prof.set_calculation_range(xmin=0) self.assertTrue(array_equal(x, prof.x)) self.assertTrue(array_equal(y, prof.y)) self.assertTrue(array_equal(dy, prof.dy)) # Test an upper bound > xmax - prof.setCalculationRange(xmax=100) + prof.set_calculation_range(xmax=100) self.assertTrue(array_equal(x, prof.x)) self.assertTrue(array_equal(y, prof.y)) self.assertTrue(array_equal(dy, prof.dy)) # Test xmin > xmax self.assertRaises( - ValueError, prof.setCalculationRange, xmin=10, xmax=3 + ValueError, prof.set_calculation_range, xmin=10, xmax=3 ) # Test xmax - xmin < dx self.assertRaises( - ValueError, prof.setCalculationRange, xmin=3, xmax=3.9, dx=1.0 + ValueError, prof.set_calculation_range, xmin=3, xmax=3.9, dx=1.0 ) # Test dx <= 0 - self.assertRaises(ValueError, prof.setCalculationRange, dx=0) - self.assertRaises(ValueError, prof.setCalculationRange, dx=-0.000001) + self.assertRaises(ValueError, prof.set_calculation_range, dx=0) + self.assertRaises(ValueError, prof.set_calculation_range, dx=-0.000001) # using string other than 'obs' - self.assertRaises(ValueError, prof.setCalculationRange, xmin="oobs") - self.assertRaises(ValueError, prof.setCalculationRange, xmax="oobs") - self.assertRaises(ValueError, prof.setCalculationRange, dx="oobs") + self.assertRaises(ValueError, prof.set_calculation_range, xmin="oobs") + self.assertRaises(ValueError, prof.set_calculation_range, xmax="oobs") + self.assertRaises(ValueError, prof.set_calculation_range, dx="oobs") # This should be alright - prof.setCalculationRange(3, 5) - prof.setCalculationRange(xmin="obs", xmax=7, dx=0.001) + prof.set_calculation_range(3, 5) + prof.set_calculation_range(xmin="obs", xmax=7, dx=0.001) self.assertEqual(5001, len(prof.x)) self.assertEqual(len(prof.x), len(prof.y)) self.assertEqual(len(prof.x), len(prof.dy)) # Test an internal bound - prof.setCalculationRange(4, 7, dx="obs") + prof.set_calculation_range(4, 7, dx="obs") self.assertTrue(array_equal(prof.x, arange(4, 7.1, 0.5))) self.assertTrue(array_equal(prof.y, arange(4, 7.1, 0.5))) self.assertTrue(array_equal(prof.y, arange(4, 7.1, 0.5))) # test setting only one of the bounds - prof.setCalculationRange(xmin=3) + prof.set_calculation_range(xmin=3) self.assertTrue(array_equal(prof.x, arange(3, 7.1, 0.5))) self.assertTrue(array_equal(prof.x, prof.y)) self.assertTrue(array_equal(prof.x, prof.dy)) - prof.setCalculationRange(xmax=5.1) + prof.set_calculation_range(xmax=5.1) self.assertTrue(array_equal(prof.x, arange(3, 5.1, 0.5))) self.assertTrue(array_equal(prof.x, prof.y)) self.assertTrue(array_equal(prof.x, prof.dy)) - prof.setCalculationRange(dx=1) + prof.set_calculation_range(dx=1) self.assertTrue(array_equal(prof.x, arange(3, 5.1))) self.assertTrue(array_equal(prof.x, prof.y)) self.assertTrue(array_equal(prof.x, prof.dy)) # Test a new grid - prof.setCalculationRange(4.2, 7, 0.3) + prof.set_calculation_range(4.2, 7, 0.3) self.assertTrue(array_equal(prof.x, arange(4.2, 6.901, 0.3))) self.assertTrue(allclose(prof.x, prof.y)) self.assertTrue(allclose(prof.x, prof.dy)) - prof.setCalculationRange(xmin=4.2, xmax=6.001) + prof.set_calculation_range(xmin=4.2, xmax=6.001) self.assertTrue(array_equal(prof.x, arange(4.2, 6.001, 0.3))) # resample on a clipped grid - prof.setCalculationRange(dx=0.5) + prof.set_calculation_range(dx=0.5) self.assertTrue(array_equal(prof.x, arange(4.5, 6.1, 0.5))) return + def testSetCalculationRange(self): + """Test the deprecated setCalculationRange method. + + Remove this test when setCalculationRange is removed in 4.0.0. + """ + x = arange(2, 9.6, 0.5) + y = array(x) + dy = array(x) + prof = self.profile + prof.set_observed_profile(x, y, dy) + prof.setCalculationRange() + # Test normal execution w/o arguments + self.assertTrue(array_equal(x, prof.x)) + self.assertTrue(array_equal(y, prof.y)) + self.assertTrue(array_equal(dy, prof.dy)) + prof.setCalculationRange() + self.assertTrue(array_equal(x, prof.x)) + self.assertTrue(array_equal(y, prof.y)) + self.assertTrue(array_equal(dy, prof.dy)) + return + def testSetCalculationPoints(self): """Test the setCalculationPoints method.""" prof = self.profile From 80d0f4b11f9f271a740652c24e8c78901001b771 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 19 Feb 2026 17:06:25 -0500 Subject: [PATCH 6/8] setCalculationPoints --- news/profile-dep.rst | 2 ++ src/diffpy/srfit/fitbase/profile.py | 31 +++++++++++++++++++++--- src/diffpy/srfit/fitbase/simplerecipe.py | 22 +++++++++++++++-- src/diffpy/srfit/pdf/pdfcontribution.py | 2 +- tests/test_profile.py | 25 +++++++++++++++++-- tests/test_profilegenerator.py | 6 ++--- 6 files changed, 76 insertions(+), 12 deletions(-) diff --git a/news/profile-dep.rst b/news/profile-dep.rst index d915194c..cd0f322e 100644 --- a/news/profile-dep.rst +++ b/news/profile-dep.rst @@ -2,6 +2,7 @@ * Added ``load_parsed_data`` in replace of ``loadParsedData`` in ``Profile`` and ``SimpleRecipe``. * Added ``set_observed_profile`` in replace of ``setObservedProfile`` in ``Profile`` and ``SimpleRecipe``. +* Added ``set_calculation_range`` in replace of ``setCalculationRange`` in ``Profile`` and ``SimpleRecipe``. **Changed:** @@ -11,6 +12,7 @@ * Deprecated ``loadParsedData`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. * Deprecated ``setObservedProfile`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. +* Deprecated ``setCalculationRange`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. **Removed:** diff --git a/src/diffpy/srfit/fitbase/profile.py b/src/diffpy/srfit/fitbase/profile.py index aaf13a44..f00f2712 100644 --- a/src/diffpy/srfit/fitbase/profile.py +++ b/src/diffpy/srfit/fitbase/profile.py @@ -57,6 +57,13 @@ removal_version, ) +setCalculationPoints_dep_msg = build_deprecation_message( + base, + "setCalculationPoints", + "set_calculation_points", + removal_version, +) + class Profile(Observable, Validatable): """Observed and calculated profile container. @@ -202,9 +209,9 @@ def set_observed_profile(self, xobs, yobs, dyobs=None): # Set the default calculation points if self.x is None: - self.setCalculationPoints(self._xobs) + self.set_calculation_points(self._xobs) else: - self.setCalculationPoints(self.x) + self.set_calculation_points(self.x) return @@ -321,7 +328,7 @@ def _isobs(a): self.dy = self.dyobs[indices] else: x1 = numpy.arange(lo, hi + epshi, step) - self.setCalculationPoints(x1) + self.set_calculation_points(x1) return @deprecated(setCalculationRange_dep_msg) @@ -336,7 +343,7 @@ def setCalculationRange(self, xmin=None, xmax=None, dx=None): self.set_calculation_range(xmin, xmax, dx) return - def setCalculationPoints(self, x): + def set_calculation_points(self, x): """Set the calculation points. Parameters @@ -366,6 +373,22 @@ def setCalculationPoints(self, x): return + @deprecated(setCalculationPoints_dep_msg) + def setCalculationPoints(self, x): + """Set the calculation points. + + Parameters + ---------- + x + A non-empty numpy array containing the calculation points. If + xobs exists, the bounds of x will be limited to its bounds. + + This will create y and dy on the specified grid if xobs, yobs and + dyobs exist. + """ + self.set_calculation_points(x) + return + def loadtxt(self, *args, **kw): """Use numpy.loadtxt to load data. diff --git a/src/diffpy/srfit/fitbase/simplerecipe.py b/src/diffpy/srfit/fitbase/simplerecipe.py index 6e9b7919..da4aadd8 100644 --- a/src/diffpy/srfit/fitbase/simplerecipe.py +++ b/src/diffpy/srfit/fitbase/simplerecipe.py @@ -44,6 +44,13 @@ removal_version, ) +setCalculationPoints_dep_msg = build_deprecation_message( + base, + "setCalculationPoints", + "set_calculation_points", + removal_version, +) + class SimpleRecipe(FitRecipe): """SimpleRecipe class. @@ -227,7 +234,7 @@ def setCalculationRange(self, xmin=None, xmax=None, dx=None): """ return self.set_calculation_range(xmin, xmax, dx) - def setCalculationPoints(self, x): + def set_calculation_points(self, x): """Set the calculation points. Parameters @@ -239,7 +246,18 @@ def setCalculationPoints(self, x): This will create y and dy on the specified grid if xobs, yobs and dyobs exist. """ - return self.profile.setCalculationPoints(x) + return self.profile.set_calculation_points(x) + + @deprecated(setCalculationPoints_dep_msg) + def setCalculationPoints(self, x): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use + diffpy.srfit.fitbase.simplerecipe.SimpleRecipe.set_calculation_points + instead. + """ + return self.set_calculation_points(x) def loadtxt(self, *args, **kw): """Use numpy.loadtxt to load data. diff --git a/src/diffpy/srfit/pdf/pdfcontribution.py b/src/diffpy/srfit/pdf/pdfcontribution.py index 44083452..9b2bdd93 100644 --- a/src/diffpy/srfit/pdf/pdfcontribution.py +++ b/src/diffpy/srfit/pdf/pdfcontribution.py @@ -164,7 +164,7 @@ def setCalculationRange(self, xmin=None, xmax=None, dx=None): ValueError When xmin > xmax or if dx <= 0. Also if dx > xmax - xmin. """ - return self.profile.setCalculationRange(xmin, xmax, dx) + return self.profile.set_calculation_range(xmin, xmax, dx) def savetxt(self, fname, **kwargs): """Call numpy.savetxt with x, ycalc, y, dy. diff --git a/tests/test_profile.py b/tests/test_profile.py index 25722dad..f8c186b4 100644 --- a/tests/test_profile.py +++ b/tests/test_profile.py @@ -206,7 +206,6 @@ def testSetCalculationRange(self): dy = array(x) prof = self.profile prof.set_observed_profile(x, y, dy) - prof.setCalculationRange() # Test normal execution w/o arguments self.assertTrue(array_equal(x, prof.x)) self.assertTrue(array_equal(y, prof.y)) @@ -217,8 +216,30 @@ def testSetCalculationRange(self): self.assertTrue(array_equal(dy, prof.dy)) return + def test_set_calculation_points(self): + """Test the set_calculation_points method.""" + prof = self.profile + + x = arange(2, 10.5, 0.5) + y = array(x) + dy = array(x) + + # Test without data + xcalc = arange(3, 12.2, 0.2) + prof.set_calculation_points(xcalc) + self.assertTrue(array_equal(xcalc, prof.x)) + + # Add the data. This should change the bounds of the calculation array. + prof.set_observed_profile(x, y, dy) + self.assertTrue(array_equal(arange(3, 10.1, 0.2), prof.x)) + + return + def testSetCalculationPoints(self): - """Test the setCalculationPoints method.""" + """Test the deprecated setCalculationPoints method. + + Remove this test when setCalculationPoints is removed in 4.0.0. + """ prof = self.profile x = arange(2, 10.5, 0.5) diff --git a/tests/test_profilegenerator.py b/tests/test_profilegenerator.py index 14612a93..aeacf690 100644 --- a/tests/test_profilegenerator.py +++ b/tests/test_profilegenerator.py @@ -29,7 +29,7 @@ def setUp(self): self.gen = ProfileGenerator("test") self.profile = Profile() x = arange(0, 10, 0.1) - self.profile.setCalculationPoints(x) + self.profile.set_calculation_points(x) self.gen.set_profile(self.profile) return @@ -55,7 +55,7 @@ def testUpdate(self): # Make sure attributes get updated with a change in the calculation # points. x = arange(0, 9, 0.1) - prof.setCalculationPoints(x) + prof.set_calculation_points(x) self.assertTrue(gen._value is None) val = gen.value self.assertTrue(array_equal(x, val)) @@ -68,7 +68,7 @@ def testUpdate(self): # Make sure attributes get updated with a new profile. x = arange(0, 8, 0.1) prof = Profile() - prof.setCalculationPoints(x) + prof.set_calculation_points(x) gen.set_profile(prof) self.assertTrue(gen._value is None) self.assertTrue(array_equal(x, gen.value)) From 36957e024a01a0cf0540144ff1b66bd445bb0087 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 19 Feb 2026 17:08:00 -0500 Subject: [PATCH 7/8] change rebinArray to rebin_array --- news/profile-dep.rst | 2 ++ src/diffpy/srfit/fitbase/profile.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/news/profile-dep.rst b/news/profile-dep.rst index cd0f322e..48424bcd 100644 --- a/news/profile-dep.rst +++ b/news/profile-dep.rst @@ -3,6 +3,7 @@ * Added ``load_parsed_data`` in replace of ``loadParsedData`` in ``Profile`` and ``SimpleRecipe``. * Added ``set_observed_profile`` in replace of ``setObservedProfile`` in ``Profile`` and ``SimpleRecipe``. * Added ``set_calculation_range`` in replace of ``setCalculationRange`` in ``Profile`` and ``SimpleRecipe``. +* Added ``set_calculation_points`` in replace of ``setCalculationPoints`` in ``Profile`` and ``SimpleRecipe``. **Changed:** @@ -13,6 +14,7 @@ * Deprecated ``loadParsedData`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. * Deprecated ``setObservedProfile`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. * Deprecated ``setCalculationRange`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. +* Deprecated ``setCalculationPoints`` in ``Profile`` and ``SimpleRecipe`` for removal in 4.0.0. **Removed:** diff --git a/src/diffpy/srfit/fitbase/profile.py b/src/diffpy/srfit/fitbase/profile.py index f00f2712..c7f94ee7 100644 --- a/src/diffpy/srfit/fitbase/profile.py +++ b/src/diffpy/srfit/fitbase/profile.py @@ -361,7 +361,7 @@ def set_calculation_points(self, x): x = x[x <= self.xobs[-1] + epsilon] self.x = x if self.yobs is not None: - self.y = rebinArray(self.yobs, self.xobs, self.x) + self.y = rebin_array(self.yobs, self.xobs, self.x) if self.dyobs is not None: # work around for interpolation issue making some of these non-1 if (self.dyobs == 1).all(): @@ -369,7 +369,7 @@ def set_calculation_points(self, x): else: # FIXME - This does not follow error propagation rules and it # introduces (more) correlation between the data points. - self.dy = rebinArray(self.dyobs, self.xobs, self.x) + self.dy = rebin_array(self.dyobs, self.xobs, self.x) return @@ -500,7 +500,7 @@ def _validate(self): # End class Profile -def rebinArray(A, xold, xnew): +def rebin_array(A, xold, xnew): """Rebin the an array by interpolating over the new x range. Parameters From 7443c6a8bd882b925cb7588f384f978655e331a7 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 19 Feb 2026 17:24:27 -0500 Subject: [PATCH 8/8] make _rebin_array private --- src/diffpy/srfit/fitbase/profile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diffpy/srfit/fitbase/profile.py b/src/diffpy/srfit/fitbase/profile.py index c7f94ee7..ae4e896b 100644 --- a/src/diffpy/srfit/fitbase/profile.py +++ b/src/diffpy/srfit/fitbase/profile.py @@ -361,7 +361,7 @@ def set_calculation_points(self, x): x = x[x <= self.xobs[-1] + epsilon] self.x = x if self.yobs is not None: - self.y = rebin_array(self.yobs, self.xobs, self.x) + self.y = _rebin_array(self.yobs, self.xobs, self.x) if self.dyobs is not None: # work around for interpolation issue making some of these non-1 if (self.dyobs == 1).all(): @@ -369,7 +369,7 @@ def set_calculation_points(self, x): else: # FIXME - This does not follow error propagation rules and it # introduces (more) correlation between the data points. - self.dy = rebin_array(self.dyobs, self.xobs, self.x) + self.dy = _rebin_array(self.dyobs, self.xobs, self.x) return @@ -500,7 +500,7 @@ def _validate(self): # End class Profile -def rebin_array(A, xold, xnew): +def _rebin_array(A, xold, xnew): """Rebin the an array by interpolating over the new x range. Parameters