From 9ad562bef5394e2d28c4b0addb0ff138f0018671 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 17 Jan 2025 10:14:59 +0800 Subject: [PATCH 1/3] fix: 781 pymatgen structure bug --- dpdata/plugins/pymatgen.py | 4 +--- dpdata/pymatgen/structure.py | 11 ++++++++++- ...om_pymatgen.py => test_pymatgen_structure.py} | 16 +++++++++++++++- 3 files changed, 26 insertions(+), 5 deletions(-) rename tests/{test_from_pymatgen.py => test_pymatgen_structure.py} (59%) diff --git a/dpdata/plugins/pymatgen.py b/dpdata/plugins/pymatgen.py index 322298c3c..ff935d3ab 100644 --- a/dpdata/plugins/pymatgen.py +++ b/dpdata/plugins/pymatgen.py @@ -34,9 +34,7 @@ def to_system(self, data, **kwargs): except ModuleNotFoundError as e: raise ImportError("No module pymatgen.Structure") from e - species = [] - for name, numb in zip(data["atom_names"], data["atom_numbs"]): - species.extend([name] * numb) + species = [data["atom_names"][tt] for tt in data["atom_types"]] for ii in range(data["coords"].shape[0]): structure = Structure( data["cells"][ii], diff --git a/dpdata/pymatgen/structure.py b/dpdata/pymatgen/structure.py index 36e411c02..1f74dbdd0 100644 --- a/dpdata/pymatgen/structure.py +++ b/dpdata/pymatgen/structure.py @@ -4,12 +4,19 @@ def from_system_data(structure) -> dict: - symbols = [site.species_string for site in structure] + """Convert one pymatgen structure to dpdata's datadict.""" + symbols = [ii.specie.symbol for ii in structure] atom_names = list(structure.symbol_set) atom_numbs = [symbols.count(symbol) for symbol in atom_names] atom_types = np.array([atom_names.index(symbol) for symbol in symbols]).astype(int) coords = structure.cart_coords cells = structure.lattice.matrix + if all(structure.pbc): + pbc = True + elif not any(structure.pbc): + pbc = False + else: + raise ValueError(f"Partial pbc condition {structure.pbc} is not supported") info_dict = { "atom_names": atom_names, @@ -17,5 +24,7 @@ def from_system_data(structure) -> dict: "atom_types": atom_types, "coords": np.array([coords]), "cells": np.array([cells]), + "orig": np.zeros(3), + "nopbc": not pbc, } return info_dict diff --git a/tests/test_from_pymatgen.py b/tests/test_pymatgen_structure.py similarity index 59% rename from tests/test_from_pymatgen.py rename to tests/test_pymatgen_structure.py index 7689a9d5e..1b61e4970 100644 --- a/tests/test_from_pymatgen.py +++ b/tests/test_pymatgen_structure.py @@ -3,7 +3,7 @@ import os import unittest -from comp_sys import CompSys +from comp_sys import CompSys, IsPBC from context import dpdata try: @@ -28,5 +28,19 @@ def setUp(self): self.v_places = 6 +@unittest.skipIf(not exist_module, "skip pymatgen") +class TestFormToPytmatgen(unittest.TestCase, CompSys, IsPBC): + def setUp(self): + self.system = dpdata.System("pymatgen_data/deepmd/", fmt="deepmd/npy") + self.system_1 = self.system + self.system_2 = dpdata.System().from_pymatgen_structure( + self.system.to("pymatgen/structure")[0] + ) + self.places = 6 + self.e_places = 6 + self.f_places = 6 + self.v_places = 6 + + if __name__ == "__main__": unittest.main() From d7f54f202d072a3735cb9c90506f68af95aadb54 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 17 Jan 2025 10:17:51 +0800 Subject: [PATCH 2/3] add missing data --- tests/pymatgen_data/deepmd/set.000/box.npy | Bin 0 -> 200 bytes tests/pymatgen_data/deepmd/set.000/coord.npy | Bin 0 -> 2480 bytes tests/pymatgen_data/deepmd/set.000/energy.npy | Bin 0 -> 136 bytes tests/pymatgen_data/deepmd/set.000/force.npy | Bin 0 -> 2480 bytes tests/pymatgen_data/deepmd/set.000/virial.npy | Bin 0 -> 200 bytes tests/pymatgen_data/deepmd/type.raw | 98 ++++++++++++++++++ tests/pymatgen_data/deepmd/type_map.raw | 4 + 7 files changed, 102 insertions(+) create mode 100644 tests/pymatgen_data/deepmd/set.000/box.npy create mode 100644 tests/pymatgen_data/deepmd/set.000/coord.npy create mode 100644 tests/pymatgen_data/deepmd/set.000/energy.npy create mode 100644 tests/pymatgen_data/deepmd/set.000/force.npy create mode 100644 tests/pymatgen_data/deepmd/set.000/virial.npy create mode 100644 tests/pymatgen_data/deepmd/type.raw create mode 100644 tests/pymatgen_data/deepmd/type_map.raw diff --git a/tests/pymatgen_data/deepmd/set.000/box.npy b/tests/pymatgen_data/deepmd/set.000/box.npy new file mode 100644 index 0000000000000000000000000000000000000000..566749c13f663d13ce8b61bcc568a35cd42412f1 GIT binary patch literal 200 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I$-ItrGWItsN4WCN}{7vEY4il{go5bse==9k&S00rTJ7Jq%uHQ0+8FA4c^ TUflsEj!w&m=S=J@R(1dY)yZssVJ)`hjEIX-S2j#2;q5{P4)oTrKlZ~c&2KW#7 z|2gu`-e##sgjbQ;B)fZjTUFhvN$OVqQW5f~VI9*oQ3K%wZMrFf2Hrnj&URbWf~8xh zZCli(piMV4A@i9CMg5i3{(6W2;Z?8alh{&V7(1VFwqJy1+itDNeuqJ=j0hvDN`dIZ zYWLq8F!+zpA;8hJ=~0gsNqE!Znd|)q15Kj=E>Th&juaQVTM?OH*x58mo~D4%lUCUV zQt-gr@y4)#3HqM(D%>Ut{H$G9`N2pFOfH3eAgMAT_r(Qs#YQf;?5Ozlyg&*JuC992 z2Tb_-UEG^ZFStNmZ28oDN($mHWERtuzQ%)%7wACJBrb_pCgqk?~>}qWuQrkFG&z`;X`Ga z^r)g5@O_MP_G@6^lH#C*b&C-D>+GSSeibm%Gx{-kMhl24MCZqq0Y;Gzc18~aZ(Cu6#uE&b+uoCWX&h+ZNPPHal{DO{fn%ACkmk6J~jCG(pz z$%g76k@VfY5l1rkT*%8;OUB@^x@)}a$3E0n_`YaXgADigr!Qo6V=zQ6?i^>SLs62W zyMGf63e?=+;R_V#P)(18UJCeG>`qZtr$g~V5L?tvfkVuMPTlKlFm;}dg*h7V5C2lV zsfP>xo(-B;M=5ahBc?0Gql0aVW7U>kF1$D1=bezn20Kl+YdxBa$UyMy?OU=u2+Nuo zGkit3@+zatJbDQ=^`y$4Ts23-esg&ZdqkO(z+L;B>yC?I?a;A|(oKV@M4u_j|9h=uhvS3$B z*8)424m!Qwme48>ZZ!Wt`?QE~D|>_bE#ohUjUFGX{Yf4?u0=nStx-VZV%}*OCM4fB#~f2DY!IWs5`%uxb(R z|ItStvYRdyga(p8;lZaat3?K=rCU3bCgh+?xJx2+3k&E4#;Yv`8K7k6Yh@b7hK&2i z18&HXAlK4z!$ng~kUlu@vOk&)LGoGMJ?mKzwP(aMwpr}s-lMng5f!Qpbj_IEN?iqV*Y+UhblA5)lun_5_z`03c6lhj%ixXt+K%!n zHq1RH(4p*xBX)UO9vE@g>iw?L;otiCqWT5VQ$L?15fvbu&RZ@0h7K|V-tBZlI#{=V z`@NtUhkN9&{`JOf$PE*$>z9~DUyNdz>J2zl;Etcu44aXDD(%t$S6)tXxeXoOL~+-Bj$TBZ^|w$%J{7q3 z;zaLJgr69f5)U0+LK0E2dmT!t;A|qG&WiKdkX~{wWMly)>-dEmY~{hiHGWdUDMipc zlPXeXEFebhs6mxG4-N!h_;_p(2iXfwc+AouN=j@^@*Ec-c}kS5d&mNMd*n#f#*ksu zB73;olst#lsK$$<#eleQyXN7#A@p@+kAPf(L5i1AqJX`KMy~|L-Ble%9k{Ue>H`d> zVorCQ6!WEC1Whdh2Xv0JD+qSm4n*!^Z z3m4V9C=lTicxt;V8C;?W4|EwS&@`Xv^Zh#t^v%bI)O4~St5)g8?l}tZURv|D#r+_? zN5@mElnhfJRt|>RtAKU$4iEcoE@V0E){hji;9Q%JgqsN!o&>BZPq`^VoPk~N_ z%~^%bq!tVoOJ$cUFH+(A*Ejc@$4{a9vh@dd3{XJ!oY~Kw3Nz@ZhHV}T+osXZ5}I}Y zdkVc7{rxOr3kv|uM9@TKK$V4cB0!D9Ozd0VpE30ras3i2|fwDT2dTs z-iuJ!p3A-XE)wKzN9AgEB&fa<8oh8pgnkhg-ZQtzeWRa{FWf3p9{mVm1=zAGrDY5r_nB=!*A*@ R&*pb=;h6F-T8GDI@DD}$6iNU9 literal 0 HcmV?d00001 diff --git a/tests/pymatgen_data/deepmd/set.000/energy.npy b/tests/pymatgen_data/deepmd/set.000/energy.npy new file mode 100644 index 0000000000000000000000000000000000000000..3e591429a4e56f84265761a560f0cf4f712d9e41 GIT binary patch literal 136 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= gXCxM+0{I$-ItqrGItsN4WCO0~&$stIsc$_1088~C`~Uy| literal 0 HcmV?d00001 diff --git a/tests/pymatgen_data/deepmd/set.000/force.npy b/tests/pymatgen_data/deepmd/set.000/force.npy new file mode 100644 index 0000000000000000000000000000000000000000..4546a81435a7e7638c7e601a55a1f29de80fe7af GIT binary patch literal 2480 zcmbV}`#02i7{}EjwH0d*N}WuOjLVS7A(tMFvSN)(v1c%axzI4o3>jf^zm!X4ORigP zO>)_6b?inDb|W>iC@a~hLqusyNr|@o13tg(_qXr+Jm-1duh*x5;qB(ZT%i!H5J%;3 zBiUlA4TWmQv!>E0R9=KQN*ow|I6})A`L3OYG>Vk+ zKfg8n{M_uU);O4;*LCUA{eT@bClbg)kdVXET?}W3vu41n7s#vTxv0|95NE9Jh@-tt zG~dBQ%oI;nK0heL%f9`d>v>XHp4U8OfQ_0- zI&K?^mv1V`E^$MpfpE$~m9e%#imgg|ln0Rpxbu<5$AFElAQ|>ym7Qioa==1SoU${# zPMN#JJ|o7h?)Q5fJa|y?^B?--ci6ywUDDyA^RFA{tL!6)9ORUd!Z;f9%3!+vLa(t#RmFdI{l0H)4vEsv|6pukH( zQpo4v$I=_D?QSBZ1-LCXX{I18DqudQDIRKP^LxDK{84vAZe7ut0-=SgewA$A3yWLc z{bfwcgjD(?)`~U`tj*644PpgD;S>1VAt?jKOf8hnE{fptB+t=>6^84Cd#=+C2g8^+ zuC2tKgOTdR{>Ab`U_0ubQy4CW-N}5~8O5W}bWZ(hiZ}qfSLzFA!ox{9680eBE)sf@ zc!9u6@`(hWaI10K?gPOt&>SSm`?FhsDh+QGI~YmuI_qi4aFhb%*!}Y4Y6}aq-^lL< zz8Ao3MBij_VhDPbX5Ca>9RjLUv$8>f5Kr~XyGpd8v3~HCRp4_WEWQ275|+i-YZF+M zZsCo$WyTag?mp#(hO`Z_W|FjudO~!03UcIn+Cp(#sOW=ai1C>> z(^f`bj@SumQ-j5Wkb+emL-f29FRV>vYF%97qGx;WXlLg^tUoC%@Z^TTrq7bqE!xpY zlMRh9B?(xqG3v1p=7xp2CUq=FZ5$r!kGgW34aXW@{l14DgdjrEOe4pwEWdRF?RVdaE_>NPOOX`UPULf!S!6y)WqEf=WkcwU@OTR+F;b)z1Q@3q_ z6Wzu?=`;NJRrdv$uru_{I<^I01em2s;m%p@i8sH zyY&-;4WH}PnnmAvp!q6$j%mdKXq}ku(*KYI>>m4tOT~vUxajQ*g;-(A;VwlS_)Jd)t!8zZFmUOxZ>*!WvBKKHW e*Dl&`~6J}<{KP`i^Jq$ Nbb?%A^!X#p>;aA6FPZ=V literal 0 HcmV?d00001 diff --git a/tests/pymatgen_data/deepmd/type.raw b/tests/pymatgen_data/deepmd/type.raw new file mode 100644 index 000000000..479b28ae4 --- /dev/null +++ b/tests/pymatgen_data/deepmd/type.raw @@ -0,0 +1,98 @@ +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 diff --git a/tests/pymatgen_data/deepmd/type_map.raw b/tests/pymatgen_data/deepmd/type_map.raw new file mode 100644 index 000000000..e2400b8fe --- /dev/null +++ b/tests/pymatgen_data/deepmd/type_map.raw @@ -0,0 +1,4 @@ +Fe +Li +O +P From 329ca1ee643c25d76060e84fa566259acb9c105e Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 17 Jan 2025 11:10:23 +0800 Subject: [PATCH 3/3] fix nopbc --- dpdata/plugins/pymatgen.py | 5 +++-- tests/test_pymatgen_structure.py | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/dpdata/plugins/pymatgen.py b/dpdata/plugins/pymatgen.py index ff935d3ab..b8099a3ab 100644 --- a/dpdata/plugins/pymatgen.py +++ b/dpdata/plugins/pymatgen.py @@ -30,14 +30,15 @@ def to_system(self, data, **kwargs): """Convert System to Pymatgen Structure obj.""" structures = [] try: - from pymatgen.core import Structure + from pymatgen.core import Lattice, Structure except ModuleNotFoundError as e: raise ImportError("No module pymatgen.Structure") from e species = [data["atom_names"][tt] for tt in data["atom_types"]] + pbc = not (data.get("nopbc", False)) for ii in range(data["coords"].shape[0]): structure = Structure( - data["cells"][ii], + Lattice(data["cells"][ii], pbc=[pbc] * 3), species, data["coords"][ii], coords_are_cartesian=True, diff --git a/tests/test_pymatgen_structure.py b/tests/test_pymatgen_structure.py index 1b61e4970..1e93829e1 100644 --- a/tests/test_pymatgen_structure.py +++ b/tests/test_pymatgen_structure.py @@ -3,7 +3,7 @@ import os import unittest -from comp_sys import CompSys, IsPBC +from comp_sys import CompSys, IsNoPBC, IsPBC from context import dpdata try: @@ -42,5 +42,20 @@ def setUp(self): self.v_places = 6 +@unittest.skipIf(not exist_module, "skip pymatgen") +class TestFormToPytmatgenNopbc(unittest.TestCase, CompSys, IsNoPBC): + def setUp(self): + self.system = dpdata.System("pymatgen_data/deepmd/", fmt="deepmd/npy") + self.system.data["nopbc"] = True + self.system_1 = self.system + self.system_2 = dpdata.System().from_pymatgen_structure( + self.system.to("pymatgen/structure")[0] + ) + self.places = 6 + self.e_places = 6 + self.f_places = 6 + self.v_places = 6 + + if __name__ == "__main__": unittest.main()