From 88893e7963248435387b4ead95b7bf8507b5eca6 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Thu, 21 Jul 2022 10:02:57 +0200 Subject: [PATCH 1/2] Make output precision configurable --- gc.py | 8 ++++++-- gcutil.py | 29 +++++++++++++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/gc.py b/gc.py index 37f848f..d335211 100755 --- a/gc.py +++ b/gc.py @@ -36,6 +36,8 @@ parser.add_argument("--avar", dest="avar", required=False, type=bool, default=False, help="Print angles as variables") parser.add_argument("--dvar", dest="dvar", required=False, type=bool, default=False, help="Print dihedrals as variables") parser.add_argument("--allvar", dest="allvar", required=False, type=bool, default=False, help="Print all values as variables") +parser.add_argument("--precision", dest="precision", required=False, type=int, default=8, help="Sets the precision of coordinates and distances") +parser.add_argument("--angle_precision", dest="angle_precision", required=False, type=int, default=5, help="Sets the precision of angles") args = parser.parse_args() xyzfilename = args.xyzfile @@ -44,6 +46,8 @@ rvar = args.rvar or args.allvar avar = args.avar or args.allvar dvar = args.dvar or args.allvar +precision = args.precision +angle_precision = args.angle_precision if (xyzfilename == None and zmatfilename == None): print("Please specify an input geometry") @@ -51,7 +55,7 @@ elif (zmatfilename == None): xyzarr, atomnames = gc.readxyz(xyzfilename) distmat = gc.distance_matrix(xyzarr) - gc.write_zmat(xyzarr, distmat, atomnames, rvar=rvar, avar=avar, dvar=dvar) + gc.write_zmat(xyzarr, distmat, atomnames, rvar=rvar, avar=avar, dvar=dvar, distprecision=precision, angleprecision=angle_precision) else: atomnames, rconnect, rlist, aconnect, alist, dconnect, dlist = gc.readzmat(zmatfilename) - gc.write_xyz(atomnames, rconnect, rlist, aconnect, alist, dconnect, dlist) + gc.write_xyz(atomnames, rconnect, rlist, aconnect, alist, dconnect, dlist, precision=precision) diff --git a/gcutil.py b/gcutil.py index 84de830..481b4f2 100644 --- a/gcutil.py +++ b/gcutil.py @@ -158,10 +158,13 @@ def dihedral(xyzarr, i, j, k, l): chi = chi + 360.0 return chi -def write_zmat(xyzarr, distmat, atomnames, rvar=False, avar=False, dvar=False): +def write_zmat(xyzarr, distmat, atomnames, rvar=False, avar=False, dvar=False, distprecision=8, angleprecision=5): """Prints a z-matrix from xyz coordinates, distances, and atomnames, optionally with the coordinate values replaced with variables. """ + distformat = '{:>' + str(distprecision + 6) + '.' + str(distprecision) + 'f}' + angleformat = '{:>' + str(angleprecision + 6) + '.' + str(angleprecision) + 'f}' + npart, ncoord = xyzarr.shape rlist = [] # list of bond lengths alist = [] # list of bond angles (degrees) @@ -177,7 +180,7 @@ def write_zmat(xyzarr, distmat, atomnames, rvar=False, avar=False, dvar=False): if (rvar): r = 'R1' else: - r = '{:>11.5f}'.format(rlist[0]) + r = distformat.format(rlist[0]) print('{:<3s} {:>4d} {:11s}'.format(n, 1, r)) if npart > 2: @@ -187,13 +190,13 @@ def write_zmat(xyzarr, distmat, atomnames, rvar=False, avar=False, dvar=False): if (rvar): r = 'R2' else: - r = '{:>11.5f}'.format(rlist[1]) + r = distformat.format(rlist[1]) alist.append(angle(xyzarr, 2, 0, 1)) if (avar): t = 'A1' else: - t = '{:>11.5f}'.format(alist[0]) + t = angleformat.format(alist[0]) print('{:<3s} {:>4d} {:11s} {:>4d} {:11s}'.format(n, 1, r, 2, t)) @@ -205,35 +208,37 @@ def write_zmat(xyzarr, distmat, atomnames, rvar=False, avar=False, dvar=False): if (rvar): r = 'R{:<4d}'.format(i) else: - r = '{:>11.5f}'.format(rlist[i-1]) + r = distformat.format(rlist[i-1]) alist.append(angle(xyzarr, i, i-3, i-2)) if (avar): t = 'A{:<4d}'.format(i-1) else: - t = '{:>11.5f}'.format(alist[i-2]) + t = angleformat.format(alist[i-2]) dlist.append(dihedral(xyzarr, i, i-3, i-2, i-1)) if (dvar): d = 'D{:<4d}'.format(i-2) else: - d = '{:>11.5f}'.format(dlist[i-3]) + d = angleformat.format(dlist[i-3]) print('{:3s} {:>4d} {:11s} {:>4d} {:11s} {:>4d} {:11s}'.format(n, i-2, r, i-1, t, i, d)) if (rvar): print(" ") for i in range(npart-1): - print('R{:<4d} = {:>11.5f}'.format(i+1, rlist[i])) + print('R{:<4d} = '.format(i+1) + distformat.format(rlist[i])) if (avar): print(" ") for i in range(npart-2): - print('A{:<4d} = {:>11.5f}'.format(i+1, alist[i])) + print('A{:<4d} = '.format(i+1) + angleformat.format(alist[i])) if (dvar): print(" ") for i in range(npart-3): - print('D{:<4d} = {:>11.5f}'.format(i+1, dlist[i])) + print('D{:<4d} = '.format(i+1) + angleformat.format(dlist[i])) -def write_xyz(atomnames, rconnect, rlist, aconnect, alist, dconnect, dlist): +def write_xyz(atomnames, rconnect, rlist, aconnect, alist, dconnect, dlist, precision=8): """Prints out an xyz file from a decomposed z-matrix""" + coordformat = '{:>' + str(precision + 6) + '.' + str(precision) + 'f}' + npart = len(atomnames) print(npart) print('INSERT TITLE CARD HERE') @@ -300,4 +305,4 @@ def write_xyz(atomnames, rconnect, rlist, aconnect, alist, dconnect, dlist): # print results for i in range(npart): - print('{:<4s}\t{:>11.5f}\t{:>11.5f}\t{:>11.5f}'.format(atomnames[i], xyzarr[i][0], xyzarr[i][1], xyzarr[i][2])) + print(('{:<4s}\t' + coordformat + '\t' + coordformat + '\t' + coordformat).format(atomnames[i], xyzarr[i][0], xyzarr[i][1], xyzarr[i][2])) From 8abb901a1408fb5e73b7d69f6eb14f023bea188f Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Thu, 21 Jul 2022 10:07:24 +0200 Subject: [PATCH 2/2] Formatted & extended README --- README.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 351c587..fb5b34d 100644 --- a/README.md +++ b/README.md @@ -3,44 +3,66 @@ A python utility to convert between Cartesian and Z-matrix geometries. RECENTLY ADDED: when converting from zmat to xyz, variables can now be read with no caveats. -Running the below will print the output to the standard output stream (i.e. the terminal in most cases); this can be piped into a file in the usual way, e.g. +Running the below will print the output to the standard output stream (i.e. the terminal in most cases); this can be piped into a file in the usual +way, e.g. +```bash python3 gc.py -xyz test.xyz > test.zmat +``` ## Usage To convert from XYZ to Z-matrix: +```bash python3 gc.py -xyz test.xyz +``` for files in XYZ format, i.e. -Number of atoms +``` + TITLE CARD -Atom x y z + -Atom x y z + ... +``` The default is to print the values of distances/angles/dihedrals. These can instead be printed as variables with the options +``` --rvar=True --avar=True --dvar=True +``` respectively. Alternative +``` --allvar=True +``` will set all the above to true. To convert from Z-matrix to XYZ: +```bash python gc.py -zmat test.zmat +``` -for files containing a Z-matrix. This no longer assumes that the Z-matrix has values not variables for distances/angles/dihedrals, and can read variables with no additional options. +for files containing a Z-matrix. This no longer assumes that the Z-matrix has values not variables for distances/angles/dihedrals, and can read +variables with no additional options. +The precision of the output can be changed by means of the +``` +--precision=12 +--angle_precision=4 +``` +options. These affect the precision of the printed out coordinates and distances and the angles respectively. The first option has effects for both +XYZ and Z-matrix format, whereas the latter only applies to Z-matrices. +