-
Notifications
You must be signed in to change notification settings - Fork 892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
structure.to_ase_atoms() modifies structure.properties in place #4289
Comments
The minimal example also throws an error for me. It looks like this bug is occurring on lines 205 - 215 of pymatgen.io.ase # Atoms.info <---> Structure.properties
if properties := structure.properties:
atoms.info = properties # This links values in atoms.info to the corresponding values in structure.properties
# Regenerate Spacegroup object from `.todict()` representation
if isinstance(atoms.info.get("spacegroup"), dict):
atoms.info["spacegroup"] = Spacegroup( # So now here atoms.info["spacegroup"] is actually being changed by changing structure.properties["spacegroup"]
atoms.info["spacegroup"]["number"],
setting=atoms.info["spacegroup"].get("setting", 1),
) The following is a quick change that fixes the error raised by your example, but I have not yet ran the test-checks with this change implemented. # Atoms.info <---> Structure.properties
if properties := structure.properties:
# Assign a copy to unlink the keys in atoms.info to structure.properties
atoms.info = properties.copy()
# Regenerate Spacegroup object from `.todict()` representation
if isinstance(atoms.info.get("spacegroup"), dict):
atoms.info["spacegroup"] = Spacegroup(
atoms.info["spacegroup"]["number"],
setting=atoms.info["spacegroup"].get("setting", 1),
) I know people tend to like to keep thinks light, so it might be better to just make "spacegroup" an exception to the properties set on atoms as links to avoid the in-place changing. # Atoms.info <---> Structure.properties
# Skip the following keys who's values in atoms.info are subject to change
# to avoid in-place modification of the structure object.
keys_to_skip = ["spacegroup"]
# Walrus assign properties from structure.properties with truthy values and not in keys_to_skip
if properties := {k: v for k, v in structure.properties.items() if v and k not in keys_to_skip}:
atoms.info = properties
# Regenerate Spacegroup object from `.todict()` representation
if isinstance(structure.properties.get("spacegroup"), dict):
atoms.info["spacegroup"] = Spacegroup(
structure.properties["spacegroup"]["number"],
setting=structure.properties["spacegroup"].get("setting", 1),
) |
Happy to review a PR for this! |
Thanks for the fix @benrich37! I would have opened a PR, but was unfortunately pretty swamped this week :) My vote is for your first solution where properties is simply copied. We could perhaps use |
As the person who wrote much of the ASE converter, I wholeheartedly agree with you that nothing should be mutated! That was an oversight on my part. I also agree that a |
Just submitted a PR - turns out there was a similar issue with |
Python version
3.12.4
Pymatgen version
2025.1.24
Operating system version
MacOS
Current behavior
Problems arise when converting
Structure
's with spacegroup information embedded in structure.properties intoase.Atoms
objects.MINIMAL EXAMPLE
OUTPUT
Expected Behavior
The second call to
to_json
should not raise an exception. In addition,Structure.to_ase_atoms()
should be side effect free.Minimal example
Relevant files to reproduce this bug
No response
The text was updated successfully, but these errors were encountered: