Skip to content

Commit

Permalink
Add DFTB+ gen fmt parser
Browse files Browse the repository at this point in the history
  • Loading branch information
peterspackman committed Feb 14, 2024
1 parent 522eebe commit e2e1c2e
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 0 deletions.
66 changes: 66 additions & 0 deletions src/chmpy/fmt/gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import logging
from pathlib import Path
import numpy as np
from chmpy.core.element import Element

LOG = logging.getLogger(__name__)


def parse_gen_string(contents, filename=None):
"""Convert provided xmol .xyz file contents into an array of
atomic numbers and cartesian positions
Parameters
----------
contents: str
text contents of the .xyz file to read
Returns
-------
tuple of :obj:`np.ndarray`
List[Element], (N, 3) positions, (4, 3) lattice vectors, bool (if fractional)
read from the given file
"""
lines = contents.splitlines()
natom_str, kind = lines[0].split()
natom = int(natom_str)
kind = kind.strip()
LOG.debug("Expecting %d atoms %s", natom, "in " + filename if filename else "")
elements_map = [Element[x.strip()] for x in lines[1].split()]

arr = [[float(x) for x in line.split()] for line in lines[natom + 2 : natom + 6]]
elements = []
positions = []
for line in lines[2 : natom + 2]:
if not line.strip():
break
tokens = line.strip().split()
xyz = tuple(float(x) for x in tokens[2:5])
positions.append(xyz)
el = elements_map[int(tokens[1]) - 1]
elements.append(el)
LOG.debug(
"Found %d atoms lines in %s",
len(elements),
"in " + filename if filename else "",
)
return elements, np.asarray(positions), np.asarray(arr), kind == "F"


def parse_gen_file(filename):
"""Convert a provided DFTB+ .gen file into an array of
atomic numbers, positions and
Parameters
----------
filename: str
path to the .xyz file to read
Returns
-------
tuple of :obj:`np.ndarray`
List[Element], (N, 3) positions, (4, 3) lattice vectors, bool (if fractional)
read from the given file
"""
path = Path(filename)
return parse_gen_string(path.read_text(), filename=str(path.absolute()))
19 changes: 19 additions & 0 deletions src/chmpy/tests/fmt/test_gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from chmpy.fmt.gen import parse_gen_string, parse_gen_file
import unittest
import numpy as np
from .. import TEST_FILES


class GenFileTestCase(unittest.TestCase):
def test_parse_file(self):
els, pos, vecs, frac = parse_gen_file(TEST_FILES["example.gen"])
self.assertEqual(len(els), 76)
self.assertEqual(els[0].atomic_number, 1)
self.assertEqual(els[75].atomic_number, 8)

expected_coords_46 = np.array((0.3623979304, 0.6637420302, 0.8677686357))
np.testing.assert_allclose(pos[46, :], expected_coords_46, atol=1e-5)

np.testing.assert_allclose(np.zeros(3), vecs[0, :])

