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
2 changes: 1 addition & 1 deletion .github/workflows/matrix-and-codecov-on-merge-to-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ jobs:
headless: false
run: |
set -Eeuo pipefail
python -m pip install --no-deps diffpy.srfit==3.4.0rc0
python -m pip install --no-deps diffpy.cmistructure

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.

Added a test to remove this when cmistructure is out on conda forge

secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/tests-on-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ jobs:
headless: false
run: |
set -Eeuo pipefail
python -m pip install --no-deps diffpy.srfit==3.4.0rc0
python -m pip install --no-deps diffpy.cmistructure
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
23 changes: 23 additions & 0 deletions news/rm-srfit-rc-pin.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* <news item>

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* Require ``diffpy.srfit`` 3.4.0 or later. Older versions lack the methods diffpy.cmipdf calls, so installing it next to ``diffpy.srfit`` 3.3.1 failed at run time.

**Security:**

* <news item>
23 changes: 23 additions & 0 deletions news/use-cmistructure.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* ``diffpy.cmistructure`` as a dependency.

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* Build ``diffpy.cmistructure`` parameter sets in ``set_structure`` and ``add_structure``, and accept them in ``set_structure_from_parset`` and ``add_structure_from_parset``. These used ``diffpy.srfit.structure`` and raised ``AttributeError: stru`` for a ``diffpy.cmistructure`` parameter set.

**Security:**

* <news item>
2 changes: 1 addition & 1 deletion requirements/conda.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
numpy
diffpy.srreal
diffpy.srfit
diffpy.srfit>=3.4.0
diffpy.structure
3 changes: 2 additions & 1 deletion requirements/pip.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
numpy
diffpy.srreal
diffpy.srfit
diffpy.srfit>=3.4.0
diffpy.structure
diffpy.cmistructure
10 changes: 5 additions & 5 deletions src/diffpy/cmipdf/basepdfgenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@

import numpy

from diffpy.cmistructure import structure_to_parameter_set
from diffpy.srfit.exceptions import SrFitError
from diffpy.srfit.fitbase import ProfileGenerator
from diffpy.srfit.fitbase.parameter import ParameterAdapter
from diffpy.srfit.structure import struToParameterSet

# FIXME - Parameter creation will have to be smarter once deeper calculator
# configuration is enabled.
Expand Down Expand Up @@ -257,7 +257,7 @@ def set_structure(self, structure, name="phase", periodic=True):
This creates a DiffpyStructureParSet, ObjCrystCrystalParSet or
ObjCrystMoleculeParSet that adapts structure to a ParameterSet
interface.
See those classes (located in diffpy.srfit.structure) for how they are
See those classes (located in diffpy.cmistructure) for how they are
used. The resulting ParameterSet will be managed by this generator.

Parameters
Expand All @@ -276,7 +276,7 @@ def set_structure(self, structure, name="phase", periodic=True):
"""

# Create the ParameterSet
parset = struToParameterSet(name, structure)
parset = structure_to_parameter_set(name, structure)

# Set the phase
self.set_structure_from_parset(parset, periodic)
Expand Down Expand Up @@ -304,13 +304,13 @@ def set_structure_from_parset(self, parset, periodic=True):
"""
# Store the ParameterSet for easy access
self._phase = parset
self.structure = self._phase.stru
self.structure = self._phase.structure

# Put this ParameterSet in the ProfileGenerator.
self.add_parameter_set(parset)

# Set periodicity
self._phase.useSymmetry(periodic)
self._phase.use_symmetry(periodic)
return

def _prepare(self, r):
Expand Down
2 changes: 1 addition & 1 deletion src/diffpy/cmipdf/debyepdfgenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def set_structure(self, structure, name="phase", periodic=False):
This creates a DiffpyStructureParSet, ObjCrystCrystalParSet or
ObjCrystMoleculeParSet that adapts structure to a ParameterSet
interface.
See those classes (located in diffpy.srfit.structure) for how they are
See those classes (located in diffpy.cmistructure) for how they are
used. The resulting ParameterSet will be managed by this generator.

Parameters
Expand Down
68 changes: 67 additions & 1 deletion tests/test_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import numpy as np
import pytest

from diffpy.cmipdf import PDFGenerator
from diffpy.cmipdf import DebyePDFGenerator, PDFGenerator
from diffpy.cmistructure import constrain_as_space_group
from diffpy.cmistructure.diffpyparset import DiffpyStructureParSet
from diffpy.srreal.pdfcalculator import PDFCalculator


Expand Down Expand Up @@ -51,6 +53,70 @@ def test_set_qmin():
assert actual_qmins == expected_qmins


# set_structure adapts the structure with a diffpy.cmistructure parameter
# set, which the generator then manages as its phase.
@pytest.mark.parametrize(
"input_generator_class",
[
# C1: A diffpy.structure Structure is set on a generator,
# 1. PDFGenerator, 2. DebyePDFGenerator.
# Expected: The phase is a diffpy.cmistructure DiffpyStructureParSet
# that adapts the structure.
PDFGenerator,
DebyePDFGenerator,
],
)
def test_set_structure(ni_pdffit_structure, input_generator_class):
generator = input_generator_class()
generator.set_structure(ni_pdffit_structure)
actual_phase = (type(generator.phase), generator.phase.structure)
expected_phase = (DiffpyStructureParSet, ni_pdffit_structure)
assert actual_phase == expected_phase


# set_structure_from_parset manages the given diffpy.cmistructure parameter
# set as the phase, and periodic sets whether it uses symmetry.
@pytest.mark.parametrize(
"input_periodic, expected_using_symmetry",
[
# C1: The parameter set is set as periodic.
# Expected: The generator manages that parameter set, its structure
# is the adapted structure, and the parameter set uses symmetry.
(True, True),
# C2: The parameter set is set as not periodic.
# Expected: The same, except that it does not use symmetry.
(False, False),
],
)
def test_set_structure_from_parset(
ni_pdffit_structure, input_periodic, expected_using_symmetry
):
parameter_set = DiffpyStructureParSet("phase", ni_pdffit_structure)
generator = PDFGenerator()
generator.set_structure_from_parset(parameter_set, periodic=input_periodic)
actual_state = (
generator.phase is parameter_set,
generator.structure is ni_pdffit_structure,
parameter_set.using_symmetry(),
)
expected_state = (True, True, expected_using_symmetry)
assert actual_state == expected_state


def test_constrain_as_space_group_accepts_generator(ni_pdffit_structure):
# C1: A PDFGenerator holding face-centered cubic Ni is passed to
# diffpy.cmistructure's constrain_as_space_group with Fm-3m.
# Expected: Only the lattice length a of its phase is left free.
generator = PDFGenerator()
generator.set_structure(ni_pdffit_structure)
space_group_parameters = constrain_as_space_group(generator, "Fm-3m")
actual_free_lattice_names = [
parameter.name for parameter in space_group_parameters.latpars
]
expected_free_lattice_names = ["a"]
assert actual_free_lattice_names == expected_free_lattice_names


def test_parameter_names(ni_pdffit_structure):
# C1: A structure is set on the generator.
# Expected: The generator holds one Parameter for each calculator
Expand Down
29 changes: 29 additions & 0 deletions tests/test_pdfcontribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import pytest

from diffpy.cmipdf import PDFContribution
from diffpy.cmistructure.diffpyparset import DiffpyStructureParSet
from diffpy.srfit.exceptions import SrFitError
from diffpy.structure import Structure, load_structure

Expand Down Expand Up @@ -126,3 +127,31 @@ def test_pickling(datafile):
actual_residual = unpickled_contribution.residual()
expected_residual = _make_ni_contribution(datafile, uiso=0.004).residual()
assert np.allclose(actual_residual, expected_residual)


def test_add_structure(datafile):
# C1: A diffpy.structure Structure is added to the contribution.
# Expected: The new generator's phase is a diffpy.cmistructure
# DiffpyStructureParSet that adapts the structure.
contribution = PDFContribution("pdf")
ni = load_structure(str(datafile("ni.cif")))
contribution.add_structure(ni, name="ni")
actual_phase = (
type(contribution.ni.phase),
contribution.ni.phase.structure,
)
expected_phase = (DiffpyStructureParSet, ni)
assert actual_phase == expected_phase


def test_add_structure_from_parset(datafile):
# C1: A diffpy.cmistructure DiffpyStructureParSet is added to the
# contribution.
# Expected: The new generator manages that parameter set as its phase.
contribution = PDFContribution("pdf")
ni = load_structure(str(datafile("ni.cif")))
parameter_set = DiffpyStructureParSet("phase", ni)
contribution.add_structure_from_parset(parameter_set, name="ni")
actual_phase = contribution.ni.phase
expected_phase = parameter_set
assert actual_phase is expected_phase
Loading