GIT repositories md_scripts / master python / check_chirals.py
master

Tree @master (Download .tar.gz)

check_chirals.py @masterraw · history · blame

#!/usr/bin/env python2
"""
Checks the R/S-handedness of molecules stereocenters based on the coordinates of
the four atoms bound to a chiral center.
"""
import argparse 
import MDAnalysis
import numpy 
import sys



### ATOMDICT
# some atom lists hard-coded
atomdict={}
atomdict["LBPA22"] = ["O21", "C1", "C3", "HS", "O21'", "C1'", "C3'", "HS'"]
atomdict["LBPA33"] = ["OC2", "C1", "C3", "H2A", "OC2'", "C1'", "C3'", "H2A'"]



### DEFAULTS
coordinatefile="confout.gro"
resname="LBPA"
atomnames=atomdict["LBPA22"]



### PARSE ARGUMENTS
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("-c", help='Coordinate file')
parser.add_argument("-a", help='''Atoms bound to the chiral center
                                  (in order of priority). If there is n chiral
                                  centers, 4n atoms should be given.  If only
                                  one argument is given, some of the hard coded
                                  lists are used.''', nargs='+')
parser.add_argument("-r", help='Resname of the molecule to be checked.')
parser.add_argument("-l", help='Show hard coded atom lists.', action='store_true')
args = parser.parse_args()

if args.l:
    for i in atomdict:
        print("{0}: {1}".format(i, " ".join(atomdict[i])))
    sys.exit()

if args.c:
    coordinatefile = args.c
else:
    print("Using default coordinate file: " + coordinatefile)

if args.r:
    resname = args.r
else:
    print("Using default resname: " + resname)

if args.a:
    if len(args.a) == 1:
        if args.a[0] in atomdict:
            atomnames = atomdict[args.a[0]]
            print("Using atoms: " + ", ".join(atomnames))
        else:
            sys.exit("Atom list {0} is not known.".format(args.a[0]))

    elif len(args.a) % 4 > 0:
        sys.exit("Wrong number of atoms.")
    else:
        atomnames = args.a
else:
    print("Using default atoms: " + ", ".join(atomnames))



### OPEN FILE AND CHECK CHIRALS
universe = MDAnalysis.Universe(coordinatefile) 

# number of chiral centers
chirals = len(atomnames)/4

# loop through all residues
residues = universe.selectAtoms("resname " + resname).residues
for r in residues:

    handedness = [] # handedness of each chiral centers in residue

    # loop through all chiral centers
    for c in range(0,chirals):

        # get coordinates of four atoms
        coord = []
        for n in atomnames[4*c:4*c+4]:
            atom = getattr(r, n)
            coord.append(atom.position)

        # get the normal of plane spanned by three atoms
        vec12 = coord[1] - coord[0]                 # vector from atom1 to atom2
        vec13 = coord[2] - coord[0]                 # vector from atom1 to atom3
        crs123 = numpy.cross(vec12, vec13)          # plane normal vector

        # which side of the plane is the fourth atom?
        com123 = (coord[0] + coord[1] + coord[2])/3 # center of mass
        vec4 = coord[3] - com123                    # vector from the plane to atom4

        # Is the the plane normal vector parallel or antiparallel with vec4?
        dotp = numpy.dot(crs123, vec4)              # dot product
        if dotp < 0:
            # angle bigger than 90 degrees -> antiparallel -> "Sinister"
            handedness.append('S')
        else:
            # angle smaller than 90 degrees -> parallel -> "Rectus"
            handedness.append('R')

    print("{0}{1:5}{2}".format(resname, str(r.id), " ".join(handedness)))