Mod:Hunt Research Group:position symbolic zmat
Jump to navigation
Jump to search
create an input file
- you will likely want to extract a geometry from a log file first
- extract_structure.py filename (on your log file with without the .log extension)
- this will give you a file filename.xyz
- copy this to filename.inp and add the required infomation (detailed below) to the top of the file
- otherwise create a filename.inp file
- below is the file for water (water.inp)
- info is given on each line
- number of atoms
- a b c
- where
- a atom to center the coordinates at (ie will be 0.0 0.0 0.0) here atom 1
- b atom you want along the x-axis, in my case atom 2
- c atom that will form the xy-plane along with a and b
- 0.0 0.0 0.0
- replace ONE of these with the angle you want to rotate the a-b bond in the xy, xz or yz plane
- here I have chosen a 10 degree rotation in the xy plane
- currently you can only give ONE non-zero angle here
- from then on follows your atomic coordinates (in Angstrom)
- note that you can insert a file using vi with the (comand mode)
:r filenamecommand
3 1 2 3 10.0 0.0 0.0 O 1.995482 0.000000 -0.000000 H 2.637933 -0.000000 0.697270 H 2.637933 0.000000 -0.697270
run the code
- run the code
pos_zmat.py water
- - the geom.inp file is an argument (without .inp)
- you should see something like the following
[tricia@]/Users/tricia/files/work/jobs/musa $ pos_zmat.py water directory is /Users/tricia/Files/work/jobs/musa input file is water.inp symbolic z-matrix output file is water_osymb.com xyz coord output file is water_new.xyz total number of atoms 3 center at atom 1 x-axis along bond to atom 2 atoms in the xy-plane 3 rotation of a-b around xy-pane (z-axis) by 10.0 centered x-axis aligned atoms aligned in xy plane a-b vector rotated done!
output files
- you should see 2 files geom_new.xyz and geom_osymb.xyz
- - you can see that atom 1 is at the origin
- - you can see that the bond O-H is almost aligned with the x-axis, it has been rotated in the xy plane 10 degrees.
- - the molecule is in the xy plane formed by atoms 1,2,3
- - note that 3 dummy atoms are added on the position of the x,y and z axies to help with visualisation
- geom_new.xyz gives the new coordinate file in the standard format
6 title O 0.000000 0.000000 0.000000 H 0.933714 0.164639 0.000000 H -0.240373 0.917142 -0.000000 Xx 4.000000 0.000000 0.000000 Xy 0.000000 4.000000 0.000000 Xz 0.000000 0.000000 4.000000
- geom_osymb.xyz gives the coordinates in the symbolic z-matrix format
%nprocshared=16 %mem=30GB %chk=water.chk # opt b3lyp/6-311+g(d,p) int=ultrafine scf=conver=10 empiricaldispersion=gd3bj nosymm geom=z-matrix Title Card Required 0 1 O 0 x1 y1 z1 H 0 x2 y2 z2 H 0 x3 y3 z3 Xx 0 x4 y4 z4 Xy 0 x5 y5 z5 Xz 0 x6 y6 z6 x1 = 0.000000 y1 = 0.000000 z1 = 0.000000 x2 = 0.933714 y2 = 0.164639 z2 = 0.000000 x3 =-0.240373 y3 = 0.917142 z3 =-0.000000 x4 = 4.000000 y4 = 0.000000 z4 = 0.000000 x5 = 0.000000 y5 = 4.000000 z5 = 0.000000 x6 = 0.000000 y6 = 0.000000 z6 = 4.000000
pos_zmat.py
#!/opt/local/bin/python3
#
# pos_zmat.py
#
# python script to take cartesian coords and orient a molecule and convert to a symbolic z-matrix format.
# the *.xyz file can be draged into jmol
# the symbolic matrix file is saved in *.com format
#
# to run the script you need an input file *.inp
# if you have a log file run extract_structure.py filename (without log extension) first to get the xyz coordinates
# then copy this file to filename.inp and add the following at the top
# no of atoms
# a b c
# where
# a atom to center at
# b x-axis will align along bond a-b
# c the atoms a-b-c will form the xy plane
# this means the z-axis is perpendicular to the plane of these 3 atoms
# xx yy zz
# the angle to rotate the a-b bond (vector) in the xy, xz, or yz planes
# currently only active for one axis at a time!
# then follows a section for atomic symbol/atomic no and coordinates
#
# to run the script type python pos_zmat.py input_file_name (without extension)
#
# this will produce the files
# filename_new.xyz (for jmol)
# filename_osymb.com (for G16)
#
import sys
import os
import math
import numpy as np
dir=os.getcwd()
from numpy import (array, dot, arccos, clip)
from numpy.linalg import norm
#
if len(sys.argv) >= 3:
print('to run the script please type: python symb_zmat.py input_file_name (without extension)')
sys.exit()
else:
base=str(sys.argv[1])
file=base+'.inp'
out1=base+'_osymb.com'
out2=base+'_new.xyz'
s='directory is '
print('{0:}{1:}'.format(s,dir))
s='input file is '
print('{0:}{1:}'.format(s,file))
s='symbolic z-matrix output file is '
print('{0:}{1:}'.format(s,out1))
s='xyz coord output file is '
print('{0:}{1:}'.format(s,out2))
#close if
#
# set some defaults
atomtotal=0
atomcenter=0
atomxaxis=0
atomyaxis=0
xa=0.0
xb=0.0
xc=0.0
rotanglex=0.0
rotangley=0.0
rotanglez=0.0
dipole=0.0
nz1=0
nz2=0
nz3=0
a=[]
col_atom=[]
col_x=[]
col_y=[]
col_z=[]
newcol_x=[]
newcol_y=[]
newcol_z=[]
v1=np.zeros(3,dtype=float)
v2=np.zeros(3,dtype=float)
v3=np.zeros(3,dtype=float)
# open file and read lines one by one
f=open(file,"r")
#total number of atoms
line =f.readline()
#print('{0:}'.format(line))
atomtotal=int(line.rstrip())
s='total number of atoms '
print('{0:}{1:}'.format(s,atomtotal))
#read in data center atom, xaxis atom, xy plane atom
line =f.readline()
#print('{0:}'.format(line))
a=line.rstrip().split()
atomcenter=int(a[0])
atomxaxis=int(a[1])
atomyaxis=int(a[2])
s='center at atom '
print('{0:}{1:}'.format(s,atomcenter))
s='x-axis along bond to atom '
print('{0:}{1:}'.format(s,atomxaxis))
s='atoms in the xy-plane '
print('{0:}{1:}'.format(s,atomyaxis))
#read in the rotation angles (degrees)
line =f.readline()
b1,c1,d1=line.rstrip().split()
rotplanexy=float(b1)
rotplanexz=float(c1)
rotplaneyz=float(d1)
if rotplanexy != 0:
s='rotation of a-b around xy-pane (z-axis) by '
print('{0:}{1:}'.format(s,rotplanexy))
elif rotplanexz != 0:
s='rotation a-b around xz-pane (y-axis) by '
print('{0:}{1:}'.format(s,rotplanexz))
elif rotplaneyz != 0:
s='rotation a-b around yz-pane (x-axis) by '
print('{0:}{1:}'.format(s,rotplaneyz))
else:
print('no rotations')
#endif
#read in atoms and coordinates
mx=np.zeros(atomtotal,dtype=float)
my=np.zeros(atomtotal,dtype=float)
mz=np.zeros(atomtotal,dtype=float)
mx1=np.zeros(atomtotal,dtype=float)
my1=np.zeros(atomtotal,dtype=float)
mz1=np.zeros(atomtotal,dtype=float)
mxf=np.zeros(atomtotal,dtype=float)
myf=np.zeros(atomtotal,dtype=float)
mzf=np.zeros(atomtotal,dtype=float)
#print(ny)
n=0
while n < atomtotal :
line =f.readline()
# print('{0:}'.format(line))
a1,b1,c1,d1=line.rstrip().split()
col_atom.append(a1)
col_x.append(float(b1))
col_y.append(float(c1))
col_z.append(float(d1))
n=n+1
#close while
#turn list into a numpty array
mx=np.array(col_x)
my=np.array(col_y)
mz=np.array(col_z)
#print(ny)
#center at atomcenter
c=atomcenter-1
#print('center at {0:} {1:9.6f},{2:9.6f},{3:9.6f}'.format(atomcenter,col_x[c],col_y[c],col_z[c]))
mx = mx - mx[c]
my = my - my[c]
mz = mz - mz[c]
print('centered')
#align along x-y atom vector
a=atomcenter-1
b=atomxaxis-1
#print('align along atom vector {0:} {1:}'.format(atomcenter,atomxaxis))
#print('old atom coords {0:} {1:9.4f},{2:9.4f},{3:9.4f}'.format(atomxaxis,col_x[b],col_y[b],col_z[b]))
#print('new atom coords {0:} {1:9.4f},{2:9.4f},{3:9.4f}'.format(atomxaxis,mx[b],my[b],mz[b]))
v0=np.zeros(2,dtype=float)
vxy=np.zeros(2,dtype=float)
vxz=np.zeros(2,dtype=float)
print('x-axis aligned')
#first rotate xy plane
#ie rotate around z-axis
#note that atan2 give the correct quadrant
theta=math.atan2(my[b],mx[b])
t2_deg=math.degrees(theta)
#print('theta ',round(theta,2), 'radians')
#print('theta ',round(t2_deg,2), 'degrees')
#rotate backwards!
t2_rad=-theta
mx1=mx*np.cos(t2_rad)-my*np.sin(t2_rad)
my1=mx*np.sin(t2_rad)+my*np.cos(t2_rad)
mz1=mz
#print('after xy rotation {0:9.4f}, {1:9.4f}, {2:9.4f}'.format(mx1[b],my1[b],mz1[b]))
#then rotate in xz plane
#ie rotate "down"around y-axis
theta=math.atan2(mz1[b],mx1[b])
t2_deg=math.degrees(theta)
#print('theta ',round(theta,2), 'radians')
#print('theta ',round(t2_deg,2), 'degrees')
#rotate backwards!
t2_rad=-theta
mx=mx1*np.cos(t2_rad)-mz1*np.sin(t2_rad)
my=my1
mz=mx1*np.sin(t2_rad)+mz1*np.cos(t2_rad)
#print('after xz rotation {0:9.4f}, {1:9.4f}, {2:9.4f}'.format(mx[b],my[b],mz[b]))
#then rotate in yz plane
#ie rotate "down"around x-axis
#to bring atom c into the xy plane
b=atomyaxis-1
theta=math.atan2(mz[b],my[b])
t2_deg=math.degrees(theta)
#print('theta ',round(theta,2), 'radians')
#print('theta ',round(t2_deg,2), 'degrees')
#rotate backwards!
t2_rad=-theta
mx1=mx
my1=my*np.cos(t2_rad)-mz*np.sin(t2_rad)
mz1=my*np.sin(t2_rad)+mz*np.cos(t2_rad)
#print('after yz rotation {0:9.4f}, {1:9.4f}, {2:9.4f}'.format(mx1[b],my1[b],mz1[b]))
print('atoms aligned in xy plane')
#reset so mx,my,mz contain current values too
mx=mx1
my=my1
mz=mz1
#if rotangle is not zero rotate the bond in xy,xz or yz planes
t=0
if rotplanexy != 0.0 :
a=np.deg2rad(rotplanexy)
mx1=mx*np.cos(a)-my*np.sin(a)
my1=mx*np.sin(a)+my*np.cos(a)
mz1=mz
t=1
# endif
if t==0 and rotplanexz != 0.0 :
print('rotate in xz plane')
a=np.deg2rad(rotplanexz)
mx1=mx*np.cos(a)-mz*np.sin(a)
my1=my
mz1=mx*np.sin(a)+mz*np.cos(a)
t=1
#endif
if t==0 and rotplaneyz != 0.0 :
a=np.deg2rad(rotplaneyz)
mx1=mx
my1=my*np.cos(a)-mz*np.sin(a)
mz1=my*np.sin(a)+mz*np.cos(a)
t=1
#endif
print('a-b vector rotated')
mfx=mx1
mfy=my1
mfz=mz1
#now write to the _new.xyz file
c=open(out2,"w")
c.write('{0:<3} \n'.format(atomtotal+3))
c.write('{0:<5} \n'.format('title'))
n=0
while n < atomtotal:
c.write('{0:<3} {1:9.6f} {2:9.6f} {3:9.6f} \n'.format(col_atom[n],mfx[n],mfy[n],mfz[n]))
n=n+1
#close while
#postions dummy atoms on axis
p=4.0
c.write('{0:<3} {1:9.6f} {2:9.6f} {3:9.6f} \n'.format('Xx',p,0.0,0.0))
c.write('{0:<3} {1:9.6f} {2:9.6f} {3:9.6f} \n'.format('Xy',0.0,p,0.0))
c.write('{0:<3} {1:9.6f} {2:9.6f} {3:9.6f} \n'.format('Xz',0.0,0.0,p))
#
#now write to the _symb.com file
c=open(out1,"w")
s="%nprocshared=16\n%mem=30GB\n"
c.write('{0:}'.format(s))
s='%chk='+base+'.chk\n'
c.write('{0:}'.format(s))
s="# opt b3lyp/6-311+g(d,p) int=ultrafine scf=conver=10 empiricaldispersion=gd3bj \n "
c.write('{0:}'.format(s))
s=" geom=z-matrix \n \n "
c.write('{0:}'.format(s))
s="Title Card Required\n\n"
c.write('{0:}'.format(s))
charge=0
multiplicity=1
c.write('{0:} {1:} \n'.format(charge,multiplicity))
#
#write out z-matrix
n=0
while n < atomtotal:
m=n+1
c.write('{0:} 0 x{1:<4} y{2:<4} z{3:<4} \n'.format(col_atom[n],m,m,m))
n=n+1
#close while
m=n+1
c.write('{0:} 0 x{1:<4} y{2:<4} z{3:<4} \n'.format('Xx',m,m,m))
m=n+2
c.write('{0:} 0 x{1:<4} y{2:<4} z{3:<4} \n'.format('Xy',m,m,m))
m=n+3
c.write('{0:} 0 x{1:<4} y{2:<4} z{3:<4} \n'.format('Xz',m,m,m))
c.write('\n'.format())
#write out variables
n=0
while n < atomtotal:
m=n+1
c.write(' x{0:<3}={1:>9.6f} \n y{2:<3}={3:9.6f} \n z{4:<3}={5:9.6f} \n'.format(m,mfx[n],m,mfy[n],m,mfz[n]))
n=n + 1
#close while
m=n+1
c.write(' x{0:<3}={1:>9.6f} \n y{2:<3}={3:9.6f} \n z{4:<3}={5:9.6f} \n'.format(m,p,m,0.0,m,0.0))
m=n+2
c.write(' x{0:<3}={1:>9.6f} \n y{2:<3}={3:9.6f} \n z{4:<3}={5:9.6f} \n'.format(m,0.0,m,p,m,0.0))
m=n+3
c.write(' x{0:<3}={1:>9.6f} \n y{2:<3}={3:9.6f} \n z{4:<3}={5:9.6f} \n'.format(m,0.0,m,0.0,m,p))
c.write('\n\n'.format())
# close all open files
f.close()
c.close()
print('done!')
exit(0)
#