forked from dbmagers/comp-chem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxyz.py
68 lines (56 loc) · 2.39 KB
/
xyz.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/opt/miniconda3/envs/python2.7/bin/python
# D. B. Magers
# 2.26.28
# converts xyz file from angstrom to bohr or vice versa
import argparse
from argparse import RawTextHelpFormatter
bohr_to_angstrom = 0.52917721067 # codata 2014 value
# argument parser
description = 'Converts xyz file units to angstrom or bohr.\nxyz file is assumed to follow the the standard format.\nExample:\n 2\n comment line\n H 0.0000 0.0000 0.3705\n H 0.0000 0.0000 -0.3705\n ...'
parser = argparse.ArgumentParser(description=description, formatter_class=RawTextHelpFormatter)
parser.add_argument('-u','--unit', choices=["angstrom","bohr"], help="Set unit to convert to", default='angstrom')
parser.add_argument('-i', '--input', help='Set the name of the input file. (Default: geo.xyz)', default='geo.xyz')
parser.add_argument('-o', '--output', help='Set the name of the output file. (Default: geo_[unit].xyz)')
parser.add_argument('-p', '--print', action='store_true', help='Print output to screen instead of file. Overrides -o flag.')
args = vars(parser.parse_args())
# read input file
f = open(args['input'], "r")
inputLines = f.readlines()
f.close()
inputLines = [x.strip() for x in inputLines]
# define variables
unit = args['unit']
file_length = len(inputLines)
output = args['output']
if output is None:
output = 'geo_'+unit+'.xyz'
# check for consistency
# does num atoms on first line match file
# add units to file comment line
inputLines[1] +=' ['+unit+']'
# determine number of digits to past decimal to print, look at z component of first atom for ref
digits = str(len(inputLines[2].split()[-1].split('.')[-1]))
# do conversion and replace
for i, line in enumerate(inputLines[2:]):
split_line = line.split()
for j,item in enumerate(split_line[1:]):
if unit == 'angstrom':
temp = str(('{0:.'+digits+'f}').format(float(item) * bohr_to_angstrom))
elif unit == 'bohr':
temp = str(('{0:.'+digits+'f}').format(float(item) / bohr_to_angstrom))
# add space for positive numbers for padding
if not temp.startswith('-'):
temp = ' '+temp
temp = ' '+temp
split_line[j+1] = temp
line = " ".join(split_line)
inputLines[i+2] = line
# write file
if not args['print']:
with open(output,'w') as f_out:
for item in inputLines:
f_out.write("%s\n" % item)
f_out.close()
else:
for item in inputLines:
print(item)