def setHexComplexes(self, com_lst, n=20 ): """ add contact matrices of hex-generated (wrong) complexes for comparison @param com_lst: ComplexList with contacts calculated @type com_lst: ComplexList """ t.flushPrint('adding hex-generated complexes') self.hexContacts = [] # f = lambda a: molUtils.elementType(a['element']) == 'p' i = 0 while i < n: com = com_lst[i] t.flushPrint('#') try: if com['fractNatCont'] == 0.0:#com['fnac_10'] == 0.0: com.rec_model.remove( com.rec().maskH() ) com.lig_model.remove( com.lig_model.maskH() ) com.rec_model = com.rec_model.sort() com.lig_model = com.lig_model.sort() com.rec_model.keep( self.i_free_rec ) com.lig_model.keep( self.i_free_lig ) com.lig_transformed = None self.hexContacts += [ com.atomContacts() ] else: n += 1 i+= 1 except: print t.lastError() self.hexSurfaces = self.__categorizeHexSurf( 0.2 )
def failed( self ): """ If HEX job fails """ print "FAILED: ", self.host, ' ', t.stripFilename(self.finp) print "\tJob details:" print "\tCommand: ", self.cmd print "\tinput: ", self.finp print "\tHex log: ", self.log print "\tHex out: ", self.fout print print "\t", t.lastError() self.owner.failedHex( self )
def _sequentialDist(self, chain, cutoff, atom): """ Calculate sequential atom-atom distance, report residues with longer distance than cutoff (chain break positions). @param chain: Scientific.IO.PDB.PeptideChain object @type chain: object @param cutoff: threshold for reporting gap (chain break) @type cutoff: float @param atom: type of atoms to check (i.e. 'CA') @type atom: str @return: list of chain break positions (residue index for each first residue of two that are too distant) @rtype: list of int """ distanceList = [] v0 = Vector( 0,0,0 ) jump = 1 for res in range(0,len(chain)-2): try: v1 = Vector(chain[res][atom].position.array) ## ignore CA with 0,0,0 coordinate if v1 != v0: jump = 1 v2 = Vector(chain[ res+jump ][atom].position.array) ## look for next CA with non-zero coordinate while v2 == v0 and jump + res < len( chain ): jump += 1 v2 = Vector(chain[ res+jump ][atom].position.array) if (v1 - v2).length() > cutoff * jump: distanceList = distanceList + [res + jump - 1] except: self.log.add( "_sequentialDist():\nError while checking CA-CA distance"+\ " between residues "+str(chain[res].name)+\ str(chain[res].number)+" and "+\ str(chain[res+jump].name)+\ str(chain[res+jump].number)+ " in chain "+chain.chain_id) self.log.add("Error: " + T.lastError() ) return distanceList
def _sequentialDist(self, chain, cutoff, atom): """ Calculate sequential atom-atom distance, report residues with longer distance than cutoff (chain break positions). @param chain: Scientific.IO.PDB.PeptideChain object @type chain: object @param cutoff: threshold for reporting gap (chain break) @type cutoff: float @param atom: type of atoms to check (i.e. 'CA') @type atom: str @return: list of chain break positions (residue index for each first residue of two that are too distant) @rtype: list of int """ distanceList = [] v0 = Vector(0, 0, 0) jump = 1 for res in range(0, len(chain) - 2): try: v1 = Vector(chain[res][atom].position.array) ## ignore CA with 0,0,0 coordinate if v1 != v0: jump = 1 v2 = Vector(chain[res + jump][atom].position.array) ## look for next CA with non-zero coordinate while v2 == v0 and jump + res < len(chain): jump += 1 v2 = Vector(chain[res + jump][atom].position.array) if (v1 - v2).length() > cutoff * jump: distanceList = distanceList + [res + jump - 1] except: self.log.add( "_sequentialDist():\nError while checking CA-CA distance"+\ " between residues "+str(chain[res].name)+\ str(chain[res].number)+" and "+\ str(chain[res+jump].name)+\ str(chain[res+jump].number)+ " in chain "+chain.chain_id) self.log.add("Error: " + T.lastError()) return distanceList
def fatal( self, message ): """ Handle a fatal error (likely a bug), stop program execution. @param message: message to be given to user @type message: str @raise FatalError: """ s = '\nFatal Error: '+str(message) s += '\n\t' + T.lastError() + '\n' s += 'TraceBack: \n' + T.lastErrorTrace() + '\n' self.log.add(s) raise FatalError
def fatal(self, message): """ Handle a fatal error (likely a bug), stop program execution. @param message: message to be given to user @type message: str @raise FatalError: """ s = '\nFatal Error: ' + str(message) s += '\n\t' + T.lastError() + '\n' s += 'TraceBack: \n' + T.lastErrorTrace() + '\n' self.log.add(s) raise FatalError
def error(self, message): """ Handle a normal error (like non-existing file) that is not necessarily a bug. @param message: message to be given to user @type message: str @raise NormalError: """ s = '\nError: ' + str(message) s += '\n\t' + T.lastError() s += '\nTraceBack: \n' + T.lastErrorTrace() + '\n' self.log.add(s) raise NormalError
def error( self, message ): """ Handle a normal error (like non-existing file) that is not necessarily a bug. @param message: message to be given to user @type message: str @raise NormalError: """ s = '\nError: '+str(message) s += '\n\t' + T.lastError() s += '\nTraceBack: \n' + T.lastErrorTrace() + '\n' self.log.add(s) raise NormalError
def remove_multi_occupancies(self): """ Keep only atoms with alternate A field (well, or no alternate). """ if self.verbose: self.logWrite(self.model.pdbCode + ': Removing multiple occupancies of atoms ...') i = 0 to_be_removed = [] for a in self.model: if a['alternate']: try: str_id = "%i %s %s %i" % (a['serial_number'], a['name'], a['residue_name'], a['residue_number']) if a['alternate'].upper() == 'A': a['alternate'] = '' else: if float(a['occupancy']) < 1.0: to_be_removed += [i] if self.verbose: self.logWrite( 'removing %s (%s %s)' % (str_id, a['alternate'], a['occupancy'])) else: if self.verbose: self.logWrite(( 'keeping non-A duplicate %s because of 1.0 ' + 'occupancy') % str_id) except: self.logWrite("Error removing duplicate: " + t.lastError()) i += 1 try: self.model.remove(to_be_removed) if self.verbose: self.logWrite('Removed %i atoms' % len(to_be_removed)) except: if self.verbose: self.logWrite('No atoms with multiple occupancies to remove')
def remove_multi_occupancies( self ): """ Keep only atoms with alternate A field (well, or no alternate). """ if self.verbose: self.logWrite( self.model.pdbCode + ': Removing multiple occupancies of atoms ...') i = 0 to_be_removed = [] for a in self.model: if a['alternate']: try: str_id = "%i %s %s %i" % (a['serial_number'], a['name'], a['residue_name'], a['residue_number']) if a['alternate'].upper() == 'A': a['alternate'] = '' else: if float( a['occupancy'] ) < 1.0: to_be_removed += [ i ] if self.verbose: self.logWrite( 'removing %s (%s %s)' % (str_id,a['alternate'], a['occupancy'])) else: if self.verbose: self.logWrite( ('keeping non-A duplicate %s because of 1.0 '+ 'occupancy') % str_id ) except: self.logWrite("Error removing duplicate: "+t.lastError() ) i+=1 try: self.model.remove( to_be_removed ) if self.verbose: self.logWrite('Removed %i atoms' % len( to_be_removed ) ) except: if self.verbose: self.logWrite('No atoms with multiple occupancies to remove' )
def extractWaters(self): """ Write waters into separate pdb file, called |pdbCode|_waters.pdb. """ try: fTarget = self.outPath + '/' +\ self.pdbname()[:4] + '_waters.pdb' pdb = PDBFile( fTarget, mode='w' ) waters = [] for key in ['HOH', 'DOD']: if self.pdb.molecules.has_key( key ): waters += self.pdb.molecules[ key ] pdb.nextChain(chain_id='', segment_id='1XWW') for w in waters: pdb.nextResidue('TIP3') ## XPLOR wants "ATOM" not "HETATM": pdb.het_flag = 0 pdb.writeAtom('OH2', w.atoms['O'].position) ## keep TIP3 waters as well if len(waters) == 0: try: TIP3_waters = self.pdb.molecules[ 'TIP3' ] except: TIP3_waters = [] for w in TIP3_waters: pdb.nextResidue('TIP3') ## XPLOR wants "ATOM" not "HETATM": pdb.het_flag = 0 pdb.writeAtom('OH2', w.atoms['OH2'].position) pdb.writeAtom('H1', w.atoms['H1'].position) pdb.writeAtom('H2', w.atoms['H2'].position) pdb.close() except: T.errWriteln("Error writing waters to %s: " % fTarget ) T.errWriteln( T.lastError() )
def extractWaters(self): """ Write waters into separate pdb file, called |pdbCode|_waters.pdb. """ try: fTarget = self.outPath + '/' +\ self.pdbname()[:4] + '_waters.pdb' pdb = PDBFile(fTarget, mode='w') waters = [] for key in ['HOH', 'DOD']: if self.pdb.molecules.has_key(key): waters += self.pdb.molecules[key] pdb.nextChain(chain_id='', segment_id='1XWW') for w in waters: pdb.nextResidue('TIP3') ## XPLOR wants "ATOM" not "HETATM": pdb.het_flag = 0 pdb.writeAtom('OH2', w.atoms['O'].position) ## keep TIP3 waters as well if len(waters) == 0: try: TIP3_waters = self.pdb.molecules['TIP3'] except: TIP3_waters = [] for w in TIP3_waters: pdb.nextResidue('TIP3') ## XPLOR wants "ATOM" not "HETATM": pdb.het_flag = 0 pdb.writeAtom('OH2', w.atoms['OH2'].position) pdb.writeAtom('H1', w.atoms['H1'].position) pdb.writeAtom('H2', w.atoms['H2'].position) pdb.close() except: T.errWriteln("Error writing waters to %s: " % fTarget) T.errWriteln(T.lastError())
def reportError(self, msg, soln): """ Report any errors to log @param msg: error message @type msg: str @param soln: solution number for complex giving the error @type soln: int """ try: s = '%s on %s, soln %i\n' % (msg, os.uname()[1], soln) s += '\t' + T.lastError() + '\n' s += 'TraceBack: \n' + T.lastErrorTrace() + '\n' f = open(self.ferror, 'a') f.write(s) f.close() except: f = open('ErrorReportError_ContactSlave', 'a') f.write('') f.close()
def reportError(self, msg, soln ): """ Report any errors to log @param msg: error message @type msg: str @param soln: solution number for complex giving the error @type soln: int """ try: s = '%s on %s, soln %i\n' % (msg, os.uname()[1], soln) s += '\t' + T.lastError() + '\n' s += 'TraceBack: \n' + T.lastErrorTrace() + '\n' f = open( self.ferror, 'a' ) f.write( s ) f.close() except: f = open('ErrorReportError_ContactSlave','a') f.write('') f.close()
def getResult(self, **arg): """ Collapse the results for different values of the variable parameter into lists and put the results into a tree ala:: r[ member_index ][ protocol_name ][ result_field ] -> [ values ] @return: tree-like dict ordered by variable value, member, protocol @rtype: dict of dict of dict of lists """ tree = self.dictionate(self.result) vvalues = tree.keys() vvalues.sort() keys = self.result.keys() sub_keys = [k for k in keys if k[0] == vvalues[0]] r = {} for v, member, protcl in sub_keys: try: if not member in r: r[member] = {} r[member][protcl] = {} run_dic = tree[v][member][protcl] for k in run_dic.keys(): r[member][protcl][k] = [ tree[v][member][protcl][k] \ for v in vvalues ] except: EHandler.warning('missing result: ' + str(T.lastError())) r['var'] = self.var r['vrange'] = self.vrange r['protocols'] = self.protocols self.result_tree = r return r
def getResult( self, **arg ): """ Collapse the results for different values of the variable parameter into lists and put the results into a tree ala:: r[ member_index ][ protocol_name ][ result_field ] -> [ values ] @return: tree-like dict ordered by variable value, member, protocol @rtype: dict of dict of dict of lists """ tree = self.dictionate( self.result ) vvalues = tree.keys() vvalues.sort() keys = self.result.keys() sub_keys = [ k for k in keys if k[0] == vvalues[0] ] r = {} for v, member, protcl in sub_keys: try: if not member in r: r[member] = {} r[member][protcl] = {} run_dic = tree[v][member][protcl] for k in run_dic.keys(): r[member][protcl][k] = [ tree[v][member][protcl][k] \ for v in vvalues ] except: EHandler.warning('missing result: ' + str(T.lastError())) r['var'] = self.var r['vrange']= self.vrange r['protocols'] = self.protocols self.result_tree = r return r
def warning( self, message, error=1, trace=0 ): """ Issue a warning. No exception is raised. @param message: message to be given to user @type message: str @param error: report Exception with line (default: 1) @type error: 1||0 @param trace: report full back trace to exception (default: 0) @type trace: 1||0 """ s = '\nWarning (ignored): '+str(message) try: if trace: error = 1 if error: s += '\n\t' + T.lastError() + '\n' if trace: s += '\nTraceBack: \n' + T.lastErrorTrace() + '\n' except: pass self.log.add(s)
def warning(self, message, error=1, trace=0): """ Issue a warning. No exception is raised. @param message: message to be given to user @type message: str @param error: report Exception with line (default: 1) @type error: 1||0 @param trace: report full back trace to exception (default: 0) @type trace: 1||0 """ s = '\nWarning (ignored): ' + str(message) try: if trace: error = 1 if error: s += '\n\t' + T.lastError() + '\n' if trace: s += '\nTraceBack: \n' + T.lastErrorTrace() + '\n' except: pass self.log.add(s)
def reportError(self, msg, id ): try: try: print msg except: pass msg = 'trouble with ' + msg s = '%s on %s, run %s\n' % (msg, os.uname()[1], id) s += '\Error:' + T.lastError() s += '\nErrorTrace:\n' + T.lastErrorTrace() + '\n' s += '\n' self.errorLog.add( s ) except Exception, why: f = open('ErrorReportError_AmberEntropySlave','a') f.write( str(type(why)) ) try: f.write( T.lastErrorTrace() ) except: pass f.close()
def reportError(self, msg, id): try: try: print msg except: pass msg = 'trouble with ' + msg s = '%s on %s, run %s\n' % (msg, os.uname()[1], id) s += '\Error:' + T.lastError() s += '\nErrorTrace:\n' + T.lastErrorTrace() + '\n' s += '\n' self.errorLog.add(s) except Exception, why: f = open('ErrorReportError_AmberEntropySlave', 'a') f.write(str(type(why))) try: f.write(T.lastErrorTrace()) except: pass f.close()
def generateInp(self): """ Prepare the program input (file or string) from a template (if any, file or string). @return: input file name OR (if pipes=1) content of input file OR None @rtype: str @raise TemplateError: if error while creating template file """ try: inp = None if self.template: inp = self.fillTemplate() return self.convertInput(inp) except IOError, why: s = "Error while creating input file from template." s += "\n template file: " + str(self.template) s += "\n why: " + str(why) s += "\n Error:\n " + t.lastError() raise TemplateError, s
def generateInp(self): """ Prepare the program input (file or string) from a template (if any, file or string). @return: input file name OR (if pipes=1) content of input file OR None @rtype: str @raise TemplateError: if error while creating template file """ try: inp = None if self.template: inp = self.fillTemplate() return self.convertInput( inp ) except IOError, why: s = "Error while creating input file from template." s += "\n template file: " + str( self.template ) s += "\n why: " + str( why ) s += "\n Error:\n " + t.lastError() raise TemplateError, s
class IcmCad(Executor): """ CAD calculation =============== Calculate ContactAreaDifference between a reference structure and one or many other structures. Described in Abagyan and Totrov, 1997. Example usage ------------- >>> x = IcmCad( ref_model, [ m1, m2 ], verbose=1 ) >>> result = x.run() IcmCad writes temporary pdb files, calls the icmbrowser program, and parses the result from the STDOUT pipe. The result values are then in x.result (if x is the IcmCad instance). As recommended, the value is multiplied by factor 1.8 which puts it into a range from 0 (identical) to 100 (completely different). This scaling is not recommended for docking solutions. @todo: Not speed-optimized! - it should be possible to pipe the PDB-files directly into icmbrowser instead of writing temporary files to disc - Abagyan and Totrov mention a c-library available -- the best solution would hence be to wrap this c-library in python... @note: Command configuration in: biskit/Biskit/data/defaults/exe_icmbrowser.dat """ inp_head = \ """ call _startup read pdb unix cat \"%(f_ref)s\" copy a_ \"mol1\" """ inp_tail = "quit\n" inp_calc = \ """ read pdb unix cat \"%(f_pdb)s\" copy a_ \"mol2\" delete 1.8*Cad( a_mol1./* a_mol2./* ) """ def __init__(self, ref_model, models, **kw): """ @param ref_model: reference @type ref_model: PDBModel @param models: structures to be compared with reference @type models: [PDBModel] @param kw: additional key=value parameters for Executor: @type kw: key=value pairs :: debug - 0|1, keep all temporary files (default: 0) verbose - 0|1, print progress messages to log (log != STDOUT) node - str, host for calculation (None->local) NOT TESTED (default: None) nice - int, nice level (default: 0) log - Biskit.LogFile, program log (None->STOUT) (default: None) """ Executor.__init__(self, 'icmbrowser', template=self.inp_head, **kw) self.f_ref = tempfile.mktemp('_icmcad_ref.pdb') self.f_pdb = tempfile.mktemp('_icmcad_%i.pdb') self.ref_model = ref_model self.models = models if not isinstance(self.models, list): self.models = [self.models] def __prepareModel(self, model, f_out): """ Prepare a model that ICM likes. - consecutive numbering of residues - no chain identifier @param model: model @type model: PDBModel @param f_out: name of pdb file to write @type f_out: str """ model.renumberResidues() #for a in model.getAtoms(): #a['chain_id']='' model['chain_id'] = [''] * len(model) model.writePdb(f_out) def prepare(self): """ Overrides Executor method. """ self.__prepareModel(self.ref_model, self.f_ref) for i, m in enumerate(self.models): self.__prepareModel(m, self.f_pdb % i) def cleanup(self): """ Tidy up the mess you created. """ Executor.cleanup(self) if not self.debug: T.tryRemove(self.f_ref) for i in range(len(self.models)): T.tryRemove(self.f_pdb % i) def parse_icm(self, output): """ Extract CAD value from icm output. @param output: STDOUT result of ICM run @type output: [str] @return: ICM result @rtype: [str] @raise IcmCadError: if no result """ lines = output.split('\n') if len(lines) == 0: raise IcmCadError, 'no ICM result' r = [] for i, l in enumerate(lines): if re.match('.+1.8\*Cad.+', l): r.append(float(lines[i + 1].strip())) return r def isFailed(self): """ Overrides Executor method """ return self.error != '' or \ not '3> 1.8*Cad' in self.output def fail(self): """ Overrides Executor method. Called when execution fails. """ s = 'IcmBrowser failed. Please check the program output in the '+\ 'field `output` of this IcmCad instance (e.g. `print x.output`)!' self.log.add(s) raise IcmCadError, s def finish(self): """ Overrides Executor method """ Executor.finish(self) self.result = self.parse_icm(self.output) def generateInp(self): """ Has to be overridden to support head / segment / tail structure. Replace formatstr place holders in inp by fields of this class. @return: ICM input script @rtype: [str] @raise TemplateError: if template not found """ try: s = self.inp_head % self.__dict__ for i, m in enumerate(self.models): s += self.inp_calc % {'f_pdb': self.f_pdb % i} s += self.inp_tail return s except KeyError, why: s = "Unknown option/place holder in template file." s += "\n Template asked for a option called " + str(why[0]) raise TemplateError, s except Exception, why: s = "Error while creating template file." s += "\n why: " + str(why) s += "\n Error:\n " + T.lastError() raise TemplateError, s
s += "\n Please give a value for this option at the command line." s += "\n E.g: pdb2xplor.py -i input.pdb -%s some_value -t..." %\ str( why[0] ) raise XplorInputError, s except: s = "Error while adding template file." s += "\n template file: " + fTemplate s += "\n template line:\n " + str(line) s += "\n available arguments:\n" for i in valueDic.keys(): s += "\t%25s\t%s\n" % (i, str(valueDic[i])) s += "\n Error:\n " + T.lastError() raise XplorInputError, s ############# ## TESTING ############# import Biskit.test as BT import tempfile class Test(BT.BiskitTest): """ XPlorer Test
def process_all( self, file_dic, keep_hetatoms=0 ): """ Process PDB files in file_dic. The PDB is read from: - L{TemplateSearcher.F_NR} and cleaned files are written to: - L{F_CLEANED} - L{F_COFFEE} - L{F_MODELLER} If the file L{F_CLEANED} already exists, this file is used to write modeller and t-coffee pdbs. @param file_dic: dictionary mapping filenames of pdb files to the chains of interest, e.g. { fname : chain_id, } @type file_dic: {str:str} @param keep_hetatoms: keep hetatoms (default: 0) @type keep_hetatoms: 0|1 """ fasta = "" c = None for f, id in file_dic.items(): self.logWrite( '\nCLEANING ' + f + '...') try: code = string.split(f, '/')[-1][:4] ## clean to standard PDB c = PDBCleaner( f, self.log ) ## if /templates/nr_cleaned/pfb-file exists if os.path.exists( self.outFolder+self.F_CLEANED + code + '.pdb' ): model = PDBModel( self.outFolder+self.F_CLEANED \ + code + '.pdb' ) ## read pdb from /templates/nr else: model = c.process( keep_hetatoms=keep_hetatoms ) ## write complete cleaned PDB model.writePdb( self.outFolder+self.F_CLEANED \ + code + '.pdb') code = model.pdbCode title = code + '_' + id ## extract needed chain if len( id ) > 0: model = self.__chain_by_id( model, id ) fname = "%s%s.pdb" % (self.outFolder + self.F_MODELLER, title) self.write_modeller_pdb( model, fname ) ## write T_coffee CA trace with res sequence fname = "%s%s.alpha"%(self.outFolder + self.F_COFFEE, title) self.write_tcoffee_pdb( model, fname ) ## append fasta fasta += self.fasta_sequence( title, model.sequence() ) except: self.logWrite( 'Error cleaning ' + f) self.logWrite( T.lastError() ) self.err_cleaner = c self.err_file = f fasta_out = open( self.outFolder + self.F_FASTA, 'w' ) fasta_out.write( fasta ) fasta_out.close()
s2 = s2.replace('cPDBModel\narray_constructor', 'cNumeric\narray_constructor') s2 = s2.replace('cMathUtils\narray_constructor', 'cNumeric\narray_constructor') s2 = s2.replace('cfit\narray_constructor', 'cNumeric\narray_constructor') s2 = s2.replace('cTrajectory\narray_constructor', 'cNumeric\narray_constructor') s2 = s2.replace('cBiskit.Dock.ContactMaster\narray_constructor', 'cNumeric\narray_constructor') shutil.copy(fin, fout) f = open(fin, 'w') f.write(s2) f.close() try: print "checking...", o = t.load(fin) print "Done" except ImportError: print "could not fix %s" % fin os.rename(fout, fin) except: print "There is still some other problem: " print t.lastError() print t.lastErrorTrace()
def restart( rst_data, **params ): """ @param rst_data: restart data @type rst_data: dict @param params: key-value pairs, for subclass implementations @type params: {key:value} """ ## create empty master master = TrackingJobMaster( **params ) ## switch to required subclass and handle special information rst_data = master.setRst( rst_data ) ## set all remaining fields of master master.__dict__.update( rst_data ) return master if __name__ == '__main__': import pypvm try: pypvm.hostinfo() except: print T.lastError()
def nextComplex(self): """ Take list of lines, extract all Hex info about one complex (Solution number, hex energy,..) also extract 16 numbers of the transformation matrix and put them into 4 by 4 numeric array. @return: Complex created from the output from Hex @rtype: Complex """ ## get set of lines describing next complex: lines = self._nextBlock() if lines == None: ## EOF return None ## skip incomplete records if len(lines) < 13: lines = self._nextBlock() ## fill info dictionary i = {} matrix = None for l in lines: try: ## labels has to be in the same order as in hex.out m = self.ex_line.search( l ) if m != None: m = m.groups() if m[0] == 'Orientation': i['hex_clst'] = int(m[1]) elif m[0] == 'Solution': i['soln'] = int(m[1]) elif m[0] == 'ReceptorModel': if self.forceModel: i['model1'] = self.forceModel[0] else: i['model1'] = int(m[1]) elif m[0] == 'LigandModel': if self.forceModel: i['model2'] = self.forceModel[1] else: i['model2'] = int(m[1]) elif m[0] == 'Bumps': if int(m[1]) != -1: i['bumps'] = int(m[1]) elif m[0] == 'ReferenceRMS': i['rms'] = float(m[1]) elif m[0] == 'Vshape': if float(m[1]) != 0.0: i['hex_Vshape'] = float(m[1]) elif m[0] == 'Vclash': if float(m[1]) != 0.0: i['hex_Vclash'] = float(m[1]) elif m[0] == 'Etotal': i['hex_etotal'] = float(m[1]) elif m[0] == 'Eshape': i['hex_eshape'] = float(m[1]) elif m[0] == 'LigandMatrix': ## get all numbers of matrix as list of strings strings = self.ex_matrix.findall( l ) ## convert that to list of floats numbers = [] for each in strings: numbers += [float(each)] ## convert that to list of lists of 4 floats each matrix = [] for j in range(0,4): matrix.append( numbers[4*j:4*(j+1)] ) ## create 4 by 4 Numeric array from 4 by 4 list matrix = Numeric.array(matrix, Numeric.Float32) except AttributeError: print "HexParser.nextComplex(): ",t.lastError() ## Create new complex taking PCR models from dictionary c = Complex( self.rec_models[ i['model1'] ], self.lig_models[ i['model2'] ], matrix, i ) return c
s2 = s2.replace( 'cMathUtils\narray_constructor', 'cNumeric\narray_constructor' ) s2 = s2.replace( 'cfit\narray_constructor', 'cNumeric\narray_constructor' ) s2 = s2.replace( 'cTrajectory\narray_constructor', 'cNumeric\narray_constructor' ) s2 = s2.replace( 'cBiskit.Dock.ContactMaster\narray_constructor', 'cNumeric\narray_constructor' ) shutil.copy( fin, fout ) f = open( fin, 'w' ) f.write( s2 ) f.close() try: print "checking...", o = t.load( fin ) print "Done" except ImportError: print "could not fix %s" % fin os.rename( fout, fin ) except: print "There is still some other problem: " print t.lastError() print t.lastErrorTrace()
def update( self, model, source, skipRes=None, updateMissing=0, force=0, headPatterns=[]): """ Update empty or missing fields of model from the source. The model will be connected to the source via model.source. Profiles that are derived from the source are labeled 'changed'=0. The same holds for coordinates (xyzChanged=0). However, existing profiles or coordinates or fields remain untouched. @param model: existing model @type model: PDBModel @param source: source PDB file @type source: str @param skipRes: list residue names that should not be parsed @type skipRes: [ str ] @param updateMissing: ignored @type updateMissing: 1|0 @param headPatterns: [(putIntoKey, regex)] extract given REMARKS @type headPatterns: [(str, str)] @raise PDBParserError - if something is wrong with the source file """ try: ## atoms and/or coordinates need to be updated from PDB if force or self.needsUpdate( model ): atoms, xyz, info = self.__collectAll( source, skipRes, headPatterns ) keys = M.union( atoms.keys(), self.DEFAULTS.keys() ) for k in keys: a = model.atoms.get( k, default=0, update=False ) if (a is 0) or (a is None): dflt = self.DEFAULTS.get( k, None ) model.atoms.set(k, atoms.get(k, dflt), changed=0 ) if model.xyz is None: model.xyz = xyz model.xyzChanged = 0 model._resIndex =None model._chainIndex=None model.fileName = model.fileName or source model.pdbCode = model.pdbCode or info.get('pdb_code', None) or \ self.idFromName( model.fileName) ## make biounit from the dictionary we have parsed if 'BIOMT' in info: biomt = info['BIOMT'] model.biounit = BU.BioUnit(model, biomt) del info['BIOMT'] model.info.update( info ) except: msg = self.__xplorAtomIndicesTest( source ) or ' ' raise PDBParserError('Cannot read ' + str(source) + ' as PDB\n'\ '\ERROR: ' + T.lastError() + msg) model.setSource( source )
def nextComplex(self): """ Take list of lines, extract all Hex info about one complex (Solution number, hex energy,..) also extract 16 numbers of the transformation matrix and put them into 4 by 4 numeric array. @return: Complex created from the output from Hex @rtype: Complex """ ## get set of lines describing next complex: lines = self._nextBlock() if lines == None: ## EOF return None ## skip incomplete records if len(lines) < 13: lines = self._nextBlock() ## fill info dictionary i = {} matrix = None for l in lines: try: ## labels has to be in the same order as in hex.out m = self.ex_line.search(l) if m != None: m = m.groups() if m[0] == 'Orientation': i['hex_clst'] = int(m[1]) elif m[0] == 'Solution': i['soln'] = int(m[1]) elif m[0] == 'ReceptorModel': if self.forceModel: i['model1'] = self.forceModel[0] else: i['model1'] = int(m[1]) elif m[0] == 'LigandModel': if self.forceModel: i['model2'] = self.forceModel[1] else: i['model2'] = int(m[1]) elif m[0] == 'Bumps': if int(m[1]) != -1: i['bumps'] = int(m[1]) elif m[0] == 'ReferenceRMS': i['rms'] = float(m[1]) elif m[0] == 'Vshape': if float(m[1]) != 0.0: i['hex_Vshape'] = float(m[1]) elif m[0] == 'Vclash': if float(m[1]) != 0.0: i['hex_Vclash'] = float(m[1]) elif m[0] == 'Etotal': i['hex_etotal'] = float(m[1]) elif m[0] == 'Eshape': i['hex_eshape'] = float(m[1]) elif m[0] == 'LigandMatrix': ## get all numbers of matrix as list of strings strings = self.ex_matrix.findall(l) ## convert that to list of floats numbers = [] for each in strings: numbers += [float(each)] ## convert that to list of lists of 4 floats each matrix = [] for j in range(0, 4): matrix.append(numbers[4 * j:4 * (j + 1)]) ## create 4 by 4 Numeric array from 4 by 4 list matrix = Numeric.array(matrix, Numeric.Float32) except AttributeError: print "HexParser.nextComplex(): ", t.lastError() ## Create new complex taking PCR models from dictionary c = Complex(self.rec_models[i['model1']], self.lig_models[i['model2']], matrix, i) return c
s += "\n Please give a value for this option at the command line." s += "\n E.g: pdb2xplor.py -i input.pdb -%s some_value -t..." %\ str( why[0] ) raise XplorInputError, s except: s = "Error while adding template file." s += "\n template file: " + fTemplate s += "\n template line:\n " + str(line) s += "\n available arguments:\n" for i in valueDic.keys(): s += "\t%25s\t%s\n" % (i, str( valueDic[i] ) ) s += "\n Error:\n " + T.lastError() raise XplorInputError, s ############# ## TESTING ############# import Biskit.test as BT import tempfile class Test( BT.BiskitTest ): """ XPlorer Test """
def update(self, model, source, skipRes=None, updateMissing=0, force=0, headPatterns=[]): """ Update empty or missing fields of model from the source. The model will be connected to the source via model.source. Profiles that are derived from the source are labeled 'changed'=0. The same holds for coordinates (xyzChanged=0). However, existing profiles or coordinates or fields remain untouched. @param model: existing model @type model: PDBModel @param source: source PDB file @type source: str @param skipRes: list residue names that should not be parsed @type skipRes: [ str ] @param updateMissing: ignored @type updateMissing: 1|0 @param headPatterns: [(putIntoKey, regex)] extract given REMARKS @type headPatterns: [(str, str)] @raise PDBParserError - if something is wrong with the source file """ try: ## atoms and/or coordinates need to be updated from PDB if force or self.needsUpdate(model): atoms, xyz, info = self.__collectAll(source, skipRes, headPatterns) keys = M.union(atoms.keys(), self.DEFAULTS.keys()) for k in keys: a = model.atoms.get(k, default=0, update=False) if (a is 0) or (a is None): dflt = self.DEFAULTS.get(k, None) model.atoms.set(k, atoms.get(k, dflt), changed=0) if model.xyz is None: model.xyz = xyz model.xyzChanged = 0 model._resIndex = None model._chainIndex = None model.fileName = model.fileName or source model.pdbCode = model.pdbCode or info.get('pdb_code', None) or \ self.idFromName( model.fileName) ## ## make biounit from the dictionary we have parsed if 'BIOMT' in info: ## biomt = info['BIOMT'] ## model.biounit = BU.BioUnit(model, biomt) ## del info['BIOMT'] model.info.update(info) except: msg = self.__xplorAtomIndicesTest(source) or ' ' raise PDBParserError('Cannot read ' + str(source) + ' as PDB\n'\ '\ERROR: ' + T.lastError() + msg) model.setSource(source)
def __collectAll(self, fname, skipRes=None, headPatterns=[]): """ Parse ATOM/HETATM lines from PDB. Collect coordinates plus dictionaries with the other pdb records of each atom. REMARK, HEADER, etc. lines are ignored. Some changes are made to the dictionary from PDBFile.readline():: - the 'position' entry (with the coordinates) is removed - leading and trailing spaces are removed from 'name' .. - .. but a 'name_original' entry keeps the old name with spaces - a 'type' entry is added. Its value is 'ATOM' or 'HETATM' - a 'after_ter' entry is added. Its value is 1, if atom is preceeded by a 'TER' line, otherwise 0 - empty 'element' entries are filled with the first non-number letter from the atom 'name' @param fname: name of pdb file @type fname: str @param skipRes: list with residue names that should be skipped @type skipRes: list of str @return: tuple of (1) dictionary of profiles and (2) xyz array N x 3 @rtype: ( list, array ) """ xyz = [] aProfs = {} info = {} in_header = True headPatterns = headPatterns or self.RE_REMARKS patterns = [(key, re.compile(ex)) for key, ex in headPatterns] for k in B.PDBModel.PDB_KEYS: aProfs[k] = list() f = IO.PDBFile(fname) skipLine = False try: line, i = ('', ''), 0 while line[0] <> 'END' and line[0] <> 'ENDMDL': i += 1 if not skipLine: try: line = f.readLine() except ValueError, what: self.log.add('Warning: Error parsing line %i of %s' % (i, T.stripFilename(fname))) self.log.add('\tError: ' + str(what)) continue else: skipLine = False ## header handling if in_header and line[0] == 'HEADER': info.update(self.__parseHeader(line)) if in_header and line[0] == 'REMARK': if line[1].startswith(' 350'): biomtDict, line = self.__parseBiomt(f, line) info.update(biomtDict) # we've hogged a line beyond REMARK 350 records in # __parseBiomt(), now we need to process it here skipLine = True continue else: info.update(self.__parseRemark(line, patterns)) ## preserve position of TER records newChain = line[0] == 'TER' if newChain: line = f.readLine() if (line[0] in ['ATOM', 'HETATM']): if in_header: in_header = False ## switch off HEADER parsing a = line[1] if skipRes and a['residue_name'] in skipRes: continue a['name_original'] = a['name'] a['name'] = a['name'].strip() a['type'] = line[0] if newChain: a['after_ter'] = 1 else: a['after_ter'] = 0 if a['element'] == '': a['element'] = self.__firstLetter(a['name']) xyz.append(a['position']) del a['position'] for k, v in a.items(): aProfs[k].append(v) except: raise PDBParserError("Error parsing file "+fname+": " \ + T.lastError()) try: f.close() except: pass if len(xyz) == 0: raise PDBParserError("Error parsing file " + fname + ": " + "Couldn't find any atoms.") return aProfs, N0.array(xyz, N0.Float32), info
def __collectAll( self, fname, skipRes=None, headPatterns=[] ): """ Parse ATOM/HETATM lines from PDB. Collect coordinates plus dictionaries with the other pdb records of each atom. REMARK, HEADER, etc. lines are ignored. Some changes are made to the dictionary from PDBFile.readline():: - the 'position' entry (with the coordinates) is removed - leading and trailing spaces are removed from 'name' .. - .. but a 'name_original' entry keeps the old name with spaces - a 'type' entry is added. Its value is 'ATOM' or 'HETATM' - a 'after_ter' entry is added. Its value is 1, if atom is preceeded by a 'TER' line, otherwise 0 - empty 'element' entries are filled with the first non-number letter from the atom 'name' @param fname: name of pdb file @type fname: str @param skipRes: list with residue names that should be skipped @type skipRes: list of str @return: tuple of (1) dictionary of profiles and (2) xyz array N x 3 @rtype: ( list, array ) """ xyz = [] aProfs = {} info = {} in_header = True headPatterns = headPatterns or self.RE_REMARKS patterns = [ (key, re.compile(ex)) for key,ex in headPatterns ] for k in B.PDBModel.PDB_KEYS: aProfs[k] = list() f = IO.PDBFile( fname ) skipLine = False try: line, i = ('',''), 0 while line[0] <> 'END' and line[0] <> 'ENDMDL': i += 1 if not skipLine: try: line = f.readLine() except ValueError, what: self.log.add('Warning: Error parsing line %i of %s' % (i, T.stripFilename( fname )) ) self.log.add('\tError: '+str(what) ) continue else: skipLine = False ## header handling if in_header and line[0] == 'HEADER': info.update( self.__parseHeader( line ) ) if in_header and line[0] == 'REMARK': if line[1].startswith(' 350'): biomtDict, line = self.__parseBiomt( f, line ) info.update( biomtDict ) # we've hogged a line beyond REMARK 350 records in # __parseBiomt(), now we need to process it here skipLine = True continue else: info.update( self.__parseRemark( line, patterns ) ) ## preserve position of TER records newChain = line[0] == 'TER' if newChain: line = f.readLine() if (line[0] in ['ATOM','HETATM'] ): if in_header: in_header = False ## switch off HEADER parsing a = line[1] if skipRes and a['residue_name'] in skipRes: continue a['name_original'] = a['name'] a['name'] = a['name'].strip() a['type'] = line[0] if newChain: a['after_ter'] = 1 else: a['after_ter'] = 0 if a['element'] == '': a['element'] = self.__firstLetter( a['name'] ) if a['position'].is_vector: lst = [ a['position'][0], a['position'][1], a['position'][2]] xyz.append( lst ) else: xyz.append( a['position'] ) del a['position'] for k, v in a.items(): aProfs[k].append( v ) except: raise PDBParserError("Error parsing file "+fname+": " \ + T.lastError()) try: f.close() except: pass if len( xyz ) == 0: raise PDBParserError("Error parsing file "+fname+": "+ "Couldn't find any atoms.") return aProfs, N.array( xyz, N.Float32 ), info