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 Prepare and run a xplor job.
26 """
27
28 import tempfile
29 from time import time
30 import os
31
32 import settings
33 import Biskit.tools as t
34 from Biskit.Errors import BiskitError
35 from Biskit import StdLog
36
38 pass
39
41 pass
42
44 pass
45
47 """
48 Prepare and run a xplor job
49
50 @todo: Most of this has been abstracted into Executor next thing
51 to do is to subclass Executor and delete redundant parts
52 """
53
54 - def __init__( self, inpFile, xout=None, bin=settings.xplor_bin,
55 node=None, nice=0, log=None, debug=0, verbose=None,
56 **params ):
57 """
58 @param inpFile: file name of inp template
59 @type inpFile: str
60 @param xout: file name of xplor log file (None->discard)
61 (default: None)
62 @type xout: str
63 @param bin: file name of xplor binary (default: settings.xplor_bin)
64 @type bin: str
65 @param node: host for calculation (None->local) (default: None)
66 @type node: str
67 @param nice: nice level (default: 0)
68 @type nice: int
69 @param log: Biskit.LogFile, program log (None->STOUT) (default: None)
70 @type log: str OR None
71 @param debug: keep all temporary files (default: 0)
72 @type debug: 0|1
73 @param verbose: print xplor command to log [log != STDOUT]
74 @type verbose: 0|1
75 @param params: additional key=value pairs for inp file
76 @type params: key=value
77 """
78 self.__dict__.update( params )
79
80 self.bin = t.absfile( bin ) or settings.xplor_bin
81 self.inp = t.absfile( inpFile )
82 self.xout = t.absfile( xout ) or tempfile.mktemp('_xplor.log')
83 self.finp = None
84 self.node = node or os.uname()[1]
85 self.nice = nice
86 self.keepLog = xout is not None
87 self.debug = debug
88
89
90 self.log = log or StdLog()
91 self.verbose = verbose
92 if self.verbose is None:
93 self.verbose = (log is not None)
94
95
96 self.runTime = 0
97
98
99 self.initVersion = self.version()
100
101
102 self.logLines = None
103
104
106 """
107 Version of class.
108
109 @return: version
110 @rtype: str
111 """
112 return 'Xplorer $Revision: 2.5 $'
113
114
116 """
117 Run Xplor with given inp file and wait until it is finished.
118 Called by run().
119
120 @param finp: name of existing input file (w/o place holders)
121 @type finp: str
122
123 @return: run time in s
124 @rtype: float
125 """
126 start_time = time()
127
128 str_nice = "%s -%i" % (settings.nice_bin, self.nice)
129
130 lead_cmd = settings.ssh_bin
131 str_ssh = "%s %s" % ( settings.ssh_bin, self.node )
132
133 cmd = "%s %s %s < %s > %s"\
134 %(str_ssh, str_nice, self.bin, finp, self.xout)
135
136 if self.verbose: self.log.add_nobreak("executes: "+cmd+"..")
137
138 if os.spawnvp(os.P_WAIT, lead_cmd, cmd.split() ) <> 0:
139 raise RunError("non-0 exit status. \nCommand: "+cmd)
140
141 if self.verbose: self.log.add(".. finished.")
142
143 return time() - start_time
144
145
146 - def run( self, inp_mirror=None ):
147 """
148 Run the callculation. This calls (in that order):
149 - L{ prepare() },
150 - L{ runXplor() },
151 - L{ parseLog() },
152 - L{ finish() }/ L{ failed() },
153 - L{ cleanup() }
154
155 @param inp_mirror: file name for formatted copy of inp file
156 (default: None)
157 @type inp_mirror: str
158 """
159
160 self.prepare()
161
162 try:
163 inp = open( self.inp, 'r' ).read()
164
165 self.finp = inp_mirror or tempfile.mktemp('_xplor.inp')
166
167 self.generateInp( inp, self.finp )
168
169 self.runTime = self.runXplor( self.finp )
170
171 self.parseLog()
172
173 except RunError, why:
174 try:
175 self.failed()
176 finally:
177 self.cleanup()
178 raise RunError, why
179
180 try:
181 if self.isFailed():
182 self.failed()
183 else:
184 self.finish()
185 finally:
186 self.cleanup()
187
188
190 """
191 Remove temporary files, override it but call it in the child
192 """
193 if not self.keepLog and not self.debug:
194 t.tryRemove( self.xout )
195
196 if not self.debug:
197 t.tryRemove( self.finp )
198
199
201 """
202 Parse xplor log into self.logLines
203 """
204 self.logLines = open( self.xout ).readlines()
205
206
208 """
209 Calculation completion check.
210
211 @return: if xplor died
212 @rtype: 1
213 """
214 return self.logLines == None or \
215 self.logLines[-1].find("X-PLOR: exit time") == -1
216
217
219 """
220 called before running xplor, override!
221 """
222 pass
223
224
226 """
227 called after normal termination, override!
228 """
229 pass
230
231
233 """
234 called after aborted calculation, override!
235
236 @raise RunError: if Xplor terminated with an error
237 """
238 s = ''
239 try:
240 s += ''.join( self.logLines[-7:] )
241 except:
242 pass
243
244 raise RunError, 'Xplor terminated with an error:\n' + s
245
246
248 """
249 Replace formatstr place holders in inp by fields of this class.
250
251 @param inp: content of the input file with place holders
252 @type inp: str
253 @param fout: output file mane (xplor input file)
254 @type fout: str
255
256 @return: complete inp file
257 @rtype: str
258
259 @raise TemplateError: if unknown option/place holder in template file
260 @raise TemplateError: if error while creating template file
261 """
262 try:
263 s = inp % self.__dict__
264 f = open( fout, 'w')
265 f.write(s)
266 f.close()
267
268 except KeyError, why:
269 s = "Unknown option/place holder in template file."
270 s += "\n template file: " + self.inp
271 s += "\n Template asked for a option called " + str( why[0] )
272 raise TemplateError, s
273
274 except Exception, why:
275 s = "Error while creating template file."
276 s += "\n template file: " + self.inp
277 s += "\n why: " + str( why )
278 s += "\n Error:\n " + t.lastError()
279 raise TemplateError, s
280
281
283 """
284 Save the content of the XPlor log file to a new file.
285
286 @param fname: target file name
287 @type fname: str
288
289 @raise XPlorerError: if logLines is empty (Xplor hasn't been run)
290 """
291 if not self.logLines:
292 raise XPlorerError('Xplor log file is (yet) empty.')
293
294 f = open( t.absfile(fname), 'w')
295 f.writelines( self.logLines )
296 f.close()
297
298
299
300
301
302
303
305 """
306 Test class
307 """
308
309 inp = """
310 !! short test minimzation
311
312 ! ------------------------------------------------------------
313 ! Place holders to be inserted by Python script
314 ! ------------------------------------------------------------
315 evaluate ($ligandpsf = "%(lig_psf)s")
316 evaluate ($ligandpdb = "%(lig_pdb)s")
317 evaluate ($param19 = "%(param19)s" )
318 evaluate ($lig_out = "%(lig_out)s" )
319
320 ! -------------------------------------
321 ! read psf and pdb files for the ligand
322 ! -------------------------------------
323 structure @@$ligandpsf end
324 coor @@$ligandpdb
325 delete selection= (resname TIP3) end
326
327 ! ------------------
328 ! set toplogies etc.
329 ! ------------------
330 parameter
331 reset
332 @@$param19
333 end
334
335 ! ------------------------------------------------------------
336 ! minimize
337 ! ------------------------------------------------------------
338 flags exclude * include bond angle impr elec end
339 minimize powell nstep=10 end
340
341 ! ---------------------------------------------------
342 ! write minimized PDBs
343 ! ---------------------------------------------------
344 write coor output= $lig_out end
345 stop
346 """
347
348 - def run( self, local=0 ):
349 """
350 run function test
351
352 @param local: transfer local variables to global and perform
353 other tasks only when run locally
354 @type local: 1|0
355
356 @return:
357 @rtype:
358 """
359 dir_out = tempfile.mkdtemp( '_test_Xplorer' )
360
361
362 f = open( dir_out +'/test.inp', 'w')
363 f.writelines( self.inp )
364 f.close()
365
366
367 param = t.projectRoot() + '/external/xplor/toppar/param19.pro'
368 pdb_out = dir_out +'/lig.pdb'
369 log_out = dir_out +'/test.out'
370 pdb_in = t.testRoot() + '/lig/1A19.pdb'
371 psf_in = t.testRoot() + '/lig/1A19.psf'
372
373 x = Xplorer( dir_out +'/test.inp',
374 xout = log_out,
375 verbose = local,
376 lig_psf = psf_in,
377 lig_pdb = pdb_in,
378 param19 = param,
379 lig_out = pdb_out )
380
381 x.run()
382
383 if local:
384 print 'The minimized structure and the X-Plor log file has been written to %s and %s, respectively'%(pdb_out, log_out)
385 globals().update( locals() )
386
387 return 1
388
389
391 """
392 Precalculated result to check for consistent performance.
393
394 @return:
395 @rtype:
396 """
397 return 1
398
399
400
401 if __name__ == '__main__':
402
403 test = Test()
404
405 assert test.run( local=1 ) == test.expected_result()
406