Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/examples/coreshellnp.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

from pathlib import Path

from pyobjcryst import loadCrystal
from pyobjcryst.crystal import create_crystal_from_cif
from scipy.optimize import leastsq

from diffpy.srfit.fitbase import (
Expand Down Expand Up @@ -94,7 +94,7 @@ def makeRecipe(stru1, stru2, datname):
# diameter to twice the shell radius.
recipe.add_variable(contribution.radius, 15)
recipe.add_variable(contribution.thickness, 11)
recipe.add_constraint(contribution.psize, "2 * radius")
recipe.add_constraint(contribution.particle_diameter, "2 * radius")

# Configure the fit variables
# Start by configuring the scale factor and resolution factors.
Expand Down Expand Up @@ -152,8 +152,8 @@ def main():
data = Path(__file__).parent / "data/CdS_ZnS_nano.gr"

# Make the recipe
stru1 = loadCrystal(cdsciffile)
stru2 = loadCrystal(znsciffile)
stru1 = create_crystal_from_cif(str(cdsciffile))
stru2 = create_crystal_from_cif(str(znsciffile))
recipe = makeRecipe(stru1, stru2, data)
from diffpy.srfit.fitbase.fithook import PlotFitHook

Expand Down
6 changes: 3 additions & 3 deletions docs/examples/crystalpdfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from pathlib import Path

from gaussianrecipe import scipyOptimize
from pyobjcryst import loadCrystal
from pyobjcryst.crystal import create_crystal_from_cif

from diffpy.srfit.fitbase import (
FitContribution,
Expand Down Expand Up @@ -67,12 +67,12 @@ def makeRecipe(
# The ProfileGenerators
# We create one for each phase and share the phases.
xgenerator_ni = PDFGenerator("xG_ni")
stru = loadCrystal(ciffile_ni)
stru = create_crystal_from_cif(str(ciffile_ni))
xgenerator_ni.setStructure(stru)
phase_ni = xgenerator_ni.phase

xgenerator_si = PDFGenerator("xG_si")
stru = loadCrystal(ciffile_si)
stru = create_crystal_from_cif(str(ciffile_si))
xgenerator_si.setStructure(stru)
phase_si = xgenerator_si.phase

Expand Down
4 changes: 2 additions & 2 deletions docs/examples/crystalpdfobjcryst.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from pathlib import Path

from gaussianrecipe import scipyOptimize
from pyobjcryst import loadCrystal
from pyobjcryst.crystal import create_crystal_from_cif

from diffpy.srfit.fitbase import (
FitContribution,
Expand Down Expand Up @@ -56,7 +56,7 @@ def makeRecipe(ciffile, datname):
# create a Crystal object. That object is passed to the PDFGenerator as in
# the previous example.
generator = PDFGenerator("G")
stru = loadCrystal(ciffile)
stru = create_crystal_from_cif(str(ciffile))
generator.setStructure(stru)
generator.setQmax(40.0)

Expand Down
4 changes: 2 additions & 2 deletions docs/examples/crystalpdftwodata.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from pathlib import Path

from gaussianrecipe import scipyOptimize
from pyobjcryst import loadCrystal
from pyobjcryst.crystal import create_crystal_from_cif

from diffpy.srfit.fitbase import (
FitContribution,
Expand Down Expand Up @@ -59,7 +59,7 @@ def makeRecipe(ciffile, xdatname, ndatname):
# The ProfileGenerators
# We need one of these for the x-ray data.
xgenerator = PDFGenerator("G")
stru = loadCrystal(ciffile)
stru = create_crystal_from_cif(str(ciffile))
xgenerator.setStructure(stru)

# And we need one for the neutron data. We want to refine the same
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/crystalpdftwophase.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from pathlib import Path

from gaussianrecipe import scipyOptimize
from pyobjcryst import loadCrystal
from pyobjcryst.crystal import create_crystal_from_cif

from diffpy.srfit.fitbase import (
FitContribution,
Expand Down Expand Up @@ -61,11 +61,11 @@ def makeRecipe(niciffile, siciffile, datname):
# The generator for the nickel phase. We call it "G_ni" and will use this
# name later when we set the fitting equation in the FitContribution.
generator_ni = PDFGenerator("G_ni")
stru = loadCrystal(niciffile)
stru = create_crystal_from_cif(str(niciffile))
generator_ni.setStructure(stru)
# The generator for the silicon phase. We call it "G_si".
generator_si = PDFGenerator("G_si")
stru = loadCrystal(siciffile)
stru = create_crystal_from_cif(str(siciffile))
generator_si.setStructure(stru)

# The FitContribution
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/gaussianrecipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def scipyOptimize(recipe):
# scipy. We simply have to give it the function to minimize
# (recipe.residual) and the starting values of the Variables
# (recipe.get_values()).
from scipy.optimize.minpack import leastsq
from scipy.optimize import leastsq

print("Fit using scipy's LM optimizer")
leastsq(recipe.residual, recipe.get_values())
Expand Down
8 changes: 4 additions & 4 deletions docs/examples/nppdfcrystal.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

import matplotlib.pyplot as plt
from gaussianrecipe import scipyOptimize
from pyobjcryst import loadCrystal
from pyobjcryst.crystal import create_crystal_from_cif

from diffpy.srfit.fitbase import (
FitContribution,
Expand All @@ -53,7 +53,7 @@ def makeRecipe(ciffile, grdata):

pdfgenerator = PDFGenerator("G")
pdfgenerator.setQmax(30.0)
stru = loadCrystal(ciffile)
stru = create_crystal_from_cif(str(ciffile))
pdfgenerator.setStructure(stru)
pdfcontribution.add_profile_generator(pdfgenerator)

Expand All @@ -66,15 +66,15 @@ def makeRecipe(ciffile, grdata):
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.
# parameters, in this case 'particle_diameter'.
recipe = FitRecipe()
recipe.add_contribution(pdfcontribution)

phase = pdfgenerator.phase
for par in phase.sgpars:
recipe.add_variable(par)

recipe.add_variable(pdfcontribution.psize, 20)
recipe.add_variable(pdfcontribution.particle_diameter, 20)
recipe.add_variable(pdfgenerator.scale, 1)
recipe.add_variable(pdfgenerator.delta2, 0)
recipe.B11_0 = 0.1
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/nppdfsas.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

import matplotlib.pyplot as plt
from gaussianrecipe import scipyOptimize
from pyobjcryst import loadCrystal
from pyobjcryst.crystal import create_crystal_from_cif

from diffpy.srfit.fitbase import (
FitContribution,
Expand Down Expand Up @@ -58,7 +58,7 @@ def makeRecipe(ciffile, grdata, iqdata):

pdfgenerator = PDFGenerator("G")
pdfgenerator.setQmax(30.0)
stru = loadCrystal(ciffile)
stru = create_crystal_from_cif(str(ciffile))
pdfgenerator.setStructure(stru)
pdfcontribution.add_profile_generator(pdfgenerator)
pdfcontribution.set_residual_equation("resv")
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/simplepdftwophase.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from pathlib import Path

from gaussianrecipe import scipyOptimize
from pyobjcryst import loadCrystal
from pyobjcryst.crystal import create_crystal_from_cif

from diffpy.srfit.fitbase import FitRecipe, FitResults
from diffpy.srfit.pdf import PDFContribution
Expand All @@ -33,10 +33,10 @@ def makeRecipe(niciffile, siciffile, datname):
contribution.loadData(datname)
contribution.set_calculation_range(xmax=20)

stru = loadCrystal(niciffile)
stru = create_crystal_from_cif(str(niciffile))
contribution.addStructure("ni", stru)

stru = loadCrystal(siciffile)
stru = create_crystal_from_cif(str(siciffile))
contribution.addStructure("si", stru)

# Make the FitRecipe and add the FitContribution.
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/threedoublepeaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def scipyOptimize(recipe):
# scipy. We simply have to give it the function to minimize
# (recipe.residual) and the starting values of the Variables
# (recipe.get_values()).
from scipy.optimize.minpack import leastsq
from scipy.optimize import leastsq

print("Fit using scipy's LM optimizer")
leastsq(recipe.residual, recipe.get_values())
Expand Down
1 change: 1 addition & 0 deletions docs/source/api/diffpy.srfit.interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ diffpy.srfit.interface.interface module
.. automodule:: diffpy.srfit.interface.interface
:members:
:undoc-members:
:special-members: __lshift__, __imul__, __imod__, __iadd__, __ior__
:show-inheritance:
25 changes: 25 additions & 0 deletions news/fix-structure-deprecations.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**Added:**

* Document the ``*=``, ``%=``, ``+=``, ``|=``, and ``<<`` shorthand operators in the ``diffpy.srfit.interface`` API reference.

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* Use ``get_space_group``, ``position_formulas``, and ``u_formulas`` in place of the deprecated ``diffpy.structure`` functions ``GetSpaceGroup``, ``positionFormulas``, and ``UFormulas`` to silence deprecation warnings.
* Use ``add_constraint`` and ``add_soft_bounds`` in the ``*=`` and ``%=`` operators of ``RecipeOrganizerInterface`` so they no longer raise deprecation warnings for ``constrain`` and ``restrain``.
* Use ``pyobjcryst.crystal.create_crystal_from_cif``, ``scipy.optimize.leastsq``, and the ``particle_diameter`` argument of ``spherical_particle`` in the examples in place of deprecated or renamed APIs.

**Security:**

* <news item>
8 changes: 4 additions & 4 deletions src/diffpy/srfit/interface/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ def __imul__(self, args):
Parameters
----------
args : tuple
The arguments to pass to `constrain`.
The arguments to pass to `add_constraint`.

Returns
-------
RecipeOrganizerInterface
Return self after applying the constraint.
"""
_applyargs(args, self.constrain)
_applyargs(args, self.add_constraint)
return self

def __imod__(self, args):
Expand All @@ -91,14 +91,14 @@ def __imod__(self, args):
Parameters
----------
args : tuple
The arguments to pass to `restrain`.
The arguments to pass to `add_soft_bounds`.

Returns
-------
RecipeOrganizerInterface
Return self after applying the restraint.
"""
_applyargs(args, self.restrain)
_applyargs(args, self.add_soft_bounds)
return self

def __iadd__(self, args):
Expand Down
8 changes: 4 additions & 4 deletions src/diffpy/srfit/structure/objcrystparset.py
Original file line number Diff line number Diff line change
Expand Up @@ -1911,17 +1911,17 @@ def _create_space_group(sgobjcryst):
"""
import copy

from diffpy.structure.spacegroups import GetSpaceGroup, SymOp
from diffpy.structure.spacegroups import SymOp, get_space_group

name = sgobjcryst.GetName()
extnstr = ":%s" % sgobjcryst.GetExtension()
if name.endswith(extnstr):
name = name[: -len(extnstr)]

# Get whatever spacegroup we can get by name. This will set the proper
# crystal system. Creating a copy of the singleton from GetSpaceGroup,
# as this function messes with sg.symop_list.
sg = copy.copy(GetSpaceGroup(name))
# crystal system. Creating a copy of the singleton from
# get_space_group, as this function messes with sg.symop_list.
sg = copy.copy(get_space_group(name))

# Replace the symmetry operations to guarantee that we get it right.
symops = sgobjcryst.GetSymmetryOperations()
Expand Down
10 changes: 5 additions & 5 deletions src/diffpy/srfit/structure/sgconstraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ def constrain_as_space_group(
b and c are constrained to a, and alpha, beta and
gamma are fixed to 90.
"""
from diffpy.structure.spacegroups import GetSpaceGroup, SpaceGroup
from diffpy.structure.spacegroups import SpaceGroup, get_space_group

sg = spacegroup
if not isinstance(spacegroup, SpaceGroup):
sg = GetSpaceGroup(spacegroup)
sg = get_space_group(spacegroup)
sgp = _constrain_as_space_group(
phase,
sg,
Expand Down Expand Up @@ -309,7 +309,7 @@ def __init__(
A BaseStructure object to be constrained.
sg
The space group number or symbol (compatible with
diffpy.structure.spacegroups.GetSpaceGroup.
diffpy.structure.spacegroups.get_space_group.
sgoffset
Optional offset for sg origin.
scatterers
Expand Down Expand Up @@ -533,7 +533,7 @@ def _constrain_xyzs(self, positions):
self._xyzpars.addParameter(newpar)

# Constrain non-free xyz parameters
fpos = g.positionFormulas(xyznames)
fpos = g.position_formulas(xyznames)
for idx, tmp in enumerate(zip(scatterers, fpos)):
scatterer, fp = tmp

Expand Down Expand Up @@ -634,7 +634,7 @@ def _constrain_adps(self, positions):
isosymbol, isoname, params=self._parameters
)

fadp = g.UFormulas(adpnames)
fadp = g.u_formulas(adpnames)

# Constrain dependent anisotropics. We use the fact that an
# anisotropic cannot be dependent on an isotropic.
Expand Down
55 changes: 55 additions & 0 deletions tests/test_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env python
##############################################################################
#
# (c) 2026-present The DiffPy Team. All rights reserved.
#
# File coded by: Caden Myers
#
# See GitHub contributions for a more detailed list of contributors.
# https://github.com/diffpy/diffpy.srfit/graphs/contributors
#
# See LICENSE.rst for license information.
#
##############################################################################
"""Tests for the interface module."""

from diffpy.srfit.fitbase import FitRecipe


def _make_recipe_with_variables():
"""Return a recipe with the variables p1 = 1 and p2 = 2."""
recipe = FitRecipe("recipe")
p1 = recipe.create_new_variable("p1", 1)
p2 = recipe.create_new_variable("p2", 2)
return recipe, p1, p2


# Test that "*=" constrains a Parameter to an equation.
# C1: p1 is constrained to "2*p2" with "*=", and p2 is then set to 3.
# Expected: p1 is constrained and its value is 6.
def test_constrain_operator():
recipe, p1, p2 = _make_recipe_with_variables()
recipe *= "p1", "2*p2"

@cadenmyers13 cadenmyers13 Oct 15, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh, i had no clue you could constrain/restrain parameters with *=/%=. Kinda cool! Although not super intuitive

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh, i had no clue you could constrain/restrain parameters with *=/%=. Kinda cool! Although not super intuitive

Classic Pavol. Is it in the docs, where the symbols are actually explained? If not, let's put it there.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbillinge 😂 . Added it to the docs. built them and doubled checked it

p2.set_value(3)
recipe._constraints[p1].update()
assert recipe.is_constrained(p1)
actual_p1_value = p1.get_value()
expected_p1_value = 6
assert actual_p1_value == expected_p1_value


# Test that "%=" restrains an equation between soft bounds.
# C1: "p1+p2" is restrained between 0 and 10 with "%=", and p2 is then set
# to 10.
# Expected: The recipe has one restraint with a penalty of 1.
def test_restrain_operator():
recipe, _, p2 = _make_recipe_with_variables()
recipe %= "p1+p2", 0, 10
p2.set_value(10)
actual_number_of_restraints = len(recipe._restraints)
expected_number_of_restraints = 1
assert actual_number_of_restraints == expected_number_of_restraints
(restraint,) = recipe._restraints
actual_penalty = restraint.penalty()
expected_penalty = 1
assert actual_penalty == expected_penalty
2 changes: 1 addition & 1 deletion tests/test_objcrystparset.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ def xtestCreateSpaceGroup(self):
shn = smbls.hermann_mauguin()
short_name = shn.replace(" ", "")
if spacegroups.IsSpaceGroupIdentifier(short_name):
sg = spacegroups.GetSpaceGroup(shn)
sg = spacegroups.get_space_group(shn)
sgnew = self.getObjCrystParSetSpaceGroup(sg)
# print("dbsg: " + repr(self.sgsEquivalent(sg, sgnew)))
assert self.sgsEquivalent(sg, sgnew)
Expand Down
Loading
Loading