def __call__(self): # get view on screen my_view = cmd.get_view() delta_mv = 0. for i in range(18): delta_mv = max(delta_mv,abs(my_view[i] - self.my_view[i])) self.my_view[i] = my_view[i] #print my_view # get orientation/position matrices for two molecules # how does pymol define rotation center of molecule? # apparnetly by geometric average pdbmat1 = cmd.get_object_matrix(self.pdbobj1) pdbmat2 = cmd.get_object_matrix(self.pdbobj2) delta_mm = 0. for i in range(12): delta_mm = max(delta_mm,abs(pdbmat1[i] - self.objmat1[i])) delta_mm = max(delta_mm,abs(pdbmat2[i] - self.objmat2[i])) self.objmat1[i] = pdbmat1[i] self.objmat2[i] = pdbmat2[i] if(delta_mm > 0.01): # we only do expensive energy calc if pose changed do_mm = True else: do_mm = False if((delta_mv > 0.01) or do_mm): # we only update if pose or view changed cgo_obj = pdb_interaction(pdbmat1,pdbmat2,self.pdb1,self.pdb2,self.gcen1,self.gcen2, self.energy,do_mm,self.logscale,self.dielectric,self.eps,self.nbest,self.energy_min) if(self.nbest[0] != self.nbest[1]): # print('Switching models ',self.nbest) self.nbest[1] = self.nbest[0] # # write new best pose to logfile # et = self.energy[0] ee = self.energy[1] ev = self.energy[2] if(self.energy[0] < self.energy_min): print(' NEW MIN ee: %12.3g ev: %12.3g et: %12.3g model %4d ' % (ee,ev,et,self.nbest[0])) self.energy_min = et self.dockeye_log.write('new min: %12.5g %12.5g %12.5g model %4d \n' % (ee,ev,et,self.nbest[0])) for i in range(4): for j in range(4): indx = j + 4*i self.dockeye_log.write('%12.5f ' % (pdbmat1[indx])) self.dockeye_log.write('\n') for i in range(4): for j in range(4): indx = j + 4*i self.dockeye_log.write('%12.5f ' % (pdbmat2[indx])) self.dockeye_log.write('\n') #else: # if(do_mm): # #print('Current energy: ee: %12.3g ev: %12.3g et: %12.3g' % (ee,ev,et)) # continue if(do_mm): cmd.delete('dockeye_obj') cmd.load_cgo(cgo_obj,'dockeye_obj') draw_ligand(pdbmat2,self.pdb2,self.gcen2,self.nbest[0])
def test_matrix_copy(self): cmd.fragment('ala') cmd.fragment('gly') cmd.rotate('x', 90, 'none', object='ala') cmd.matrix_copy('ala', 'gly') self.assertArrayEqual(cmd.get_object_matrix('gly'), (1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0), 1e-4) cmd.matrix_reset('gly', mode=1) self.assertArrayEqual(cmd.get_object_matrix('gly'), (1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), 1e-4)
def testReset(self): # view v = cmd.get_view() cmd.turn('x', 10) cmd.move('y', 10) self.assertNotEqual(v, cmd.get_view()) cmd.reset() self.assertEqual(v, cmd.get_view()) # object cmd.pseudoatom("m1") x = cmd.get_object_matrix("m1") cmd.translate([1,2,3], object="m1") self.assertNotEqual(x, cmd.get_object_matrix("m1")) cmd.reset("m1") self.assertEqual(x, cmd.get_object_matrix("m1"))
def testReset(self): # view v = cmd.get_view() cmd.turn('x', 10) cmd.move('y', 10) self.assertNotEqual(v, cmd.get_view()) cmd.reset() self.assertEqual(v, cmd.get_view()) # object cmd.pseudoatom("m1") x = cmd.get_object_matrix("m1") cmd.translate([1, 2, 3], object="m1") self.assertNotEqual(x, cmd.get_object_matrix("m1")) cmd.reset("m1") self.assertEqual(x, cmd.get_object_matrix("m1"))
def calc_super_matrix(mobile, static): ''' DESCRIPTION Aligns two objects (or selections), returns the transformation matrix, and resets the matrix of the mobile object. Uses CEAlign PyMOL function for alignment. ARGUMENTS mobile = string: selection describing the mobile object whose rotation matrix will be reported static = string: selection describing the static object onto which the mobile object will be aligned REQUIRES: numpy ''' cmd.cealign(static, mobile) # cmd.super(mobile,static) T = cmd.get_object_matrix(mobile) R = numpy.identity(4) k = 0 for i in range(0, 4): for j in range(0, 4): R[i][j] = T[k] k += 1 return R
def test_matrix_copy(self): cmd.fragment('ala') cmd.fragment('gly') cmd.rotate('x', 90, 'none', object='ala') cmd.matrix_copy('ala', 'gly') self.assertArrayEqual(cmd.get_object_matrix('gly'), (1.0, 0.0, 0.0, 0.0, 0.0, 0.0,-1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0), 1e-4) cmd.matrix_reset('gly', mode=1) self.assertArrayEqual(cmd.get_object_matrix('gly'), (1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), 1e-4)
def testPairFit(self): cmd.fragment('trp') cmd.fragment('his') # 1 atom sele = ('trp and guide', 'his and guide') pos = list(map(cmd.get_atom_coords, sele)) vec = cpv.sub(*pos) mat_ref = [ 1.0, 0.0, 0.0, -vec[0], 0.0, 1.0, 0.0, -vec[1], 0.0, 0.0, 1.0, -vec[2], 0.0, 0.0, 0.0, 1.0] rms = cmd.pair_fit(*sele) self.assertEqual(rms, 0.0) mat = cmd.get_object_matrix('trp') self.assertArrayEqual(mat, mat_ref, 1e-4) # 2 atoms sele += ('trp & name CB', 'his & name CB') rms = cmd.pair_fit(*sele) self.assertAlmostEqual(rms, 0.0082, delta=1e-4) # 4 atoms sele += ('trp & name CG', 'his & name CG', 'trp & name CD1', 'his & name CD2') rms = cmd.pair_fit(*sele) self.assertAlmostEqual(rms, 0.0713, delta=1e-4)
def testPairFit(self): cmd.fragment('trp') cmd.fragment('his') # 1 atom sele = ('trp and guide', 'his and guide') pos = list(map(cmd.get_atom_coords, sele)) vec = cpv.sub(*pos) mat_ref = [ 1.0, 0.0, 0.0, -vec[0], 0.0, 1.0, 0.0, -vec[1], 0.0, 0.0, 1.0, -vec[2], 0.0, 0.0, 0.0, 1.0 ] rms = cmd.pair_fit(*sele) self.assertEqual(rms, 0.0) mat = cmd.get_object_matrix('trp') self.assertArrayEqual(mat, mat_ref, 1e-4) # 2 atoms sele += ('trp & name CB', 'his & name CB') rms = cmd.pair_fit(*sele) self.assertAlmostEqual(rms, 0.0082, delta=1e-4) # 4 atoms sele += ('trp & name CG', 'his & name CG', 'trp & name CD1', 'his & name CD2') rms = cmd.pair_fit(*sele) self.assertAlmostEqual(rms, 0.0713, delta=1e-4)
def test_set_object_ttt(self): M = [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] cmd.pseudoatom('m1') cmd.set_object_ttt('m1', M) self.assertArrayEqual(M, cmd.get_object_matrix('m1'), 1e-4)
def test_set_object_ttt(self): M = [1.0, 0.0, 0.0, 0.0, 0.0, 0.0,-1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0] cmd.pseudoatom('m1') cmd.set_object_ttt('m1', M) self.assertArrayEqual(M, cmd.get_object_matrix('m1'), 1e-4)
def _update_transformation(self): """Checks if PyMOL object matrix has changed and updates self, if so.""" try: if cmd.get_title(*Registry.get(self.attachment.main_object, "name", "state")) == "PD": matrix = cmd.get_object_matrix(Registry.get(self.attachment.main_object, "name")) self.reset() self.add_rotation([matrix[:3], matrix[4:7], matrix[8:11]]) self.add_translation([matrix[3], matrix[7], matrix[11]]) self.add_prerotational_translation(list(matrix[12:15])) except AttributeError: return
def testGetObjectMatrix(self): identity = (1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0) mat_x90 = (1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0) cmd.fragment('ala', 'm1') cmd.fragment('gly', 'm2') # default/identity mat = cmd.get_object_matrix('m1', incl_ttt=1) self.assertTrue(isinstance(mat, tuple)) self.assertArrayEqual(mat, identity, delta=1e-6) mat = cmd.get_object_matrix('m1', incl_ttt=0) self.assertArrayEqual(mat, identity, delta=1e-6) # TTT cmd.rotate('x', 90, object='m1', camera=0, object_mode=0) mat = cmd.get_object_matrix('m1', incl_ttt=1) self.assertArrayEqual(mat, mat_x90, delta=1e-6) mat = cmd.get_object_matrix('m1', incl_ttt=0) self.assertArrayEqual(mat, identity, delta=1e-6) # state matrix cmd.rotate('x', 90, object='m2', camera=0, object_mode=1) mat = cmd.get_object_matrix('m2', incl_ttt=1) self.assertArrayEqual(mat, mat_x90, delta=1e-6) mat = cmd.get_object_matrix('m2', incl_ttt=0) self.assertArrayEqual(mat, mat_x90, delta=1e-6)
def transf_matrix(chA, chB): ''' DESCRIPTION Align two selections/chains, and returns the transformation matrix. I used super to carry out the alignment, likely is possible to use cmd.align and is going to be a bit faster, but I think is not going to work well with low-sequence-identity alignments. ''' cmd.create('working', chA) cmd.super('working', chB) T = cmd.get_object_matrix('working') global cmW cmW = center_of_Mass('working') cmd.delete('working') return T
def matrix_to_ttt(names, reverse=0, state=-1, quiet=1): ''' DESCRIPTION Objects can have state matrices and view (frames) matrices. This function takes the total matrix and stores it either as view matrix or as state matrix (reverse=1). For movie frames, movie_auto_store must be set. ''' from . import querying reverse, state, quiet = int(reverse), int(state), int(quiet) ostate = state for object in cmd.get_object_list('(' + names + ')'): if ostate < 1: state = querying.get_object_state(object) matrix = cmd.get_object_matrix(object, state) cmd.matrix_reset(object) if reverse: cmd.reset(object) cmd.transform_object(object, matrix, homogenous=1) else: cmd.set_object_ttt(object, matrix)
def matrix_to_ttt(names, reverse=0, state=-1, quiet=1): ''' DESCRIPTION Objects can have state matrices and view (frames) matrices. This function takes the total matrix and stores it either as view matrix or as state matrix (reverse=1). For movie frames, movie_auto_store must be set. ''' from . import querying reverse, state, quiet = int(reverse), int(state), int(quiet) ostate = state for object in cmd.get_object_list('(' + names + ')'): if ostate < 1: state = querying.get_object_state(object) matrix = cmd.get_object_matrix(object, state) for i in range(cmd.count_states(object)): cmd.matrix_reset(object, i + 1) if reverse: cmd.reset(object) cmd.transform_object(object, matrix, homogenous=1) else: cmd.set_object_ttt(object, matrix)
def test(self): cmd.pseudoatom('m1') cmd.mset('1x1') cmd.create('m2', 'm1') cmd.ray() v = cmd.get_object_matrix('m2') self.assertArrayEqual(v, [ 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., ], 0.001, 'object matrix not identity')
def angle_between_domains(selection1, selection2, method='align', state1=STATE, state2=STATE, visualize=1, quiet=1): ''' DESCRIPTION Angle by which a molecular selection would be rotated when superposing on a selection2. Do not use for measuring angle between helices, since the alignment of the helices might involve a rotation around the helix axis, which will result in a larger angle compared to the angle between helix axes. USAGE angle_between_domains selection1, selection2 [, method ] ARGUMENTS selection1 = string: atom selection of first helix selection2 = string: atom selection of second helix method = string: alignment command like "align" or "super" {default: align} EXAMPLE fetch 3iplA 3iplB, bsync=0 select domain1, resi 1-391 select domain2, resi 392-475 align 3iplA and domain1, 3iplB and domain1 angle_between_domains 3iplA and domain2, 3iplB and domain2 SEE ALSO align, super, angle_between_helices ''' import math try: import numpy except ImportError: print(' Error: numpy not available') raise CmdException state1, state2 = int(state1), int(state2) visualize, quiet = int(visualize), int(quiet) if cmd.is_string(method): try: method = cmd.keyword[method][0] except KeyError: print('no such method:', method) raise CmdException mobile_tmp = get_unused_name('_') cmd.create(mobile_tmp, selection1, state1, 1, zoom=0) try: method(mobile=mobile_tmp, target=selection2, mobile_state=1, target_state=state2, quiet=quiet) mat = cmd.get_object_matrix(mobile_tmp) except: print(' Error: superposition with method "%s" failed' % (method.__name__)) raise CmdException finally: cmd.delete(mobile_tmp) try: # Based on transformations.rotation_from_matrix # Copyright (c) 2006-2012, Christoph Gohlke R33 = [mat[i:i + 3] for i in [0, 4, 8]] R33 = numpy.array(R33, float) # direction: unit eigenvector of R33 corresponding to eigenvalue of 1 w, W = numpy.linalg.eig(R33.T) i = w.real.argmax() direction = W[:, i].real # rotation angle depending on direction m = direction.argmax() i, j, k, l = [[2, 1, 1, 2], [0, 2, 0, 2], [1, 0, 0, 1]][m] cosa = (R33.trace() - 1.0) / 2.0 sina = (R33[i, j] + (cosa - 1.0) * direction[k] * direction[l]) / direction[m] angle = math.atan2(sina, cosa) angle = abs(math.degrees(angle)) except: print(' Error: rotation from matrix failed') raise CmdException if not quiet: try: # make this import optional to support running this script standalone from .querying import centerofmass, gyradius except (ValueError, ImportError): gyradius = None try: # PyMOL 1.7.1.6+ centerofmass = cmd.centerofmass except AttributeError: centerofmass = lambda s: cpv.scale(cpv.add(*cmd.get_extent(s)), 0.5) center1 = centerofmass(selection1) center2 = centerofmass(selection2) print(' Angle: %.2f deg, Displacement: %.2f angstrom' % (angle, cpv.distance(center1, center2))) if visualize: center1 = numpy.array(center1, float) center2 = numpy.array(center2, float) center = (center1 + center2) / 2.0 if gyradius is not None: rg = numpy.array(gyradius(selection1), float) else: rg = 10.0 h1 = numpy.cross(center2 - center1, direction) h2 = numpy.dot(R33, h1) h1 *= rg / cpv.length(h1) h2 *= rg / cpv.length(h2) for pos in [center1, center2, center1 + h1, center1 + h2]: cmd.pseudoatom(mobile_tmp, pos=list(pos), state=1) # measurement object for angle and displacement name = get_unused_name('measurement') cmd.distance(name, *['%s`%d' % (mobile_tmp, i) for i in [1, 2]]) cmd.angle(name, *['%s`%d' % (mobile_tmp, i) for i in [3, 1, 4]]) # CGO arrow for axis of rotation visualize_orientation(direction, center1, rg, color='blue') cmd.delete(mobile_tmp) return angle
def alignlattice( target, mobile, a, b, c, color1="blue", color2="red", name1="supercell1", name2="supercell2", prefix1="m", prefix2="n", withmates=1, cutoff=None, ): """ DESCRIPTION Align two lattices. This facilitates the comparison of lattice contacts. USAGE alignlattice target, mobile, a, b, c, [color1/2, name1/2, prefix1/2, withmates, cutoff] ARGUMENTS target = string: name of object to generate the first lattice. This lattice is generated aligned to the original coordinates. mobile = string: name of the second object. The generated lattice will align to the original object. a, b, c = integer: repeat cell in x,y,z direction a,b,c times {default: 1,1,1} color1/2 = string: color of unit cell cgo objects {default: blue/red} name1/2 = string: name of the cgo object to create {default: supercell1/2} prefix1/2 = string: prefix for the symmetry mates {default: m/n} withmates = bool: also create symmetry mates in displayed cells {default: 1} cutoff = int: restrict symmetry mates to within cutoff angstroms of the origin. Use 0 to generate all symmetry mates. {default: 0} SEE ALSO show cell cmd """ # Check that selections contain a single object each mobileobj = "(byobj (%s))" % mobile targetobj = "(byobj (%s))" % target if len(cmd.get_object_list(mobileobj)) != 1: print("Expected single object for %s" % mobile) return if len(cmd.get_object_list(targetobj)) != 1: print("Expected single object for %s" % target) return mobilecopy = "mobile2823" # todo use unique name # Copy the mobile unit and get its superposition with the target cmd.create(mobilecopy, mobile) initial_mat = cmd.get_object_matrix(mobilecopy) cmd.super(mobilecopy, target) final_mat = cmd.get_object_matrix(mobilecopy) cmd.delete(mobilecopy) # TODO handle non-identity initial matrix orig_objects = set(cmd.get_object_list()) # Generate primary grid supercell( a, b, c, targetobj, color=color1, name=name1, withmates=withmates, prefix=prefix1, center=1, transformation=None, cutoff=cutoff, ) # Generate rotated grid supercell( a, b, c, mobileobj, color=color2, name=name2, withmates=withmates, prefix=prefix2, center=1, transformation=final_mat, cutoff=cutoff, ) colored_objects1 = set(cmd.get_object_list("(%s*)" % prefix1)) - orig_objects colored_objects2 = set(cmd.get_object_list("(%s*)" % prefix2)) - orig_objects for obj in colored_objects1: cmd.color(color1, obj) for obj in colored_objects2: cmd.color(color2, obj)
def angle_between_domains(selection1, selection2, method='align', state1=STATE, state2=STATE, visualize=1, quiet=1): ''' DESCRIPTION Angle by which a molecular selection would be rotated when superposing on a selection2. Do not use for measuring angle between helices, since the alignment of the helices might involve a rotation around the helix axis, which will result in a larger angle compared to the angle between helix axes. USAGE angle_between_domains selection1, selection2 [, method ] ARGUMENTS selection1 = string: atom selection of first helix selection2 = string: atom selection of second helix method = string: alignment command like "align" or "super" {default: align} EXAMPLE fetch 3iplA 3iplB, async=0 select domain1, resi 1-391 select domain2, resi 392-475 align 3iplA and domain1, 3iplB and domain1 angle_between_domains 3iplA and domain2, 3iplB and domain2 SEE ALSO align, super, angle_between_helices ''' import math try: import numpy except ImportError: print ' Error: numpy not available' raise CmdException state1, state2 = int(state1), int(state2) visualize, quiet = int(visualize), int(quiet) if cmd.is_string(method): try: method = cmd.keyword[method][0] except KeyError: print 'no such method:', method raise CmdException mobile_tmp = get_unused_name('_') cmd.create(mobile_tmp, selection1, state1, 1, zoom=0) try: method(mobile=mobile_tmp, target=selection2, mobile_state=1, target_state=state2, quiet=quiet) mat = cmd.get_object_matrix(mobile_tmp) except: print ' Error: superposition with method "%s" failed' % (method.__name__) raise CmdException finally: cmd.delete(mobile_tmp) try: # Based on transformations.rotation_from_matrix # Copyright (c) 2006-2012, Christoph Gohlke R33 = [mat[i:i+3] for i in [0,4,8]] R33 = numpy.array(R33, float) # direction: unit eigenvector of R33 corresponding to eigenvalue of 1 w, W = numpy.linalg.eig(R33.T) i = w.real.argmax() direction = W[:, i].real # rotation angle depending on direction m = direction.argmax() i,j,k,l = [ [2,1,1,2], [0,2,0,2], [1,0,0,1]][m] cosa = (R33.trace() - 1.0) / 2.0 sina = (R33[i, j] + (cosa - 1.0) * direction[k] * direction[l]) / direction[m] angle = math.atan2(sina, cosa) angle = abs(math.degrees(angle)) except: print ' Error: rotation from matrix failed' raise CmdException if not quiet: try: # make this import optional to support running this script standalone from .querying import centerofmass, gyradius except (ValueError, ImportError): gyradius = None try: # PyMOL 1.7.1.6+ centerofmass = cmd.centerofmass except AttributeError: centerofmass = lambda s: cpv.scale(cpv.add(*cmd.get_extent(s)), 0.5) center1 = centerofmass(selection1) center2 = centerofmass(selection2) print ' Angle: %.2f deg, Displacement: %.2f angstrom' % (angle, cpv.distance(center1, center2)) if visualize: center1 = numpy.array(center1, float) center2 = numpy.array(center2, float) center = (center1 + center2) / 2.0 if gyradius is not None: rg = numpy.array(gyradius(selection1), float) else: rg = 10.0 h1 = numpy.cross(center2 - center1, direction) h2 = numpy.dot(R33, h1) h1 *= rg / cpv.length(h1) h2 *= rg / cpv.length(h2) for pos in [center1, center2, center1 + h1, center1 + h2]: cmd.pseudoatom(mobile_tmp, pos=list(pos), state=1) # measurement object for angle and displacement name = get_unused_name('measurement') cmd.distance(name, *['%s`%d' % (mobile_tmp, i) for i in [1,2]]) cmd.angle(name, *['%s`%d' % (mobile_tmp, i) for i in [3,1,4]]) # CGO arrow for axis of rotation visualize_orientation(direction, center1, rg, color='blue') cmd.delete(mobile_tmp) return angle
def biomolecule(name=None, filename=None, prefix=None, number=1, suffix=None, quiet=0): ''' DESCRIPTION Create biological unit (quaternary structure) as annotated by the REMARK 350 BIOMOLECULE record. USAGE biomolecule name [, filename [, prefix [, number ]]] ARGUMENTS name = string: name of object and basename of PDB file, if filename is not given {default: first loaded object} filename = string: file to read remarks from {default: <name>.pdb} prefix = string: prefix for new objects {default: <name>} EXAMPLE fetch 1rmv, async=0 biomolecule 1rmv ''' import os from .importing import local_mirror_pdb try: import numpy except ImportError: numpy = None number, quiet = int(number), int(quiet) if name is None: name = cmd.get_object_list()[0] if prefix is None: prefix = name if suffix is None: suffix = str(number) if filename is None: candidates = [ '%s.pdb' % (name), '%s/%s.pdb' % (cmd.get('fetch_path'), name), local_mirror_pdb(name), ] for filename in candidates: if os.path.exists(filename): break else: print('please provide filename') raise CmdException if not quiet: print('loading from %s' % (filename)) remarks = pdbremarks(filename) if 350 not in remarks: print('There is no REMARK 350 in ' + filename) raise CmdException current = 1 biomt = {current: {}} chains = tuple() for line in remarks[350]: if line.startswith('BIOMOLECULE:'): current = int(line[12:]) biomt[current] = {} elif line.startswith('APPLY THE FOLLOWING TO CHAINS:'): chains = tuple(chain.strip() for chain in line[30:].split(',')) elif line.startswith(' AND CHAINS:'): chains += tuple(chain.strip() for chain in line[30:].split(',')) elif line.startswith(' BIOMT'): row = int(line[7]) num = int(line[8:12]) vec = line[12:].split() vec = list(map(float, vec)) biomt[current].setdefault(chains, dict()).setdefault(num, []).extend(vec) if number not in biomt or len(biomt[number]) == 0: print(' Error: no BIOMOLECULE number %d' % (number)) raise CmdException if numpy is not None: mat_source = numpy.reshape(cmd.get_object_matrix(name), (4, 4)) mat_source = numpy.matrix(mat_source) for chains, matrices in biomt[number].items(): for num in matrices: mat = matrices[num][0:12] mat.extend([0, 0, 0, 1]) copy = '%s_%s_%d' % (prefix, suffix, num) if not quiet: print('creating %s' % (copy)) cmd.create(copy, 'model %s and chain %s' % (name, '+'.join(chains))) cmd.alter(copy, 'segi="%d"' % (num)) if numpy is not None: mat = mat_source * numpy.reshape(mat, (4, 4)) * mat_source.I mat = list(mat.flat) cmd.transform_object(copy, mat) cmd.disable(name) cmd.group('%s_%s' % (prefix, suffix), '%s_%s_*' % (prefix, suffix))
def biomolecule(name=None, filename=None, prefix=None, number=1, suffix=None, quiet=0): ''' DESCRIPTION Create biological unit (quaternary structure) as annotated by the REMARK 350 BIOMOLECULE record. USAGE biomolecule name [, filename [, prefix [, number ]]] ARGUMENTS name = string: name of object and basename of PDB file, if filename is not given {default: first loaded object} filename = string: file to read remarks from {default: <name>.pdb} prefix = string: prefix for new objects {default: <name>} EXAMPLE fetch 1rmv, async=0 biomolecule 1rmv ''' import os from .importing import local_mirror_pdb try: import numpy except ImportError: numpy = None number, quiet = int(number), int(quiet) if name is None: name = cmd.get_object_list()[0] if prefix is None: prefix = name if suffix is None: suffix = str(number) if filename is None: candidates = [ '%s.pdb' % (name), '%s/%s.pdb' % (cmd.get('fetch_path'), name), local_mirror_pdb(name), ] for filename in candidates: if os.path.exists(filename): break else: print('please provide filename') raise CmdException if not quiet: print('loading from %s' % (filename)) remarks = pdbremarks(filename) if 350 not in remarks: print('There is no REMARK 350 in', filename) raise CmdException current = 1 biomt = {current: {}} chains = tuple() for line in remarks[350]: if line.startswith('BIOMOLECULE:'): current = int(line[12:]) biomt[current] = {} elif line.startswith('APPLY THE FOLLOWING TO CHAINS:'): chains = tuple(chain.strip() for chain in line[30:].split(',')) elif line.startswith(' AND CHAINS:'): chains += tuple(chain.strip() for chain in line[30:].split(',')) elif line.startswith(' BIOMT'): row = int(line[7]) num = int(line[8:12]) vec = line[12:].split() vec = list(map(float, vec)) biomt[current].setdefault(chains, dict()).setdefault(num, []).extend(vec) if number not in biomt or len(biomt[number]) == 0: print(' Error: no BIOMOLECULE number %d' % (number)) raise CmdException if numpy is not None: mat_source = numpy.reshape(cmd.get_object_matrix(name), (4,4)) mat_source = numpy.matrix(mat_source) for chains, matrices in biomt[number].items(): for num in matrices: mat = matrices[num][0:12] mat.extend([0,0,0,1]) copy = '%s_%s_%d' % (prefix, suffix, num) if not quiet: print('creating %s' % (copy)) cmd.create(copy, 'model %s and chain %s' % (name, '+'.join(chains))) cmd.alter(copy, 'segi="%d"' % (num)) if numpy is not None: mat = mat_source * numpy.reshape(mat, (4,4)) * mat_source.I mat = list(mat.flat) cmd.transform_object(copy, mat) cmd.disable(name) cmd.group('%s_%s' % (prefix, suffix), '%s_%s_*' % (prefix, suffix))
def __call__(self): # 1st check for a dockeye action flag de_action = 'none' mark_number = 0 do_mm = True try: actionfile = open('dockeye_action', 'r') line = actionfile.readline() fields = line.split() de_action = fields[0] mark_number = int(fields[1]) actionfile.close() os.system('/bin/rm -f dockeye_action') #print(de_action,mark_number) except: # de_action = 'none' mark_number = 0 # get view on screen my_view = cmd.get_view() delta_mv = 0. for i in range(18): delta_mv = max(delta_mv, abs(my_view[i] - self.my_view[i])) self.my_view[i] = my_view[i] #print my_view # get orientation/position matrices for two molecules # how does pymol define rotation center of molecule? # apparnetly by geometric average pdbmat1 = cmd.get_object_matrix(self.pdbobj1) pdbmat2 = cmd.get_object_matrix(self.pdbobj2) # if (de_action == 'mark'): # write bookmark print('bookmarking... ', mark_number) et = self.energy[0] ee = self.energy[1] ev = self.energy[2] print('current energies: %12.5g %12.5g %12.5g model %4d \n' % (ee, ev, et, self.nbest[0])) #mark_prt = 'dockeye_prt_mark_%d.pdb' % (mark_number) mark_lig = 'dockeye_lig_mark_%d.pdb' % (mark_number) ligfile = open(mark_lig, 'w') ligfile.write('REMARK pdbfile 1: ' + self.pdbfile1 + '\n') ligfile.write('REMARK pdbfile 2: ' + self.pdbfile2 + '\n') ligfile.write('REMARK # of atoms 1: %6d 2: %6d\n' % (self.pdb1.natom, self.pdb2.natom)) ligfile.write('REMARK geometric centers: \n') ligfile.write('REMARK 1: %8.3f %8.3f %8.3f \n' % (self.gcen1[0], self.gcen1[1], self.gcen1[2])) ligfile.write('REMARK 2: %8.3f %8.3f %8.3f \n' % (self.gcen2[0], self.gcen2[1], self.gcen2[2])) ligfile.write('REMARK net charge 1: %8.3f 2: %8.3f \n' % (self.qtot1, self.qtot2)) ligfile.write( 'REMARK energy parameters dielectric: blank VDW depth: blank\n' ) ligfile.write('REMARK # of ligand conformers: %6d\n' % (self.pdb2.nmodel)) ligfile.write( 'REMARK current energies: %12.5g %12.5g %12.5g model %4d \n' % (ee, ev, et, self.nbest[0])) for i in range(4): for j in range(4): indx = j + 4 * i ligfile.write('REMARK %12.5f ' % (pdbmat1[indx])) ligfile.write('\n') for i in range(4): for j in range(4): indx = j + 4 * i ligfile.write('REMARK %12.5f ' % (pdbmat2[indx])) ligfile.write('\n') # # extract rot rmtp = [[pdbmat1[0], pdbmat1[1], pdbmat1[2]], [pdbmat1[4], pdbmat1[5], pdbmat1[6]], [pdbmat1[8], pdbmat1[9], pdbmat1[10]]] rmtl = [[pdbmat2[0], pdbmat2[1], pdbmat2[2]], [pdbmat2[4], pdbmat2[5], pdbmat2[6]], [pdbmat2[8], pdbmat2[9], pdbmat2[10]]] # # extract trans trnp = [pdbmat1[3], pdbmat1[7], pdbmat1[11]] trnl = [pdbmat2[3], pdbmat2[7], pdbmat2[11]] # # apply transrot to coords # write out transrot to temporary pdb files gcenp_rot = rot_vec(rmtp, self.gcen1) gcenl_rot = rot_vec(rmtl, self.gcen2) for k in range(3): trnp[k] = trnp[k] - (self.gcen1[k] - gcenp_rot[k]) trnl[k] = trnl[k] - (self.gcen2[k] - gcenl_rot[k]) i1 = 0 #print(rmtp,trnp) #print(rmtl,trnl) xyz = [0., 0., 0.] tmpfile = 'dockeye_lig_tmp.pdb' for n in range(self.pdb2.nmodel): ligfile.write('MODEL%4d \n' % (n + 1)) for i in range(self.pdb2.natom): # # apply rotations and translations # and inverse of protein rot/trans to ligand # in case user moved protein too- now ligand should be in # coord frame of original protein pdb for k in range(3): xyz[k] = self.pdb2.coords[i1][k] - self.gcen2[k] xyz1 = rot_vec(rmtl, xyz) for k in range(3): xyz[k] = xyz1[k] + self.gcen2[k] + trnl[ k] - self.gcen1[k] - trnp[k] xyz2 = rot_vec(rmtp, xyz, inv=1) for k in range(3): xyz[k] = xyz2[k] + self.gcen1[k] string = 'ATOM %6d%6s%4s%1s%4s %8.3f%8.3f%8.3f%6.2f%7.3f \n' \ % (i,self.pdb2.name[i],self.pdb2.res[i], \ self.pdb2.chain[i], self.pdb2.resnum[i], xyz[0],xyz[1],xyz[2], \ self.pdb2.radius[i],self.pdb2.bfact[i]) ligfile.write(string) i1 += 1 ligfile.write('ENDMDL\n') ligfile.close() mark_pml = 'dockeye_mark_%d.pml' % (mark_number) pmlfile = open(mark_pml, 'w') pmlfile.write( '#------------------------------------------------\n') pmlfile.write('run $HOME/source/dockeye_multi/src/dockeyeM_c.py\n') pmlfile.write('de("%s","%s")\n' % (self.pdbfile1, mark_lig)) pmlfile.write('#optional view settings\n') pmlfile.write('hide lines\n') pmlfile.write('spectrum b, red_white_blue\n') pmlfile.write('show sticks, dockeye_lig\n') pmlfile.write('show surface, dockeye_prt\n') pmlfile.write('set transparency, 0.4\n') pmlfile.write( '#------------------------------------------------\n') pmlfile.close() # done with bookmarking # # check for new view or pose # delta_mm = 0. for i in range(12): delta_mm = max(delta_mm, abs(pdbmat1[i] - self.objmat1[i])) delta_mm = max(delta_mm, abs(pdbmat2[i] - self.objmat2[i])) self.objmat1[i] = pdbmat1[i] self.objmat2[i] = pdbmat2[i] if (delta_mm > 0.01): # we only do expensive energy calc if pose changed do_mm = True else: do_mm = False if ((delta_mv > 0.01) or do_mm): # we only update if pose or view changed cgo_obj = pdb_interaction(pdbmat1, pdbmat2, self.pdb1, self.pdb2, self.gcen1, self.gcen2, self.energy, do_mm, self.logscale, self.dielectric, self.eps, self.nbest, self.energy_min) if (self.nbest[0] != self.nbest[1]): # print('Switching models ',self.nbest) self.nbest[1] = self.nbest[0] # # write new best pose to logfile # et = self.energy[0] ee = self.energy[1] ev = self.energy[2] if (self.energy[0] < self.energy_min): print( ' NEW MIN ee: %12.3g ev: %12.3g et: %12.3g model %4d ' % (ee, ev, et, self.nbest[0])) self.energy_min = et self.dockeye_log.write( 'new min: %12.5g %12.5g %12.5g model %4d \n' % (ee, ev, et, self.nbest[0])) for i in range(4): for j in range(4): indx = j + 4 * i self.dockeye_log.write('%12.5f ' % (pdbmat1[indx])) self.dockeye_log.write('\n') for i in range(4): for j in range(4): indx = j + 4 * i self.dockeye_log.write('%12.5f ' % (pdbmat2[indx])) self.dockeye_log.write('\n') #else: # if(do_mm): # #print('Current energy: ee: %12.3g ev: %12.3g et: %12.3g' % (ee,ev,et)) # continue if (do_mm): cmd.delete('dockeye_obj') cmd.load_cgo(cgo_obj, 'dockeye_obj') draw_ligand(pdbmat2, self.pdb2, self.gcen2, self.nbest[0])