diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6850e3c..aac0883 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -33,4 +33,3 @@ Release notes **Added:** * ``constrain_as_space_group`` also accepts a generator, such as a ``PDFGenerator``, whose ``.phase`` is the structure parameter set, for example ``constrain_as_space_group(generator, "Fm-3m")``. - diff --git a/news/fix-stretch-mode-atoms.rst b/news/fix-stretch-mode-atoms.rst new file mode 100644 index 0000000..2e692f0 --- /dev/null +++ b/news/fix-stretch-mode-atoms.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* ``ObjCrystMoleculeParSet.wrap_stretch_mode_parameters`` no longer raises ``AttributeError`` for a molecule with stretch modes. It called ``AddAtoms``, which ``StretchModeParameter`` doesn't have. + +**Security:** + +* diff --git a/src/diffpy/cmistructure/objcrystparset.py b/src/diffpy/cmistructure/objcrystparset.py index 7531967..f471043 100644 --- a/src/diffpy/cmistructure/objcrystparset.py +++ b/src/diffpy/cmistructure/objcrystparset.py @@ -418,7 +418,7 @@ def wrap_stretch_mode_parameters(self): name = a.GetName() atoms.append(getattr(self, name)) - parameter.AddAtoms(atoms) + parameter.add_atoms(atoms) self.add_parameter(parameter) @@ -441,7 +441,7 @@ def wrap_stretch_mode_parameters(self): for a in mode.GetAtoms(): name = a.GetName() atoms.append(getattr(self, name)) - parameter.AddAtoms(atoms) + parameter.add_atoms(atoms) self.add_parameter(parameter) diff --git a/tests/test_objcrystparset.py b/tests/test_objcrystparset.py index cfbcffe..263189a 100644 --- a/tests/test_objcrystparset.py +++ b/tests/test_objcrystparset.py @@ -248,10 +248,32 @@ def test_implicit_dihedral_angle_restraints(c60_crystal, c60_molecule): return -def test_implicit_stretch_modes(): - """Test the molecule with implicit stretch modes.""" - # Not sure how to make this happen. - pass +def test_wrap_stretch_mode_parameters(c60_crystal, c60_molecule): + # Case: The molecule has two bond lengths and one bond angle in the + # chain C0-C1-C2, and its stretch modes are built. + # Expected: Each bond length and bond angle stretch mode is wrapped + # as a Parameter named after its atoms. pyobjcryst builds one mode + # for each side of a bond or angle, so every name appears in both + # atom orders. + ocmol = c60_molecule + ocmol.AddBond(ocmol[0], ocmol[1], 1.37, 0.1, 0.1) + ocmol.AddBond(ocmol[1], ocmol[2], 6.9, 0.1, 0.1) + ocmol.AddBondAngle(ocmol[0], ocmol[1], ocmol[2], 1.57, 0.1, 0.1) + ocmol.BuildStretchModeBondLength() + ocmol.BuildStretchModeBondAngle() + molecule = ObjCrystCrystalParSet("bucky", c60_crystal).c60 + parameter_names_before = set(molecule._parameters) + molecule.wrap_stretch_mode_parameters() + actual_names = sorted(set(molecule._parameters) - parameter_names_before) + expected_names = [ + "ba_C0_C1_C2", + "ba_C2_C1_C0", + "bl_C0_C1", + "bl_C1_C0", + "bl_C1_C2", + "bl_C2_C1", + ] + assert actual_names == expected_names def test_explicit_bond_length_restraints(c60_crystal, c60_molecule):