Package Biskit :: Module XplorInput
[hide private]
[frames] | no frames]

Source Code for Module Biskit.XplorInput

  1  ## 
  2  ## Biskit, a toolkit for the manipulation of macromolecular structures 
  3  ## Copyright (C) 2004-2005 Raik Gruenberg & Johan Leckner 
  4  ## 
  5  ## This program is free software; you can redistribute it and/or 
  6  ## modify it under the terms of the GNU General Public License as 
  7  ## published by the Free Software Foundation; either version 2 of the 
  8  ## License, or any later version. 
  9  ## 
 10  ## This program is distributed in the hope that it will be useful, 
 11  ## but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 13  ## General Public License for more details. 
 14  ## 
 15  ## You find a copy of the GNU General Public License in the file 
 16  ## license.txt along with this program; if not, write to the Free 
 17  ## Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 18  ## 
 19  ## 
 20  ## $Revision: 2.4 $ 
 21  ## last $Author: leckner $ 
 22  ## $Date: 2006/09/12 06:34:36 $ 
 23  """ 
 24  Create Xplor input files. 
 25  """ 
 26   
 27  import Biskit.tools as T 
 28  import os 
 29   
30 -class XplorInputError(Exception):
31 pass
32
33 -class XplorInput:
34 """ 35 Create Xplor input file. addFromTemplate() might be usefull for 36 non-xplor-stuff, too. 37 38 @note: The file is only flushed to disc when the object is destructed, 39 or the flush() method is called! 40 """ 41
42 - def __init__(self, outName, mode='w'):
43 """ 44 @param outName: Folder to place output files in 45 @type outName: str 46 @param mode: open file with this mode, w=override, a=append 47 @type mode: str 48 """ 49 self.foutName = os.path.abspath(outName) # name of new .inp file 50 51 # open for <appending|writing|reading> 52 self.fgenerate = open(self.foutName, mode)
53 54
55 - def __del__(self):
56 self.fgenerate.close()
57 58
59 - def flush(self):
60 """ 61 Flush output file (but keep it open). 62 """ 63 self.fgenerate.flush()
64 65
66 - def add(self, str):
67 """ 68 Add String str and line break to xplor input file. 69 70 @param str: string to add to file 71 @type str: str 72 """ 73 try: 74 self.fgenerate.write(str + '\n') 75 except (IOError): 76 T.errWriteln( 77 "XPlorInput.append(): Error adding string to xplor input file.") 78 T.errWriteln( T.lastError() )
79 80
81 - def _singleParam(self, param, value, indent):
82 """ 83 return single parameter=value line with |indent| leading tabs. 84 (Used by blockFromDic) 85 86 @param param: parameter 87 @type param: str 88 @param value: value 89 @type value: str 90 @param indent: number of tabs at begining of line 91 @type indent: int 92 93 @return: line vith indent+parameter+value 94 @rtype: str 95 """ 96 result = indent*'\t' + param 97 try: 98 if (value <> None) and (value <> ''): 99 result = result + "=" + str(value) 100 except: 101 pass 102 return result + '\n'
103 104
105 - def blockFromDic(self, title, paramDic, indent=0, priorityParams=None):
106 """ 107 Returns block with parameters (as String). 108 Use e.g. for minimize or paramter statement. 109 110 @param title: first line of block 111 @type title: str 112 @param paramDic: dictionary of type 113 C{ {'param1':value1, 'param2':value2,...} } 114 @type paramDic: dict 115 @param indent: number of tabs to add before each line 116 @type indent: int 117 @param priorityParams: list of params to write first (in that order) 118 e.g. C{ [param1, param2] } to have param1 and 119 param2 come first 120 @type priorityParams: [str] 121 122 @return: Will result in param1=value1, param2=value2. If e.g. value1 123 is an empty string or None just param is written in that line 124 @rtype: str 125 """ 126 result = "" 127 if indent > 0: 128 # if nested, the first line most likely already has a ta 129 result = (indent-1)*'\t' 130 131 result = result + title + '\n' # first line of block 132 133 # create ordered list of (parameter, value) tuples 134 paramItems = [] 135 # put priority Params first 136 if priorityParams <> None: 137 for param in priorityParams: 138 paramItems = paramItems + [(param, paramDic[ param ])] 139 140 # add all others Params 141 for param in paramDic.keys(): # add all others next 142 if (param, paramDic[ param ]) not in paramItems: 143 paramItems = paramItems + [(param, paramDic[ param ])] 144 for paramTuple in paramItems: 145 result += self._singleParam(paramTuple[0], paramTuple[1], indent+1) 146 147 result = result + indent*"\t" + "end" # end of block 148 return result
149 150
151 - def block(self, title, paramLst, indent=0):
152 """ 153 As block() but takes parameters as list of strings without resorting 154 to the clumpsy dictionary. 155 156 @param title: first line 157 @type title: string 158 @param paramLst: list of strings, i.e. C{ ['nsteps=10', 'eps=1'] } 159 @type paramLst: [str] 160 @param indent: number of tabs indentation 161 @type indent: int 162 163 @return: block with parameters. 164 @rtype: str 165 """ 166 result = indent*'\t' + title + '\n' # first line of block 167 168 for param in paramLst: 169 result = result + (indent+1) * '\t' + param + '\n' 170 result = result + indent*'t' + 'end\n' 171 172 return result
173 174
175 - def addBlockFromDic(self, title, paramDic, indent=0):
176 """ 177 Convenience implementation of block. This one directly appends 178 the block to the growing file. 179 180 @param title: first line of block 181 @type title: str 182 @param paramDic: dictionary of type 183 C{ {'param1':value1, 'param2':value2,...} } 184 @type paramDic: dict 185 @param indent: number of tabs to add before each line 186 @type indent: int 187 """ 188 self.add( self.blockFromDic(title, paramDic, indent) )
189 190
191 - def addBlock(self, title, paramLst, indent=0):
192 """ 193 create block and directly add it to growing input file. 194 195 @param title: first line 196 @type title: string 197 @param paramLst: list of strings, i.e. C{ ['nsteps=10', 'eps=1'] } 198 @type paramLst: [str] 199 @param indent: number of tabs indentation 200 @type indent: int 201 """ 202 self.add( self.block( title, paramLst, indent) )
203 204
205 - def renameAtom(self, resname, oldName, newName):
206 """ 207 append statement for renaming atoms: 208 209 @param resname: name of residue to replace atom in 210 @type resname: str 211 @param oldName: atom name to replace 212 @type oldName: str 213 @param newName: new atom name 214 @type newName: str 215 216 @return: Line: C{ vector do (name=|newName|) (name |oldName| 217 and resname |resname|) } 218 @rtype: str 219 """ 220 self.add( 221 ("""vector do (name="%(newName)s") (name "%(oldName)s" """+ 222 """and resname "%(newName)s" )""") % vars() )
223 224
225 - def renameAtoms( self, atomDicLst ):
226 """ 227 Rename several atoms. 228 229 @param atomDicLst: list of dictionaries wher each dictionary 230 describs one renaming task e.g. :: 231 [{'res':'ALA', 'old':'HT1', 'new':'H1'},{...}] 232 @type atomDicLst: dict 233 """ 234 for rename in atomDicLst: 235 self.renameAtom(rename['res'], rename['old'], rename['new'])
236 237
238 - def renameRes(self, oldName, newName, select=''):
239 """ 240 Append statement for renaming residues: 241 242 @param oldName: current residue name, to replace 243 @type oldName: str 244 @param newName: new residue name 245 @type newName: str 246 @param select: optional additional selection for residue, 247 e.g. 'and resid 10' 248 @type select: str 249 250 @return: Line: C{ 'vector do (resname=|newName|) 251 (resname |oldName| |select|)' } 252 @rtype: str 253 """ 254 255 self.add(\ 256 ("""vector do (resname="%(newName)s") (resname "%(oldName)s" """+ 257 """%(select)s )""") % vars() )
258 259
260 - def hbuild(self, selection):
261 """ 262 Append hbuild block. Example for how to use the block() method. 263 264 @param selection: String with atom selection 265 @type selection: str 266 """ 267 selection_value = "( %s )" % selection 268 result = self.blockFromDic('hbuild',{'selection': selection_value, 269 'print':'on'}) 270 self.add( result )
271 272
273 - def patchSS(self, res1, res2):
274 """ 275 Patch statement for disulfide bond between residue number 1 and 2. 276 277 @param res1: dictionary with number and segid for the first residue 278 e.g. C{ {'res':19,'id':'SEGID'} } 279 @type res1: dict 280 @param res2: dictionary with number and segid for the second residue 281 @type res2: dict 282 """ 283 select_1 = """( segid "%4s" and resid %s )""" % (res1['id'],res1['res']) 284 select_2 = """( segid "%4s" and resid %s )""" % (res2['id'],res2['res']) 285 result = self.blockFromDic("patch disu", 286 {'reference=1': select_1, 'reference=2': select_2} ) 287 self.add(result)
288 289
290 - def addAmberSegment(self, seg_id, fpdb):
291 """ 292 Return string holding xplor input for segment consisting of one chain. 293 Example for nesting blocks with blockFromDic(). 294 295 @param seg_id: segment id 296 @type seg_id: str 297 @param fpdb: complete filename of pdb 298 @type fpdb: str 299 """ 300 ## read sequence from coordinates 301 coord_statement = """coordinates @%(fpdb)s""" % vars() 302 303 ## create inner block "chain", put coordinates statement at top 304 chain_block = self.blockFromDic("chain",\ 305 {'link ppgp head - GLY tail + PRO end':'', 306 'link ppgg head - GLY tail + GLY end':'', 307 'link pepp head - * tail + PRO end':'', 308 'link ppg2 head - GLY tail + * end':'', 309 'link ppg1 head - * tail + GLY end':'', 310 'link pept head - * tail + * end':'', 311 coord_statement:''}, 1, [coord_statement]) 312 313 ## create outer block "segment" and nest chain block into it 314 result = self.blockFromDic("segment", 315 {'name':seg_id, chain_block:''}) 316 317 self.add( result )
318 319
320 - def addFromTemplate(self, fTemplate, valueDic):
321 """ 322 Read template input file with formatstr placeholders, insert values 323 from valueDic. 324 325 @param fTemplate: filename for template 326 @type fTemplate: str 327 @param valueDic: Dictionary, {placeHolder:value} 328 @type valueDic: dict 329 """ 330 try: 331 332 line = None 333 for line in open(fTemplate).readlines(): 334 line = line.rstrip() ## get rid of \n 335 336 ## skip template comments starting with '#' 337 if len(line) == 0 or line.lstrip()[0] <> '#': 338 self.add( line % valueDic ) 339 340 except KeyError, why: 341 s = "Unknown option in template file." 342 s += "\n template file: " + fTemplate 343 s += "\n Template asked for a option called " + str( why[0] ) 344 s += "\n template line:\n " + str(line) 345 s += "\n Please give a value for this option at the command line." 346 s += "\n E.g: pdb2xplor.py -i input.pdb -%s some_value -t..." %\ 347 str( why[0] ) 348 349 raise XplorInputError, s 350 351 except: 352 s = "Error while adding template file." 353 s += "\n template file: " + fTemplate 354 s += "\n template line:\n " + str(line) 355 s += "\n available arguments:\n" 356 357 for i in valueDic.keys(): 358 s += "\t%25s\t%s\n" % (i, str( valueDic[i] ) ) 359 360 s += "\n Error:\n " + T.lastError() 361 362 raise XplorInputError, s
363 364 365 ############# 366 ## TESTING 367 ############# 368
369 -class Test:
370 """ 371 Test class 372 """ 373
374 - def run( self, local=0 ):
375 """ 376 run function test 377 378 @param local: transfer local variables to global and perform 379 other tasks only when run locally 380 @type local: 1|0 381 382 @return: 1 383 @rtype: int 384 """ 385 import tempfile 386 387 ## create an temporery input template 388 f_inp = tempfile.mktemp('_test.inp') 389 f = open(f_inp, 'w') 390 f.write('Test Template with %(number)i values:\n') 391 f.write('\n') 392 f.write('%(value)s\n') 393 f.close() 394 395 ## temporery outpot template 396 f_out_inp = tempfile.mktemp('_test_out.inp') 397 398 ## write to output 399 t = XplorInput( f_out_inp ) 400 t.add("\nremarks test generate.inp\n") 401 402 t.addBlockFromDic("minimize powell",{"nsteps":100,"npr":5}) 403 t.addAmberSegment("id_1", "/home/Bis/super.pdb") 404 t.patchSS({'res':23, 'id':'id_1'},{'res':44, 'id':'id_1'} ) 405 t.hbuild("hydrogen and not known") 406 407 t.renameRes("CYS", "CYX") 408 t.renameAtom("ARG","HG1","HG2") 409 t.addFromTemplate(f_inp, {'value':'TEST','number':10}) 410 t.flush() 411 412 if local: 413 ## check result 414 f = open(f_out_inp, 'r') 415 for line in f.readlines(): 416 print line[:-1] 417 f.close() 418 419 globals().update( locals() ) 420 421 ## cleanup 422 T.tryRemove( f_inp ) 423 T.tryRemove( f_out_inp ) 424 425 return 1
426 427
428 - def expected_result( self ):
429 """ 430 Precalculated result to check for consistent performance. 431 432 @return: 1 433 @rtype: int 434 """ 435 return 1
436 437 438 if __name__ == '__main__': 439 440 test = Test() 441 442 assert test.run( local=1 ) == test.expected_result() 443