pymatgen
pymatgen copied to clipboard
Issue with symmetrization (CifWrite) in newer pymatgen version
Python version
Python 3.10.13
Pymatgen version
Version: 2023.11.12
Operating system version
Mac OSX 13.2.1
Current behavior
I try to symmetrize a POSCAR file. The symmetrization is successful but the structure produced is wrong: space group is 8 and the atoms are clearly overlapping. Using an older version of pymatgen (2023.5.31) gives the right structure instead.
Expected Behavior
I expect the structure to be correctly symmetrized (space group 12).
Minimal example
Using the zip file provided run from terminal:
python3 poscar2cif POSCAR_src_166.vasp 0.05 5
Using pymatgen 2023.5.31 gives the right cif
Using pymatgen 2023.11.12 gives the wrong cif
Relevant files to reproduce this bug
Note added: the bug persists in pymatgen version 2023.12.18.
Hi @deecadance, can you explain why you expect to get space group 12 here? The space group of the POSCAR you attached is 8, and you're not directly symmetrizating the structure.
symprec
and angprec
control the tolerance with which pymatgen handles equality of distances and angles, respectively. They maybe indirectly symmetrize a structure.
I'll just note the following simpler syntax for writing CIFs than in your file:
from pymatgen.core import Structure
struct = Structure.from_file("POSCAR_src_166.vasp")
cif_writer_kwargs = {"symprec": symprec, "angle_tolerance" : angprec}
struct.to("filename.cif", **cif_writer_kwargs)
can you explain why you expect to get space group 12 here?
Two reasons:
- Pasting the POSCAR file in a different symmetrizer (e.g. https://uspex-team.org/online_utilities/poscar2cif/#end) returns space group 12
- If you inspect the structure (e.g. using VESTA) before and after the symmetrization you can see that when space group 12 is return the structure correctly matches the original POSCAR. On the other hand, going through pymatgen 2023.11.12, when space group 8 is returned, the structure is just wrong (e.g. the W atoms are overlapping), see attached structures.zip, I also re-added the poscar in a VESTA-friendly format.
symprec and angprec control the tolerance with which pymatgen handles equality of distances and angles, respectively. They maybe indirectly symmetrize a structure.
Yes, they do. I don't know if that was intentional or not, but the code does work as a symmetrizer (exceptionally well in the previous version), and I have been using it for that way for a long time. Even if you don't care about my use case, cif_writer is not reading this poscar correctly, though it used to.
I'll just note the following simpler syntax for writing CIFs than in your file:
Thanks
Hey @deecadance, sorry if my message came across as dismissive! I'm trying to understand what might have changed so we can look into it further
When I load in your POSCAR and write it to a CIF (still space group 8), I'm not getting overlapping W sites, so hopefully this is an issue of conflicting packages. You might want to try pip install --upgrade spglib
, which handles PMG's symmetry determination
I'm using spglib==2.2.0 and pymatgen==2023.12.18
Excuse me for interrupting. I am a maintainer of spglib.
It seems the POSCAR structure is rather distorted from C2/m.
The following script shows a detected space group type depends on symprec
around 1e-2 to 1e-1.
If the behavior of CifWriter changed at some point, I guess a default symprec may be changed.
from importlib.metadata import version
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from pymatgen.io.vasp import Poscar
import spglib
print(f"pymatgen: {version('pymatgen')}")
print(f"spglib: {spglib.__version__}")
structure = Poscar.from_file('mwe/POSCAR_src_166.vasp').structure
cell = SpacegroupAnalyzer(structure)._cell
for symprec in [1e-4, 1e-2, 3e-2, 1e-1]:
dataset = spglib.get_symmetry_dataset(cell, symprec=symprec)
print(f"symprec={symprec}")
print(" Space group type:", dataset['international'])
print(" Number of atoms:", len(dataset['std_types']))
Output
pymatgen: 2023.12.18
spglib: 2.2.0
symprec=1e-08
Space group type: Cm
Number of atoms: 14
symprec=0.0001
Space group type: Cm
Number of atoms: 14
symprec=0.01
Space group type: Cm
Number of atoms: 14
symprec=0.03
Space group type: C2/m
Number of atoms: 14
symprec=0.1
Space group type: C2/m
Number of atoms: 14
Much appreciated @lan496! While I can't clearly see a spot in pymatgen where symprec may have been lowered recently, that seems to be a reasonable fix. When I use a larger / looser symprec > 0.02, I get a space group of 12 for the symmetrized structure. Can you check that you get the same behavior @deecadance?
Hi, thanks to both for the nice replies, and sorry if I sounded salty, it was not my intention! @lan496 Thanks for joining the discussion! I tried to your script. Depending on the version of spglib/pymatgen that I'm using it runs or it doesn't. In particular: spglib 2.0.2, pymatgen 2023.5.31, numpy 1.23.5 I reproduce exactly your result spglib 2.2.0, pymatgen 2023.12.18, numpy 1.26.0 the code fails with error: spglib: ssm_get_exact_positions failed. (line 479, /private/var/folders/gb/48p5g82s29b2zzvm7yzcrwwh0000gn/T/pip-install-96qlk6rd/spglib_021622f088764b9bb72fef489c5e415e/src/refinement.c).
I guess it's not so much a matter of exactly which space group, rather than a problem of overlapping atoms. Using a smaller symprec with the two versions of the libraries I can get to some cif file with both, and in both cases it has the same space group (8), except in the newer configuration the crystal structure is wrong (see png's/cifs in new_mwe.zip).
I'm using spglib==2.2.0 and pymatgen==2023.12.18
Very interesting. I am using the same when I get the wrong structure. What is your numpy version? Could it be something silly like a transpose in the wrong place?
Possibly related error:
from pymatgen.ext.matproj import MPRester
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer\
struct = mpr.get_structure_by_material_id("mp-886")
sa = SpacegroupAnalyzer(struct)
sstruct = sa.get_symmetrized_structure() #errors out
Produces:
132 def get_space_group_number(self) -> int:
133 """Get the international spacegroup number (e.g., 62) for structure.
134
135 Returns:
136 int: International spacegroup number for structure.
137 """
--> 138 return int(self._space_group_data["number"])
TypeError: 'NoneType' object is not subscriptable
So it looks like spglib is was not able to populate _space_group_data
.
Just tested the code above using different managers:
pip install spglib
-> gives error
conda install -c conda-forge spglib
-> no error
I’m guessing this is some weird interplay between the way data is represented in the numpy parts of the spglib python wrapper and the specific compilation of the C code. ~We probably have to ping one of their developer to resolve this one.~ nvm @lan496 is already here!
Hi @lan496 dear spglib developer, I recently had an issue related to this. For the same structure, I got a different number of symmetry operations after updating my pymatgen, let me reproduce the issue here
from importlib.metadata import version
from pymatgen.analysis.structure_matcher import StructureMatcher
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from pymatgen.ext.matproj import MPRester
from pymatgen.io.vasp import Poscar
import spglib
from pymatgen.core import Structure
sm=StructureMatcher()
print(f"pymatgen: {version('pymatgen')}")
print(f"spglib: {spglib.__version__}")
mpr=MPRester()
s1=mpr.get_structure_by_material_id("mp-2133")
s2 = Poscar.from_file('./ZnO_2133/ZnO.poscar').structure ## poscar downloaded from MP website
print (f"structure_matcher={sm.fit_anonymous(s1,s2)}")
for symprec in [1e-5,1e-1]:
for s in [s1,s2]:
spg=SpacegroupAnalyzer(structure=s,symprec=symprec)
print(f"symprec={symprec}")
print("Space group type:", spg.get_space_group_symbol())
print("Number of operations:", len(spg.get_space_group_operations()))
The output is
pymatgen: 2023.8.10
spglib: 2.3.0
structure_matcher = True
symprec=1e-05
Space group type: P6_3mc
Number of operations: 24
symprec=1e-05
Space group type: P6_3mc
Number of operations: 12
symprec=0.1
Space group type: P6_3mc
Number of operations: 24
symprec=0.1
Space group type: P6_3mc
Number of operations: 12
Two things that I want to confirm are:
- Anyone knows whether
mpr.get_structure_by_material_id()
switched the defaultconventional_unit_cell
setting (from True to False
)? - For the same structure (passed structure_matcher), the symmetry operation numbers might be different (depending on whether it is a conventional unit cell or not)? Here we exclude the reasoning from symprec setting by tuning it from 1e-5 to 1e-1, plus the space group type remains the same.
Just locate the bug from spglib update (from 1.16.5 to 2.3.0
).
I have submitted a new issue there https://github.com/spglib/spglib/issues/413
@esoteric-ephemera For the first case of this issue, the distinction between Cm and C2/m would be challenging for such a large symprec. It may be helpful to check atoms are not overlapped in pymatgen's cif parser side.
@jmmshn
I could not reproduce your result with spglib==2.3.1 and pymatgen==2024.1.27. If your error still presents in the latest, please open an issue at spglib. In that case, please use a raw input for spglib by SpacegroupAnalyzer(structure)._cell
.