self.assertAlmostEqual(vecs[1, 0], 13.171)
82 changes: 82 additions & 0 deletions src/chmpy/tests/test_files/example.gen
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
76 F
H C O
1 1 0.9658052839E+00 0.2326325961E+00 0.7687699246E+00
2 1 0.8963703303E+00 0.5389962229E+00 0.9844595406E+00
3 1 0.6342630111E+00 0.4745391534E+00 0.5161534274E+00
4 1 0.5459923436E+00 0.1410933376E+00 0.5936881280E+00
5 1 0.8420784231E+00 0.5204573845E+00 0.6029239234E+00
6 1 0.5179665338E+00 0.8800071240E+00 0.2535595132E+00
7 1 0.6868754472E+00 0.1008380572E+01 0.3983723386E+00
8 1 0.9855964515E+00 0.6266057466E+00 0.4084760756E+00
9 1 0.8963595160E+00 0.9610316611E+00 0.4844496140E+00
10 1 0.6342714645E+00 0.2544426384E-01 0.1615604557E-01
11 1 0.5459943670E+00 0.3588770277E+00 0.9368914938E-01
12 1 0.8420877317E+00 -0.2044801417E-01 0.1029268975E+00
13 1 0.9658096468E+00 0.2673898859E+00 0.2687691690E+00
14 1 0.4820378757E+00 0.1199569656E+00 0.7464673927E+00
15 1 0.3131307039E+00 -0.8381852403E-02 0.6016400269E+00
16 1 0.1440720913E-01 0.3734336440E+00 0.5915140784E+00
17 1 0.1036471647E+00 0.3900120588E-01 0.5155451985E+00
18 1 0.3657266162E+00 0.9745544316E+00 0.9838528360E+00
19 1 0.4540061056E+00 0.6411003528E+00 0.9063301626E+00
20 1 0.1579103389E+00 0.1020472370E+01 0.8970694439E+00
21 1 0.9856001937E+00 0.8734260099E+00 0.9084804245E+00
22 1 0.6868873458E+00 0.4916144487E+00 0.8983805634E+00
23 1 0.3419057758E-01 0.7326420242E+00 0.7312217278E+00
24 1 0.3131422868E+00 0.5083786224E+00 0.1016471911E+00
25 1 0.1036579139E+00 0.4610215263E+00 0.1555214705E-01
26 1 0.5179749979E+00 0.6199647356E+00 0.7535661304E+00
27 1 0.4820477242E+00 0.3800170620E+00 0.2464723060E+00
28 1 0.4540051604E+00 0.8588700348E+00 0.4063274872E+00
29 1 0.3418658828E-01 0.7673829089E+00 0.2312227953E+00
30 1 0.1441162206E-01 0.1265960709E+00 0.9151727550E-01
31 1 0.1579022289E+00 0.4795397101E+00 0.3970669986E+00
32 1 0.3657197382E+00 0.5254274431E+00 0.4838489156E+00
33 2 0.8057534435E+00 0.1270111409E+00 0.1389014546E+00
34 2 0.1560363812E+00 0.3324791265E+00 0.8734584127E-01
35 2 0.8737977995E+00 0.2859949157E+00 0.2304533404E+00
36 2 0.2952056354E+00 0.4967520300E+00 0.7732890206E+00
37 2 0.1062871773E+00 0.1467017163E+00 0.1294236691E+00
38 2 0.1746735984E+00 0.5214054747E+00 0.7232973339E+00
39 2 0.6568640443E+00 0.8019767804E+00 0.7734385710E+00
40 2 0.2749313479E+00 0.1401116901E+00 0.6357146680E+00
41 2 0.1062825494E+00 0.3533180569E+00 0.6294196627E+00
42 2 0.2749395382E+00 0.3598894371E+00 0.1357200267E+00
43 2 0.1560287344E+00 0.1675363455E+00 0.5873402016E+00
44 2 0.3431481080E+00 0.1980068367E+00 0.2265817479E+00
45 2 0.3133493041E+00 0.8478841200E+00 0.9110335651E+00
46 2 0.1746740016E+00 0.9786022988E+00 0.2232990372E+00
47 2 0.3623979304E+00 0.6637420302E+00 0.8677686357E+00
48 2 0.1942457087E+00 0.8730060715E+00 0.8610983908E+00
49 2 0.3431439806E+00 0.3019795614E+00 0.7265798206E+00
50 2 0.6376026629E+00 0.3362504532E+00 0.1322436686E+00
51 2 0.6866497862E+00 0.1521181734E+00 0.8897363646E-01
52 2 0.8253285466E+00 0.2139436222E-01 0.7767054805E+00
53 2 0.7250818169E+00 0.6401049063E+00 0.8642999506E+00
54 2 0.8937251961E+00 0.8533087579E+00 0.8705810723E+00
55 2 0.8439838088E+00 0.6675277612E+00 0.9126657446E+00
56 2 0.7047968650E+00 0.9967424376E+00 0.7267215562E+00
57 2 0.6866438609E+00 0.3478705918E+00 0.5889718910E+00
58 2 0.6376002805E+00 0.1637315891E+00 0.6322431499E+00
59 2 0.1261990519E+00 0.7859860463E+00 0.2695439459E+00
60 2 0.8057470678E+00 0.3729928432E+00 0.6388996746E+00
61 2 0.3133445243E+00 0.6521060318E+00 0.4110314863E+00
62 2 0.1262025780E+00 0.7140289619E+00 0.7695435377E+00
63 2 0.8737938163E+00 0.2140170698E+00 0.7304533051E+00
64 2 0.1942403090E+00 0.6270007570E+00 0.3610968868E+00
65 2 0.8253284903E+00 0.4786108858E+00 0.2767038568E+00
66 2 0.6568597951E+00 0.6980067021E+00 0.2734358641E+00
67 2 0.7250733753E+00 0.8598949183E+00 0.3642933766E+00
68 2 0.8937210344E+00 0.6467109257E+00 0.3705763054E+00
69 2 0.3623964704E+00 0.8362419793E+00 0.3677676908E+00
70 2 0.8439761328E+00 0.8324888471E+00 0.4126584173E+00
71 2 0.7047963974E+00 0.5032469923E+00 0.2267204641E+00
72 2 0.2952064889E+00 0.3240321445E-02 0.2732900890E+00
73 3 0.5396545383E+00 0.7144317939E+00 0.2249486212E+00
74 3 0.4603487469E+00 0.2855305932E+00 0.7750786575E+00
75 3 0.5396594619E+00 0.7855378210E+00 0.7249506828E+00
76 3 0.4603534341E+00 0.2144434887E+00 0.2750791894E+00
0.0000000000E+00 0.0000000000E+00 0.0000000000E+00
0.1317100000E+02 0.0000000000E+00 0.0000000000E+00
0.0000000000E+00 0.4798000000E+01 0.0000000000E+00
-0.6051939240E+01 0.0000000000E+00 0.1181635339E+02

0 comments on commit e2e1c2e

Please sign in to comment.