File: hbond.py

package info (click to toggle)
pdb2pqr 1.8-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 8,576 kB
  • sloc: python: 24,897; sh: 12,005; cpp: 9,831; xml: 9,098; makefile: 355; ansic: 36
file content (161 lines) | stat: -rw-r--r-- 6,986 bytes parent folder | download | duplicates (2)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
"""
    Hbond extension

    Find all hydrogen bonds as determined by the cutoffs specified.
    Uses PDB2PQR to determine donors and acceptors, and displays
    all available bonds to file. 
    
    The original bonding parameters were an angle of 20.0, 
    distance of 3.30, and using the old method for calculating 
    distance.
    
    The original parameters for WHAT-IF output was an angle of
    90.0, distance of 3.30, and using the old method for 
    calculating distance. 

    Authors:  Todd Dolinsky, Michael J Bradley, Julie Mitchell, and Kyle Monson
"""

__date__ = "17 February 2006"
__author__ = "Todd Dolinsky, Michael J Bradley, Julie Mitchell, and Kyle Monson"
# NOTE: This extension edited and updated on 05 August 2008 by Michael J Bradley
# and again on 17 October by Kyle Monson.

# NOTE: The current defaults for hbonds used below were utilized in the following study:
#Bradley MJ, Chivers PT, Baker NA. Molecular dynamics simulation of the 
#Escherichia coli NikR protein: Equilibrium conformational fluctuations reveal 
#inter-domain allosteric communication pathways. Journal of Molecular Biology, 378, 
#1155-1173, 2008.  http://dx.doi.org/10.1016/j.jmb.2008.03.010

from src.utilities import distance, getAngle
from src.routines import Cells
from math import cos
import extensions

ANGLE_CUTOFF = 30.0       # A - D - H(D) angle
DIST_CUTOFF = 3.4         # D to A distance

def addExtensionOptions(extensionGroup):
    """
        Add options to set output type, angle cutoff, distance cutoff, and distance calculating method.
    """
    extensionGroup.add_option('--whatif', dest='whatif', action='store_true', default=False,
                              help='Change hbond output to WHAT-IF format.')
    
    extensionGroup.add_option('--angle_cutoff', dest='angle_cutoff',  type="float", action='store', default=ANGLE_CUTOFF,
                              help='Angle cutoff to use when creating hbond data (default %s)' % ANGLE_CUTOFF)
    
    extensionGroup.add_option('--distance_cutoff', dest='distance_cutoff',  type="float", action='store', default=DIST_CUTOFF,
                              help='Distance cutoff to use when creating hbond data (default %s)' % DIST_CUTOFF)
    
    extensionGroup.add_option('--old_distance_method', dest='old_distance_method', action='store_true', default=False,
                              help='Use distance from donor hydrogen to acceptor to calculate distance used with --distance_cutoff.')

def usage():
    return 'Print a list of hydrogen bonds to {output-path}.hbond'

#TODO: replace this with a ''.format() call.
def _residueString(residue, name):
    return '%4d %-4s (%4d  ) %s     %-4s' % \
        (residue.resSeq, residue.name, residue.resSeq, residue.chainID, name)

def create_hbond_output(routines, outfile, whatif=False, 
                                           angleCutoff=ANGLE_CUTOFF, 
                                           distanceCutoff=DIST_CUTOFF, 
                                           oldDistanceMethod=False):

    routines.write("Printing hydrogen bond list...\n")
    
    output = extensions.extOutputHelper(routines, outfile)
    
    cellsize = int(distanceCutoff + 1.0 + 1.0) 
    protein = routines.protein
    routines.setDonorsAndAcceptors()
    routines.cells = Cells(cellsize)
    routines.cells.assignCells(protein)

    for donor in protein.getAtoms():

        # Grab the list of donors
        if not donor.hdonor: 
            continue
        donorhs = []
        for bond in donor.bonds:
            if bond.isHydrogen(): 
                donorhs.append(bond)
        if donorhs == []: 
            continue

        # For each donor, grab all acceptors
        closeatoms = routines.cells.getNearCells(donor)
        for acc in closeatoms:
            if not acc.hacceptor: 
                continue
            if donor.residue == acc.residue: 
                continue
            
            #TODO: do we need to do this for plain hbond stuff?
            if whatif and (donor.residue.chainID == acc.residue.chainID): 
                continue
            
            # Do new style distance check
            if not oldDistanceMethod:
                dist = distance(donor.getCoords(), acc.getCoords())
                if dist > distanceCutoff:
                    continue
            
            for donorh in donorhs:

                # Do old style distance check       
                if oldDistanceMethod:
                    dist = distance(donorh.getCoords(), acc.getCoords())
                    if dist > distanceCutoff: 
                        continue
                    
                # Do angle check
                angle = getAngle(acc.getCoords(), donor.getCoords(), donorh.getCoords())
                if angle > angleCutoff: 
                    continue
                
                if whatif:
                    if (donor.tempFactor > 60.0): 
                        continue
                    if (acc.tempFactor > 60.0): 
                        continue
                    
                    thisBstring='B' if donor.isBackbone() else 'S'
                    thatBstring='B' if acc.isBackbone() else 'S'

                    score= (1.7/dist) * cos(angle * 3.142 / 180.0)
                    output.write(_residueString(donor.residue, donor.name))
                    output.write('-> ')
                    output.write(_residueString(acc.residue, acc.name))
                    output.write('Sym=   1 Val= %6.3lf  DA=%6.2f  DHA=%6.2f (%s-%s)\n' % 
                                 (score, dist, angle, thisBstring, thatBstring))
#                    outfile.write("%4d %-4s (%4d  ) %s     %-4s-> %4d %-4s (%4d  ) %s     %-4sSym=   1 Val= %6.3lf  DA=%6.2f  DHA=%6.2f (%s-%s)\n" % \
#                      (donor.residue.resSeq,donor.residue.name,donor.residue.resSeq, donor.residue.chainID,donor.name,acc.residue.resSeq,acc.residue.name,acc.residue.resSeq, acc.residue.chainID,acc.name, score, dist, angle, thisBstring, thatBstring)) 

                else:
                    s = "Donor: %s %s\tAcceptor: %s %s\tdist: %.2f\tAngle: %.2f\n" % \
                        (donor.residue, donor.name, acc.residue, acc.name, dist, angle)
                    output.write(s) 
                    
    routines.write("\n")

def run_extension(routines, outroot, options):
    """
        Print a list of hydrogen bonds.

        Parameters
            routines:  A link to the routines object
            outroot:   The root of the output name
            options:   options object 
    """
    
    outname = outroot + ".hbond"
    with open(outname, "w") as outfile:
        create_hbond_output(routines, outfile, whatif=options.whatif, 
                                               angleCutoff=options.angle_cutoff,
                                               distanceCutoff=options.distance_cutoff,
                                               oldDistanceMethod=options.old_distance_method)