Skip to content

Commit c1ab7d0

Browse files
authored
support reading xyz files (#306)
1 parent b70e3e0 commit c1ab7d0

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

dpdata/plugins/xyz.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22

33
from dpdata.xyz.quip_gap_xyz import QuipGapxyzSystems
4-
from dpdata.xyz.xyz import coord_to_xyz
4+
from dpdata.xyz.xyz import coord_to_xyz, xyz_to_coord
55
from dpdata.format import Format
66

77
@Format.register("xyz")
@@ -20,6 +20,20 @@ def to_system(self, data, file_name, **kwargs):
2020
with open(file_name, 'w') as fp:
2121
fp.write("\n".join(buff))
2222

23+
def from_system(self, file_name, **kwargs):
24+
with open(file_name, 'r') as fp:
25+
coords, types = xyz_to_coord(fp.read())
26+
atom_names, atom_types, atom_numbs = np.unique(types, return_inverse=True, return_counts=True)
27+
return {
28+
'atom_names': list(atom_names),
29+
'atom_numbs': list(atom_numbs),
30+
'atom_types': atom_types,
31+
'coords': coords.reshape((1, *coords.shape)),
32+
'cells': np.eye(3).reshape((1, 3, 3)) * 100,
33+
'nopbc': True,
34+
'orig': np.zeros(3),
35+
}
36+
2337

2438
@Format.register("quip/gap/xyz")
2539
@Format.register("quip/gap/xyz_file")
@@ -29,4 +43,4 @@ def from_labeled_system(self, data, **kwargs):
2943

3044
def from_multi_systems(self, file_name, **kwargs):
3145
# here directory is the file_name
32-
return QuipGapxyzSystems(file_name)
46+
return QuipGapxyzSystems(file_name)

dpdata/xyz/xyz.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Tuple
2+
13
import numpy as np
24

35
def coord_to_xyz(coord: np.ndarray, types: list)->str:
@@ -26,3 +28,32 @@ def coord_to_xyz(coord: np.ndarray, types: list)->str:
2628
for at, cc in zip(types, coord):
2729
buff.append("{} {:.6f} {:.6f} {:.6f}".format(at, *cc))
2830
return "\n".join(buff)
31+
32+
33+
def xyz_to_coord(xyz: str) -> Tuple[np.ndarray, list]:
34+
"""Convert xyz format to coordinates and types.
35+
36+
Parameters
37+
----------
38+
xyz : str
39+
xyz format string
40+
41+
Returns
42+
-------
43+
coords : np.ndarray
44+
coordinates, Nx3 array
45+
types : list
46+
list of types
47+
"""
48+
symbols = []
49+
coords = []
50+
for ii, line in enumerate(xyz.split('\n')):
51+
if ii == 0:
52+
natoms = int(line.strip())
53+
elif 2 <= ii <= 1 + natoms:
54+
# symbol x y z
55+
symbol, x, y, z = line.split()
56+
coords.append((float(x), float(y), float(z)))
57+
symbols.append(symbol)
58+
return np.array(coords), symbols
59+

tests/test_xyz.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
import numpy as np
33
import tempfile
44
from context import dpdata
5+
from comp_sys import CompSys, IsNoPBC
56

6-
class TestXYZ(unittest.TestCase):
7+
class TestToXYZ(unittest.TestCase):
78
def test_to_xyz(self):
89
with tempfile.NamedTemporaryFile('r') as f_xyz:
910
dpdata.System(data={
@@ -17,3 +18,21 @@ def test_to_xyz(self):
1718
xyz0 = f_xyz.read().strip()
1819
xyz1 = "2\n\nC 0.000000 1.000000 2.000000\nO 3.000000 4.000000 5.000000"
1920
self.assertEqual(xyz0, xyz1)
21+
22+
23+
class TestFromXYZ(unittest.TestCase, CompSys, IsNoPBC):
24+
def setUp(self):
25+
self.places = 6
26+
# considering to_xyz has been tested..
27+
self.system_1 = dpdata.System(data={
28+
"atom_names": ["C", "O"],
29+
"atom_numbs": [1, 1],
30+
"atom_types": np.array([0, 1]),
31+
"coords": np.arange(6).reshape((1,2,3)),
32+
"cells": np.zeros((1,3,3)),
33+
"orig": np.zeros(3),
34+
"nopbc": True,
35+
})
36+
with tempfile.NamedTemporaryFile('r') as f_xyz:
37+
self.system_1.to("xyz", f_xyz.name)
38+
self.system_2 = dpdata.System(f_xyz.name, fmt="xyz")

0 commit comments

Comments
 (0)