-
Notifications
You must be signed in to change notification settings - Fork 0
/
volumeanalysis_parallel.py
182 lines (154 loc) · 6.58 KB
/
volumeanalysis_parallel.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
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/env python
import argparse
import gencavitylib
import numpy
import os
import subprocess
import tempfile
import multiprocessing
import types
import copy_reg
def _pickle_method(m):
if m.im_self is None:
return getattr, (m.im_class, m.im_func.func_name)
else:
return getattr, (m.im_self, m.im_func.func_name)
copy_reg.pickle(types.MethodType, _pickle_method)
class VolumeAnalysis(object):
expecttemplate = '''\
#!/usr/local/bin/expect
spawn /gscratch3/lchong/ajd98/apps/voidoo_linux/lx_voidoo
expect "Type of calculation (C/V/R/Q) ? (C)"
send "V\r"
expect "Do you want extensive output ? (N)"
send "\r"
expect "Library file ? (cavity.lib)"
send "%LIBRARYFILE%\r"
expect "PDB file name ? (in.pdb)"
send "%PDBFILE%\r"
expect "Primary grid spacing (A) ? ( 1.000)"
send "\r"
expect "Probe radius (1.4 A for water) ? ( 0.000) "
send "\r"
expect " Nr of volume-refinement cycles ? ( 10) "
send "30\r"
expect "Grid-shrink factor ? ( 0.900) "
send "\r"
expect " Convergence criterion (A3) ? ( 0.100)"
send ".5\r"
expect " Convergence criterion (%) ? ( 0.100) "
send ".001\r"
expect "Create protein-surface plot file ? (N) "
send "\r"
expect "***** VOIDOO ***** VOIDOO ***** VOIDOO ***** VOIDOO ***** VOIDOO ***** "
send "\r"
'''
nprocesses = 16
def __init__(self):
self._parse_args()
self.generate_cavity_lib()
self.volumes = []
self.go()
def _parse_args(self):
parser = argparse.ArgumentParser()
parser.add_argument('--maindir', dest='maindir',
help='The main simulation directory '
'(e.g., ff14sb.xray.1).',
required=True)
parser.add_argument('--topology', dest='topologypath',
help='The path to the topology files',
required=True)
parser.add_argument('--outdir', dest='outdirpath',
help='The path to the output directory.',
required=True)
self.args = parser.parse_args()
def get_simname(self):
simname = self.args.maindir.split('/')[-1]
return simname
def generate_cavity_lib(self):
self.cavitylibpath = os.path.join(self.args.outdirpath,
'cavity.lib.autogen')
gencavitylib.CavityLibGen(self.args.topologypath, self.cavitylibpath)
# Now read the file we just wrote, and remove the "RESI" entries for
# residues that should not be included in the volume calculation
with open(self.cavitylibpath,'r') as f:
lines = f.readlines()
newlines = []
for line in lines:
if ('WAT' in line) or ('Cl-' in line) or ('Cl' in line):
pass
elif 'nan' in line:
newlines.append(line.replace('nan','0.000'))
else:
newlines.append(line)
# Write the filtered list back to the file.
with open(self.cavitylibpath, 'w') as f:
f.writelines(newlines)
def runvoidoo(self, pdbfilename, expectfilename, tpid):
'''
Run voidoo on the pdb file with path
"pdbfile.name" + ".pdb." + str(tpid)
using the named temporary file name "expectfilename" for the expect script that
controls voidoo
'''
expectcmd = self.expecttemplate
expectcmd = expectcmd.replace('%LIBRARYFILE%',self.cavitylibpath)
pdbpath = "{:s}.pdb.{:d}".format(pdbfilename, tpid)
expectcmd = expectcmd.replace('%PDBFILE%', pdbpath)
with open(expectfilename, 'w+') as expectfile:
expectfile.write(expectcmd)
expectfile.flush()
process = subprocess.Popen(['expect', expectfile.name],
stdout=subprocess.PIPE)
process.wait()
stdout, stderr = process.communicate()
# Finally, parse the output from VOIDOO
s = [line for line in stdout.split('\n') if ("Protein volume (A3)" in line)][-1]
volume = float(s.split()[5][:-1])
# Reset the expect script (delete its contents)
expectfile.seek(0)
#expectfile.file.truncate()
expectfile.truncate()
# Delete the pdb file
os.remove(pdbpath)
return volume
def runvoidoowrapper(self, args):
'''
args should be a tuple that may be passed to self.runvoidoo as args.
'''
return self.runvoidoo(*args)
def go(self):
print("Using {:d} processes".format(self.nprocesses))
pool = multiprocessing.Pool(self.nprocesses)
expectfiles = [tempfile.NamedTemporaryFile() \
for i in range(100)]
for segid in range(1,10001):
print("Working on segment {:d}".format(segid))
# write a cpptraj script to write out the frames as separate pdb files
cpptrajscript = tempfile.NamedTemporaryFile()
pdbfile = tempfile.NamedTemporaryFile()
pdbfilename = pdbfile.name
pdbfile.close()
cpptrajscript.write("parm {:s}\n".format(self.args.topologypath))
if "ff14sb.xray.1" in self.args.maindir or "ff14sb.nmr.1" in self.args.maindir:
cpptrajscript.write("trajin {:s}/{:04d}/{:04d}_cut.nc\n"\
.format(self.args.maindir, segid, segid))
else:
cpptrajscript.write("trajin {:s}/{:05d}/{:05d}_cut.nc\n"\
.format(self.args.maindir, segid, segid))
cpptrajscript.write("strip :WAT,Cl,Cl-,SOL\n")
cpptrajscript.write("trajout {:s}.pdb pdb multi nobox\n".format(pdbfilename))
cpptrajscript.write("go\n")
#cpptrajscript.file.flush()
cpptrajscript.flush()
# Call cpptraj to write out all the pdb files.
subprocess.Popen(['/ihome/lchong/ajd98/apps/amber14/bin/cpptraj', '-i',
cpptrajscript.name], stdout=subprocess.PIPE).wait()
# Now iterate over the 100 pdb files
mappingargs = [(pdbfilename, expectfiles[i].name, i+1) for i in range(100)]
volumes = pool.map(self.runvoidoowrapper, mappingargs)
self.volumes += volumes
outpath = os.path.join(self.args.outdirpath, 'volume')
numpy.save(outpath, numpy.array(self.volumes))
if __name__ == '__main__':
VolumeAnalysis()