def load(): cmd.set("valence") r = 0 list = glob("pdb/*/*") (x, y, z) = (0, 0, 0) start = time.time() count = 1 scale = 100.0 for file in list: cmd.load(file, str(count), quiet=1) cmd.translate([x * scale, y * scale, z * scale], object=str(count)) # cmd.disable(str(count)) atoms = cmd.count_atoms() passed = time.time() - start print "%3d structures/%5.1f sec = %8.1f atom/sec over %6d atoms" % ( count, passed, atoms / passed, atoms) count = count + 1 if count > 100: break x = x + 1 if x > 7: x = 0 y = y + 1 if y > 7: y = 0 z = z + 1 if z > 9: y = 0 z = z + 1 cmd.zoom() cmd.set("sphere_mode", 1) cmd.show_as("spheres") cmd.rebuild() cmd.set("hash_max", 250)
def zoom_dimer(object_name): # Get a neutral, symmetric view of the molecule(s) # cmd.viewport(viewport_width_dimer(), viewport_height_dimer()) cmd.orient(object_name) cmd.zoom("center", 35) cmd.translate([0,4,0], "(all)") return
def rezoom_tetramer_deo_alignment(target, mobile_pdb): # cmd.viewport(viewport_width_tetramer_alignment(), viewport_height_tetramer_alignment()) cmd.orient(target) cmd.zoom("center", 75) y = tetramer_alignment_centering_y(mobile_pdb) cmd.translate([0,y,0], "(all)") return
def builderMicelle(detergent, r, numberOfDetergents): i = 0 numberOfDetergents = (int)(numberOfDetergents) #FIXME: if number of detergents > 360, molecules may clash in space if numberOfDetergents > 360: x1 = range(-180, 180) x2 = range(0, 360) theta = ([random.choice(x1) for _ in range(numberOfDetergents)]) phi = ([random.choice(x2) for _ in range(numberOfDetergents)]) else: theta = random.sample(range(-180, 180), numberOfDetergents) phi = random.sample(range(0, 360), numberOfDetergents) for t, p in zip(theta, phi): i += 1 cmd.copy(f"seg{i}", detergent) # randomly sample on a sphere cmd.translate(f"[0,{r},0]", f"seg{i}") cmd.rotate("x", f"{t}", f"seg{i}") cmd.rotate("z", f"{p}", f"seg{i}") s = f"micelle_{detergent}_{(int)(r)}_{(int)(numberOfDetergents)}" cmd.create(f"{s}", "seg*") cmd.delete("seg*") #center(f"{s}") #cmd.show_as("sticks","org") # could be streched if necessary # affineStretch(s, 10) return s
def builderNanodisc(protein, membrane, scaffold, prefixName, runNumber, x=0, y=0, refine=False): """ builds a MP-nanodisc systems scaffold in this case is a double belt of MSP """ # Checking time of builder function execution if protein != None: print('protein is: ' + protein) print('scaffold is: ' + scaffold) print('membrane is: ' + membrane) empty = False if protein is None: empty = True if not empty: tmp_prot = "tmp_prot" + str(runNumber) cmd.copy(tmp_prot, protein) # store initial cmd.translate("[{},{},0]".format(x, y), tmp_prot) print("State of empty/not-empty: {}".format(empty)) # copies to delete later tmp_scaffold = "tmp_scaffold" + str(runNumber) tmp_memb = "tmp_memb" + str(runNumber) tmp_origin = "origin" + str(runNumber) cmd.copy(tmp_scaffold, scaffold) # store initial cmd.copy(tmp_memb, membrane) # store initial center(tmp_memb) center(tmp_scaffold) cmd.pseudoatom(tmp_origin, pos=[0, 0, 0]) cmd.origin(tmp_origin) #outRadius = findAverDist(tmp_scaffold) #doubles time for each run outRadius = TMdistCheck(tmp_scaffold, 0.2) print("Max distance from origin to scaffold in xy plane: {}".format(outRadius)) # remove lipids beyond border encased by MSP cmd.remove("br. org and {} beyond {} of {}".format(tmp_memb, outRadius, tmp_origin)) # remove lipids clashing with tmp_protein core if not empty: avXY = TMdistCheck(tmp_prot, 0.2) if avXY == -1: return "bad model" minXY = avXY / 2.0 # remove lipids inside pore cmd.remove("br. org and {} within {} of {}".format(tmp_memb, minXY, tmp_origin)) print("Mean distance if TM cross-section in xy plane: {}".format(avXY)) if empty: cmd.remove("br. org and {} within 0.4 of {} and not hydro".format(tmp_memb, tmp_scaffold)) s = "empty_{}_{}".format(membrane, scaffold) else: cmd.remove("br. org and {} within 0.3 of pol. and not hydro".format(tmp_memb)) s = "{}_{}_{}".format(protein, membrane, scaffold) if refine: s += "{}_{}".format(int(x), int(y)) if prefixName: s = "{}{}".format(prefixName, s) cmd.create(s, "({},{}, {})".format(protein, tmp_scaffold, tmp_memb)) cmd.save(s + ".pdb", s) cmd.delete(tmp_memb) cmd.delete(tmp_scaffold) cmd.delete(tmp_prot) cmd.delete(tmp_origin) return s
def load(): cmd.set("valence") r = 0 list = glob("pdb/*/*") (x,y,z)=(0,0,0) start = time.time() count = 1 scale = 100.0 for file in list: cmd.load(file,str(count),quiet=1) cmd.translate([x*scale,y*scale,z*scale],object=str(count)) # cmd.disable(str(count)) atoms = cmd.count_atoms() passed = time.time()-start print "%3d structures/%5.1f sec = %8.1f atom/sec over %6d atoms"%(count,passed,atoms/passed,atoms) count = count + 1 if count>100: break x = x + 1 if x>7: x = 0 y = y + 1 if y>7: y = 0 z = z + 1 if z>9: y = 0 z = z + 1 cmd.zoom() cmd.set("sphere_mode",1) cmd.as("spheres") cmd.rebuild() cmd.set("hash_max",250)
def scaleCoords(amount=1.0,sel='all'): m = cmd.get_model(sel) for a in m.atom: if a.index == 80: delta = [float(k)*(amount-1) for k in a.coord] print amount, a.coord, delta cmd.translate( [ delta[0], delta[1], delta[2] ] , "index "+`a.index`)
def DisplayLigand(self): try: cmd.set("auto_zoom", 0) cmd.load(self.RefLigand, self.LigDisplay, state=self.State) cmd.refresh() # Display the atoms spheres cmd.show('spheres', self.LigDisplay) cmd.refresh() cmd.alter(self.LigDisplay,'vdw=0.25') cmd.rebuild(self.LigDisplay) cmd.refresh() util.cbag(self.LigDisplay) cmd.refresh() cmd.translate(self.Translation,self.LigDisplay) cmd.refresh() cmd.zoom(self.LigDisplay) cmd.refresh() except: self.ErrorCode = 1 cmd.set("auto_zoom", self.auto_zoom) return self.ErrorCode
def center_coords(file_name): pymol.finish_launching() cmd.delete('all') cmd.load(file_name) xyz_limits = cmd.get_extent() xyz_mean = [(xyz_limits[0][i] + xyz_limits[1][i]) / 2 for i in range(3)] cmd.translate([-1 * xyz_mean[i] for i in range(3)], 'all') cmd.save(file_name, 'all')
def curveBilayer(radius=15.0, shift=1.0): """ Raise/lower height of central bilayer lipids to create a curved bilayer surface """ shiftTop = shift # shift in + Z shiftBot = -1.0 * float(shift) # shift in -Z cmd.translate([0.0, 0.0, shiftTop], "br. segi 'mema' within %s of origin0" % radius) # Adjust height of bilayer cmd.translate([0.0, 0.0, shiftBot], "br. segi 'memb' within %s of origin0" % radius) # Adjust height of bilayer print("Adjusted vertical position of central lipids by %s A" % shift)
def rpcTranslate(vect, objName='all', state=-1): """ translates objects Arguments: - vect: a sequence with x y and z translations - objName: (OPTIONAL) object to be translated - state: (OPTIONAL) if zero only visible states are translated, if -1 (the default), all states are translated """ cmd.translate(vect, objNAme, state=state) return 1
def align_helix_axis(sele='all', state=1): print('align_helix_axis', f'({sele}) and name CA') axis, cen = helix_axis(sele, state) print('axis', axis) print('cen ', cen) # showline(axis * 1000, cen) cmd.rotate(list((axis[:3] + [0, 0, 1]) / 2), 180, selection=sele) cmd.translate(list(-calc_com(f'{sele} and name CA'))) axis, cen = helix_axis(sele, state) cen[2] = 0 cmd.translate(list(-cen))
def testSaveState(self, format, pymol_version): if pymol_version > testing.PYMOL_VERSION[1]: self.skipTest("version %f" % (pymol_version)) # for rms_cur (not all formats save all identifiers) m = -1 cmd.set('retain_order') # create a multistate object cmd.fragment('ala', 'm1') cmd.create('m1', 'm1', 1, 2) cmd.create('m1', 'm1', 1, 3) cmd.translate([5, 0, 0], 'm1', state=2) cmd.translate([0, 5, 0], 'm1', state=3) n_states = cmd.count_states('m1') with testing.mktemp('.' + format) as filename: if format == 'mae' and not pymol.invocation.options.incentive_product: format = 'cms' # explicit for state in range(1, n_states + 1): cmd.delete('m2') cmd.save(filename, 'm1', state=state) cmd.load(filename, 'm2', format=format) rms = cmd.rms_cur('m1', 'm2', state, 1, matchmaker=m) self.assertAlmostEqual(rms, 0.00, delta=1e-2) # current state for state in range(1, n_states + 1): cmd.frame(state) cmd.delete('m2') cmd.save(filename, 'm1') cmd.load(filename, 'm2', 1, format=format) rms = cmd.rms_cur('m1', 'm2', state, 1, matchmaker=m) self.assertAlmostEqual(rms, 0.00, delta=1e-2) if format in ('mol', 'cms'): # no multi support return # all states cmd.delete('m2') cmd.save(filename, 'm1', state=0) cmd.load(filename, 'm2', 1, discrete=1, multiplex=0) self.assertEqual(cmd.count_states('m2'), n_states) for state in range(1, n_states + 1): rms = cmd.rms_cur('m1', 'm2 and state %d' % state, state, state, matchmaker=m) self.assertAlmostEqual(rms, 0.00, delta=1e-2)
def undock(chains, type): for chainOrName in chains: selection_string = f'chain {chainOrName}' if type is 'cif' else chainOrName translation_vector = [ random.randrange(MIN_UNDOCK_DISTANCE, MAX_UNDOCK_DISTANCE), random.randrange(MIN_UNDOCK_DISTANCE, MAX_UNDOCK_DISTANCE), random.randrange(MIN_UNDOCK_DISTANCE, MAX_UNDOCK_DISTANCE) ] cmd.translate(translation_vector, selection_string) cmd.rotate('x', random.randrange(-360, 360), selection_string) cmd.rotate('y', random.randrange(-360, 360), selection_string) cmd.rotate('z', random.randrange(-360, 360), selection_string)
def builderNanodisc(protein, membrane, scaffold, prefixName, offset=0, refine=False): """ builds a MP-nanodisc systems scaffold in this case is a double belt of MSP """ # Checking time of builder function execution print(f'protein is: {protein}') print(f'scaffold is: {scaffold}') print(f'membrane is: {membrane}') empty = False if protein == None: empty = True # copies to delete later cmd.copy("tmp_scaffold", scaffold) # store initial cmd.copy("tmp_memb", membrane) # store initial cmd.copy("tmp_prot", protein) # store initial center("tmp_memb") center("tmp_scaffold") cmd.pseudoatom("origin0", pos=[0, 0, 0]) cmd.origin("origin0") outRadius = findAverDist("tmp_scaffold") cmd.translate(f"[0,0,{offset}]", f"tmp_scaffold") print(f"Max distance from origin to scaffold in xy plane: {outRadius}") # remove lipids beyond border encased by MSP cmd.remove(f"org and tmp_memb beyond {outRadius} of origin0") print(f"State of empty/not-empty: {empty}") # remove lipids clashing with tmp_protein core if not empty: avXY = TMdistCheck("tmp_prot", 0.2) minXY = avXY / 2.0 # remove lipids inside pore cmd.remove(f"org and tmp_memb within {minXY} of origin0") print(f"Mean distance if TM cross-section in xy plane: {avXY}") if empty: cmd.remove("org and tmp_memb within 0.4 of tmp_scaffold and not hydro") s = f"{prefixName}empty_{membrane}_{scaffold}" else: cmd.remove("org and tmp_memb within 0.3 of pol. and not hydro") s = f"{prefixName}{protein}_{membrane}_{scaffold}" if refine: s += str(int(offset)) cmd.create(s, f"({protein},tmp_scaffold, tmp_memb)") cmd.save(s + ".pdb", s) cmd.delete("tmp_memb") cmd.delete("tmp_scaffold") cmd.delete("tmp_prot") cmd.delete("origin0") return s
def test_protect(self): cmd.pseudoatom('m1', pos=[0.,0.,0.]) cmd.pseudoatom('m1', pos=[1.,0.,0.]) cmd.protect('m1`1') cmd.translate([0.,1.,0.]) self.assertEqual([0.,0.,0.], cmd.get_atom_coords('m1`1')) self.assertEqual([1.,1.,0.], cmd.get_atom_coords('m1`2')) cmd.deprotect() cmd.translate([0.,0.,1.]) self.assertEqual([0.,0.,1.], cmd.get_atom_coords('m1`1')) self.assertEqual([1.,1.,1.], cmd.get_atom_coords('m1`2'))
def align_ligand(selection, center, angles): pos_halligand = get_pos(center) translation_vector = pos_halligand cmd.rotate("x", -angles[3], selection, 0, 0, origin=[0, 0, 0]) cmd.rotate("y", -angles[2], selection, 0, 0, origin=[0, 0, 0]) cmd.rotate("x", -angles[1], selection, 0, 0, origin=[0, 0, 0]) cmd.rotate("z", -angles[0], selection, 0, 0, origin=[0, 0, 0]) cmd.translate([ translation_vector[0][0], translation_vector[0][1], translation_vector[0][2] ], selection, -1, 0)
def test_protect(self): cmd.pseudoatom('m1', pos=[0., 0., 0.]) cmd.pseudoatom('m1', pos=[1., 0., 0.]) cmd.protect('m1`1') cmd.translate([0., 1., 0.]) self.assertEqual([0., 0., 0.], cmd.get_atom_coords('m1`1')) self.assertEqual([1., 1., 0.], cmd.get_atom_coords('m1`2')) cmd.deprotect() cmd.translate([0., 0., 1.]) self.assertEqual([0., 0., 1.], cmd.get_atom_coords('m1`1')) self.assertEqual([1., 1., 1.], cmd.get_atom_coords('m1`2'))
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 testSaveANISO(self): cmd.read_pdbstr(v_pdbstr_anisou, 'm1') v = cmd.get_pdbstr() self.assertEqual(v, v_pdbstr_anisou, 'ANISOU records missing:\n' + v) cmd.rotate('y', 30, object='m1') cmd.translate([20, 0, 0], object='m1') cmd.rotate('z', 20, object='m1') v = cmd.get_pdbstr() self.assertEqual(v, v_pdbstr_rotated, 'ANISOU not rotated in PDB string' + v) v = cmd.get_model('m1').atom[0].u_aniso self.assertArrayEqual(v, [0.183853, 0.378995, 0.309052, -0.103350, 0.125751, 0.050349], 1e-5, 'ANISOU not rotated in chempy model')
def builderMembrane(lipid, runNumber): """ build membrane bilayer from single lipid PDB file """ refresh() cmd.load(lipid + ".pdb", "start_lipid") cmd.alter("start_lipid", "chain = 'X'") cmd.alter("start_lipid", "segi = 'mema'") # cmd.rotate('x', 90, "start_lipid") dmax = findMaxDist("start_lipid") # create lipid copies and translate them to new position nlip = 20 # number of lipids forming edge of bilayer s0 = range(1, nlip, 1) s1 = range(1, nlip + 1, 1) # excludes first lipid step_x = 0 # translation in x (TODO: automatic determination of spacing without clashes) step_y = 7 step_z = 0 step_x2 = 7 step_y2 = 0 step_z2 = 0 for i in s1: # first column cmd.copy("lip{}".format(i), "start_lipid") # row of lipids cmd.alter("lip{}".format(i), "resi={}".format(i)) # change residue numbers y = i * step_y cmd.translate("[{},{},{}]".format(step_x, y, step_z), "lip{}".format(i)) # generate remaining rows/columns in same leaflet for j in s0: k = int(nlip) * i + j # TODO: general counter to write correct lipid number cmd.copy("lip{}".format(k), "lip{}".format(i)) # adjacent row of lipids cmd.alter("lip{}".format(k), "resi={}".format(k)) # change residue numbers x2 = j * step_x2 cmd.translate("[{},{},{}]".format(x2, step_y2, step_z2), "lip{}".format(k)) cmd.sort() # sort atom order # create second leaflet # simple method by creating a single leaflet object: cmd.create("mema", "(lip*)") cmd.delete("lip*") cmd.copy("memb", "mema") cmd.alter("memb", "segi = 'memb'") cmd.rotate("x", 180, "memb") cmd.translate("[0,0,{}]".format((-1.0 * (dmax + 0.5))), "memb") # cmd.color("yellow", "segi = 'mema'") # cmd.color("blue", "segi = 'memb'") cmd.translate("[3.5,3.5,0]", "memb") # optional shift of single leaflet to avoid aliphatic clashes s = "{}_bilayer".format(lipid) cmd.create(s, "(mema,memb)") cmd.delete("mema ,memb, start_lipid") center(s) cmd.save(s + ".pdb", s) cmd.reset() return s
def explode_helix(sele='all', scale=3, state=1, **kw): print('explode_helix: aligning to 0,0,0 / 0,0,1') align_helix_axis('original', state=state) unit_selections = list(helix_units(sele, state)) primary_nbr, other_nbr = sort_and_calc_neighbors(unit_selections, **kw) coms = [] for i, unit in enumerate(unit_selections): cmd.translate(list(unit.com * (scale - 1.0)), selection=unit.sele) coms.append(unit.com * scale) if other_nbr is not None: for i, j in primary_nbr.items(): show_interaction(coms[i], coms[j], primary=True, scale=scale) for i, j in other_nbr.items(): show_interaction(coms[i], coms[j], primary=False, scale=scale) else: for i, j in primary_nbr: show_interaction(coms[i], coms[j], primary=False, scale=scale)
def builderCorona(theta, fi, detergent, r, detR): # Build symmates with desired rotations thetaSteps = len(theta) angleVer = np.linspace(-90, 90, thetaSteps) i = 0 for t, a in zip(theta, angleVer): for f in fi: i += 1 cmd.copy(f"seg{i}", detergent) # corona cmd.rotate("x", f"{a}", f"seg{i}") cmd.translate(f"[0,{r + 0.5*detR*np.cos(np.deg2rad(a))},0]", f"seg{i}") cmd.translate(f"[0,0,{(r+detR)*np.sin(np.deg2rad(t))}]", f"seg{i}") cmd.rotate("z", f"{f}", f"seg{i}") cmd.create("corona", "seg*") cmd.delete("seg*")
def undock(chainsOrNames, type): print('undocking', chainsOrNames, 'type', type) for chainOrName in chainsOrNames: if type == 'cif': selection_string = f'chain {chainOrName}' else: selection_string = chainOrName translation_vector = [ random.randrange(MIN_UNDOCK_DISTANCE, MAX_UNDOCK_DISTANCE), random.randrange(MIN_UNDOCK_DISTANCE, MAX_UNDOCK_DISTANCE), random.randrange(MIN_UNDOCK_DISTANCE, MAX_UNDOCK_DISTANCE) ] print('translate', selection_string, translation_vector) cmd.translate(translation_vector, selection_string) cmd.rotate('x', random.randrange(-360, 360), selection_string) cmd.rotate('y', random.randrange(-360, 360), selection_string) cmd.rotate('z', random.randrange(-360, 360), selection_string)
def simulationCycle(objList,prob,scale,a,b,UC_spacing): objList = isLock(objList,a,b,UC_spacing) objList = isBound(objList,prob,a,b,UC_spacing) objList = setTrajectory(objList,a,b,UC_spacing) if np.ceil(np.random.rand(1)-0.7) else objList objList = setOrientation(objList) for n,objComp in enumerate(objList): #if objComp.locked==False: # cmd.color('yellow',objComp.objName) if objComp.bound==False: if objComp.compType=="A": cmd.color('colorCompAr',objComp.objName) if objComp.compType=="B": cmd.color('colorCompBr',objComp.objName) objComp.loc = objComp.loc+objComp.trajectory*scale cmd.translate(list(objComp.trajectory*scale), selection = objComp.objName,camera = 0) return objList
def DisplayLigand(self): try: cmd.load(self.pdbPath, self.LigDisplay, state=self.State) # Display the atoms spheres cmd.show('spheres', self.LigDisplay) cmd.alter(self.LigDisplay,'vdw=0.25') cmd.rebuild(self.LigDisplay) util.cbag(self.LigDisplay) cmd.translate(self.Translation,self.LigDisplay) cmd.zoom(self.LigDisplay) except: return 1 return 0
def builderMicelle(detergent, r, numberOfDetergents): refresh() i = 0 numberOfDetergents = int(numberOfDetergents) # FIXME: if number of detergents > 360, molecules may clash in space points = fibonacci_sphere(numberOfDetergents) print("Rotating detergent molecule for build protocol...") for x,y,z in points: i += 1 t = np.degrees(np.arccos(z)) p = np.degrees(np.arctan(y/x)) cmd.copy("seg{}".format(i), detergent) cmd.alter("seg{}".format(i), "resi={}".format(i)) # assign residue numbers # put to to knot of fibonacci grid center("seg{}".format(i)) cmd.translate("[0,{},0]".format(r), "seg{}".format(i)) if x < 0: cmd.rotate("z", 180, "seg{}".format(i)) cmd.rotate("z", str(t), "seg{}".format(i)) cmd.rotate("y", str(p), "seg{}".format(i)) #cmd.translate("[{},{},{}]".format(r * x, r * y, r * z), "seg{}".format(i)) # if numberOfDetergents > 360: # x1 = range(-180, 180) # x2 = range(0, 360) # theta = ([random.choice(x1) for _ in range(numberOfDetergents)]) # phi = ([random.choice(x2) for _ in range(numberOfDetergents)]) # else: # theta = random.sample(range(-180, 180), numberOfDetergents) # phi = random.sample(range(0, 360), numberOfDetergents) # for t, p in zip(theta, phi): # i += 1 # cmd.copy("seg{}".format(i), detergent) # cmd.alter("seg{}".format(i), "resi={}".format(i)) # assign residue numbers # # randomly sample on a sphere # cmd.translate("[0,{},0]".format(r), "seg{}".format(i)) # cmd.rotate("x", str(t), "seg{}".format(i)) # cmd.rotate("z", str(p), "seg{}".format(i)) s = "micelle_{}_{}_{}".format(detergent, int(r), int(numberOfDetergents)) cmd.create(s, "seg*") cmd.delete("seg*") # center(f"{s}") # cmd.show_as("sticks","org") # could be streched if necessary # affineStretch(s, 10) return s
def DisplayLigand(self): try: cmd.set("auto_zoom", 0) cmd.load(self.LigandPath, self.LigDisplay, state=self.State) cmd.refresh() cmd.translate(self.Translation, self.LigDisplay) cmd.refresh() cmd.zoom(self.LigDisplay) cmd.refresh() except: self.ErrorCode = 1 cmd.set("auto_zoom", self.auto_zoom) return self.ErrorCode
def DisplayLigand(self): try: cmd.set("auto_zoom", 0) cmd.load(self.LigandPath, self.LigDisplay, state=self.State) cmd.refresh() cmd.translate(self.Translation,self.LigDisplay) cmd.refresh() cmd.zoom(self.LigDisplay) cmd.refresh() except: self.ErrorCode = 1 cmd.set("auto_zoom", self.auto_zoom) return self.ErrorCode
def moveInPymol(self, solutionPymolString, chromosome, state): # recreate protein B at solution coordinates cmd.create(solutionPymolString, self.pymolString, 1, state) # translate to origin with proteinBcog. IMPORTANT: set camera to "0" so that the translation is not done along the camera coordinate system! cmd.translate(list(-1 * self.labelAtomsCog.reshape(-1, )), solutionPymolString, state, 0, None) # rotate and translate according to solution translation = chromosome.genes[3:6] rotX = chromosome.genes[0] # IMPORTANT: set camera to "0" so that the translation is not done along the camera coordinate system! Also set rotation origin to 0,0,0! cmd.rotate([1, 0, 0], rotX, solutionPymolString, state, 0, None, [0, 0, 0]) rotY = chromosome.genes[1] cmd.rotate([0, 1, 0], rotY, solutionPymolString, state, 0, None, [0, 0, 0]) rotZ = chromosome.genes[2] cmd.rotate([0, 0, 1], rotZ, solutionPymolString, state, 0, None, [0, 0, 0]) cmd.translate(list(translation.reshape(-1, )), solutionPymolString, state, 0, None) if chromosome.symmetry != "None": if chromosome.symmetry == "C2": monomers = 2 elif chromosome.symmetry == "C3": monomers = 3 elif chromosome.symmetry == "C4": monomers = 4 elif chromosome.symmetry == "C5": monomers = 5 elif chromosome.symmetry == "C6": monomers = 6 elif chromosome.symmetry == "C7": monomers = 7 elif chromosome.symmetry == "C8": monomers = 8 angle = 360.0 / monomers for i in range(1, monomers): cmd.create(solutionPymolString, solutionPymolString, 1, state + i) cmd.rotate([1, 0, 0], i * angle, solutionPymolString, state + i, 0, None, [0, 0, 0])
def show_result(tmpdir, ligname): n = 10 # number of positions of ligand ft_file = tmpdir + "/ft.000.0.0" rm_file = tmpdir + "/rm.000.0.0" ft_data = np.loadtxt(ft_file) rm_data = np.loadtxt(rm_file) for i in range(n): num_state = i + 1 name_copy = "copy_ligand_" + str(i) cmd.copy(name_copy, ligname) tv = ft_data[i, 1:4] rm = rm_data[i].reshape((3, 3)) en = ft_data[i, 4] cmd.translate(list(tv), name_copy) cmd.rotate(list(get_axis(rm)), get_angle(rm), name_copy) cmd.create("result", name_copy, 0, num_state) cmd.delete(name_copy) result = tmpdir + "/result_dock.pdb" cmd.save(result, "result") cmd.mplay()
def drowSaveN_ASUs(N,Type="Hexagonal",shape='round',ratio=1,UCp0=[0,0,0],UCa=310,UCb=100,UCaAng=0,UCbAng=60,name="ASU"): # note the 5 lines below are design specific and surpass the default input UCa, UCb, UCaAng, and UCbAng (which can than becaluculated from a,b, and UC-spacing) a = np.array((1,0)) # primitive vector "a" b = np.array((np.cos(60*np.pi/180),np.sin(60*np.pi/180))) # primitive vector "b" for p6 c0 = np.array((0.5,0.5*np.tan(30*np.pi/180))) # vector pointing from the UC corner to the oen of the C3 centers in a p6 symmetry c1 = 2*c0 # second C3 center in a p6 (also rotated by 180 around Z axis) b0 = a/2 # 90 rotation b1 = b/2 # 150 rotation b2 = (a+b)/2 # 30 rotation UC_spacing = int(537*2*np.cos(30*np.pi/180)/3) ########################## #name="ASU" # for selection purposes coefArray = genA_RotCentersInd(N,a,b,c0,shape='round') # indices of the UC for each ASU, the third element is the Z orientation (if 1 rotation of 180 degrees is applied) latticePos = genA_RotCentersPos(coefArray,a,b,c0)*UC_spacing # this is the set of ASUs CM position if ratio!=1: creatDilutedObj(name,ratio,name="ASUbase") name = "ASUbase" LofL = [] # Objects list for n,k in enumerate(range(N)): print("ASU location: ",latticePos[k]) objNew = createAndTranlateObj(name,count=k,name=name) # create a new object and return name of object print("objNew: ",objNew) cmd.color("blue", objNew+" and chain A+C+E+G+I+K") cmd.show( representation="dots", selection=objNew ) cmd.translate(list(latticePos[k]), selection = objNew,camera = 0) if coefArray[k,2]==1: cmd.rotate([0,0,1],180,selection=objNew ,camera=0,origin=latticePos[k]) LofL.append(objNew) #LofL.append([s]+LofL[n-1]) if n>0 else LofL.append([s]) # create list of list, each list contain print("Arrays object name: ", LofL) ### dumping list of selections (each dump will have an additional ASU ) A = [] # Aname = []
def render(self, modelConfiguration, pdb_fname, modelName, color_str="green"): """Renders a pdb with given configuration in PyMOL. modelConfiguration is of type (x,y,z,a,b,g); model_fname is of type string and represents the model PDB file.""" x = 10*float(modelConfiguration[0]) ## scale "up" by a factor of 10 y = 10*float(modelConfiguration[1]) ## because modelConfiguration's x,y,z have units of nm z = 10*float(modelConfiguration[2]) ## but PyMOL uses coordinates of Angstroms translationVector = "[{},{},{}]".format(x,y,z) xDegOfRot = 360*float(modelConfiguration[3]) ## alpha, is in units of a fraction of 360 degrees yDegOfRot = 360*float(modelConfiguration[4]) zDegOfRot = 360*float(modelConfiguration[5]) #cmd.load(pdb_fname, "original_{}".format(modelName)) ## for debug, something to compare against cmd.load(pdb_fname, modelName) cmd.rotate('x', xDegOfRot, modelName, 0, 0) ## rotate about x-axis cmd.rotate('y', yDegOfRot, modelName, 0, 0) ## rotate about y-axis cmd.rotate('z', zDegOfRot, modelName, 0, 0) ## rotate about z-axis ## note: apply rotations before translation, because it rotates about the origin cmd.translate(translationVector, modelName, 0, 0) ## all states, and _not_ camera coordinates cmd.color(color_str, modelName)
def setUpAssembly(N,UCtype="hexagon32",colors=["colorCompA","colorCompB"]): if UCtype=="hexagon32": # unit cell promitive vectors and geometical parameters a = np.reshape(np.array((1,0,0)),(3,1)) # primitive vector "a" b = np.reshape(np.array((np.cos(60*np.pi/180),np.sin(60*np.pi/180),0)),(3,1)) # primitive vector "b" for p6 c0 = np.reshape(np.array((0.5,0.5*np.tan(30*np.pi/180),0)),(3,1)) # vector pointing from the UC corner to the oen of the C3 centers in a p6 symmetry c1 = 2*c0 # second C3 center in a p6 (also rotated by 180 around Z axis) b0 = a/2 # 90 rotation b1 = b/2 # 150 rotation b2 = (a+b)/2 # 30 rotation UC_spacing = int(537*2*np.cos(30*np.pi/180)/3) ### generate lattice parameters array for the A component (C3) coefArray = genA_RotCentersInd(N,a,b,c0,UC_spacing,shape='round') # note that coefArray[:,:,x] also determine the rotation of the ASU Adata = genA_RotCentersPos(coefArray,a,b,c0,UC_spacing)[1] # this was use to generate the lattice fro ma single ASU object ### generate lattice parameters array for the B component (C2) coefArrayB = genB_RotCentersInd(coefArray) Bdata = genB_RotCentersPos(coefArrayB,a,b) # here distances are still normalized (need to multiply with UC_spacing) Bdata[:,:2] = Bdata[:,:2]*UC_spacing #### databases to a list of objects objListA = [eval("compPymolObj")("A"+str(n[0]).zfill(4),"A"+str(n[0]).zfill(4),"A",3,n[1][:3],n[1][4]) for n in enumerate(Adata)] objListB = [eval("compPymolObj")("B"+str(n[0]).zfill(4),"B"+str(n[0]).zfill(4),"B",2,n[1][:3],n[1][4]) for n in enumerate(Bdata)] objListAll = objListA+objListB cmd.hide(representation="everything", selection="Acomp") cmd.hide(representation="everything", selection="Bcomp") ### initiation - generating and positioning all the objects for objComp in objListAll: # objListAll: list of objects of class compPymolObj instances to allow visualization #print("ASU location: ",latticePos[k]) createNewObj(objComp) # create a new pymol object namde (objComp.objName) from template named objComp.compType #cmd.color("blue", objNew+" and chain A+C+E+G+I+K") #cmd.show( representation="dots", selection=objNew ) cmd.translate(list(objComp.loc), selection = objComp.objName,camera = 0) rotationAngleAroundZ = np.round(objComp.orientation.as_euler('xyz')[2]*180/np.pi,4) cmd.rotate([0,0,1],rotationAngleAroundZ,selection=objComp.objName ,camera=0,origin=list(objComp.loc)) cmd.color('colorCompA',objComp.objName) if objComp.compType=="A" else cmd.color('colorCompB',objComp.objName) return objListAll
def reps(self,cleanup=0): rep_list = [ "lines","sticks","spheres","surface","mesh","dots","ribbon","cartoon" ] try: if not cleanup: cmd.disable() cmd.set("suspend_updates",1,quiet=1) cmd.load("$PYMOL_DATA/demo/pept.pdb","rep1") cmd.alter("rep1///1-5+8-13/","ss='S'") cmd.cartoon("auto") cmd.hide("everything","rep1") for a in range(2,9): cmd.create("rep%d"%a,"rep1") for x, y in enumerate(rep_list, 1): cmd.show(x, "rep%d" % y) cmd.reset() cmd.zoom("rep1",24) util.cbay("rep2") util.cbac("rep3") util.cbas("rep4") util.cbab("rep5") util.cbaw("rep6") util.cbay("rep8") cmd.set("suspend_updates",0,quiet=1) scale=0.5 for b in range(1,20): cmd.set("suspend_updates",0,quiet=1) cmd.refresh() cmd.set("suspend_updates",1,quiet=1) xt=-3.2 yt=1.6 for a in range(1,5): cmd.translate([xt*scale,yt*scale,0],object="rep%d"%a,camera=0) xt=xt+2 yt=-yt xt=-3.2 for a in range(5,9): cmd.translate([xt*scale,yt*scale,0],object="rep%d"%a,camera=0) xt=xt+2 for a in range(1,9): cmd.origin("rep%d"%a,object="rep%d"%a) cmd.mset("1") st = ' '.join(map(lambda x,y:"rotate angle=-3,object=rep%d,axis=%s;"%(x,y),list(range(1,9)), ['x','y','x','y','x','y','x','y'])) cmd.mdo(1,st) cmd.set("suspend_updates",0,quiet=1) cmd.mplay() cgo = [] axes = [[4.5,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]] c = 1 for a in rep_list: ext = cmd.get_extent("rep%d"%c) pos = [(ext[0][0]+ext[1][0])/2, (ext[0][1]+ext[1][1])/2+14, (ext[0][2]+ext[1][2])/2] c = c + 1 pos[0]=pos[0]-(measure_text(plain,a,axes)/2) wire_text(cgo,plain,pos,a,axes) cmd.set("cgo_line_width",1.5) cmd.set("auto_zoom",0) cmd.load_cgo(cgo,'reps') cmd.set("auto_zoom",1) else: cmd.delete("rep*") cmd.mset() cmd.mstop() except: traceback.print_exc()
def cgo_grid( pos1=[0,0,0], pos2=[1,0,0], pos3=[0,0,1], length_x=30, length_z='', npoints_x='', npoints_z='', nwaves_x=2, nwaves_z='', offset_x=0, offset_z='', gain_x=1, gain_z='', thickness=2.0, color='', nstates=60, startframe=1, endframe=1, mode=0, view=0, name='', quiet=1): ''' DESCRIPTION Generates an animated flowing mesh object using the points provided or the current view. The shape is affected substantially by the arguments! USEAGE cgo_grid [ pos1 [, pos2 [, pos3 [, length_x [, length_z [, npoints_x [, npoints_z [, nwaves_x [, nwaves_z [, offset_x [, offset_z [, gain_x [, gain_z [, thickness [, color [, nstates [, startframe [, endframe [, mode [, view [, name [, quiet ]]]]]]]]]]]]]]]]]]]]]] EXAMPLE cgo_grid view=1 ARGUMENTS pos1 = single atom selection (='pk1') or list of 3 floats {default: [0,0,0]} pos2 = single atom selection (='pk2') or list of 3 floats {default: [1,0,0]} pos3 = single atom selection (='pk3') or list of 3 floats {default: [0,0,1]} --> the plane is defined by pos1 (origin) and vectors to pos2 and pos3, respectively length_x = <float>: length of membrane {default: 30} length_z = <float>: length of membrane {default: ''} # same as length_x npoints_x = <int>: number of points(lines) along x-direction {default: ''} #will be set to give a ~1 unit grid npoints_z = <int>: number of points(lines) along z-direction {default: ''} #will be set to give a ~1 unit grid {minimum: 1 # automatic} nwaves_x = <float>: number of complete sin waves along object x-axis {default: 2} nwaves_z = <float>: number of complete sin waves along object z-axis {default: ''} # same as nwaves_x define separately to adjust number of waves in each direction offset_x = <float> phase delay (in degrees) of sin wave in x-axis can be set to affect shape and starting amplitude {default: 0} offset_z = <float> phase delay (in degrees) of sin wave in z-axis can be set to affect shape and starting amplitude {default: ''} # same as offset_x offset_x and offset_z can be used together to phase otherwise identical objects gain_x = <float>: multiplication factor for y-amplitude for x-direction {default: 1} gain_z = <float>: multiplication factor for y-amplitude for z-direction {default: ''} #=gain_x thickness = <float>: line thickness {default: 2} color = color name <string> (e.g. 'skyblue') OR rgb-value list of 3 floats (e.g. [1.0,1.0,1.0]) OR {default: ''} // opposite of background input illegal values for random coloring nstates = <int>: number of states; {default: 60} this setting will define how many states the object will have (per wave) and how fluent and fast the animation will be. Higher values will promote 'fluent' transitions, but decrease flow speed. Note: Frame animation cycles thought the states one at a time and needs to be set accordingly. Can also be used to phase otherwise identical objects. Set to 1 for static object {automatic minimum} startframe: specify starting frame <int> or set (='') to use current frame set to 'append' to extend movie from the last frame {default: 1} endframe: specify end frame <int> or set (='') to use last frame if 'append' is used for startframe, endframe becomes the number of frames to be appended instead {default: 1} Note: if start- and endframe are the same, movie animation will be skipped, the object will be loaded and can be used afterwards mode: defines positioning {default: 0}: 0: pos1 is center 1: pos1 is corner view {default: 0}: '0': off/ uses provided points to create CGO '1': overrides atom selections and uses current orienatation for positioning - pos1 = origin/center - pos2 = origin +1 in camera y - pos3 = origin +1 in camera z name: <string> name of cgo object {default: ''} / automatic quiet: <boolean> toggles output ''' ########## BEGIN OF FUNCTION CODE ########## def get_coord(v): if not isinstance(v, str): try: return v[:3] except: return False if v.startswith('['): return cmd.safe_list_eval(v)[:3] try: if cmd.count_atoms(v)==1: # atom coordinates return cmd.get_atom_coords(v) else: # more than one atom --> use "center" # alt check! if cmd.count_atoms('(alt *) and not (alt "")')!=0: print("cgo_grid: warning! alternative coordinates found for origin, using center!") view_temp=cmd.get_view() cmd.zoom(v) v=cmd.get_position() cmd.set_view(view_temp) return v except: return False def eval_color(v): try: if not v: v=eval(cmd.get('bg_rgb')) v=list(map(sum, list(zip(v,[-1,-1,-1])))) v=list(map(abs, v)) if v[0]==v[1]==v[2]==0.5: # grey v=[0,0,0] return v if isinstance(v, list): return v[0:3] if not isinstance(v, str): return v[0:3] if v.startswith('['): return cmd.safe_list_eval(v)[0:3] return list(cmd.get_color_tuple(v)) except: return [random.random(),random.random(),random.random()] cmd.extend("eval_color", eval_color) color=eval_color(color) try: mode=int(mode) except: raise Exception("Input error in Mode") if mode<0 or mode>1: raise Exception("Mode out of range!") try: nstates=int(nstates) if nstates<1: nstates=1 print("NB! nstates set to 1 (automatic minimum)") length_x=float(length_x) if length_z=='': length_z=length_x else: length_z=float(length_z) if npoints_x=='': npoints_x=int(length_x)+1 else: npoints_x=int(npoints_x) if npoints_x<1: npoints_x=1 print("NB! npoints_x set to 1 (automatic minimum)") if npoints_z =='': npoints_z=int(length_z)+1 else: npoints_z=int(npoints_z) if npoints_z<1: npoints_z=1 print("NB! npoints_x set to 1 (automatic minimum)") nwaves_x=abs(float(nwaves_x)) if nwaves_z=='': nwaves_z=nwaves_x else: nwaves_z=abs(float(nwaves_z)) offset_x=float(offset_x)*math.pi/180 if offset_z=='': offset_z=offset_x else: offset_z=float(offset_z)*math.pi/180 thickness=float(thickness) gain_x=float(gain_x) if gain_z=='': gain_z=gain_x else: gain_z=float(gain_z) if not name: name = cmd.get_unused_name('membrane') else: name = str(name) if int(quiet): quiet=True else: quiet=False if int(view): view=True else: view=False except: raise Exception("Input error in parameters!") #prevent auto zooming on object temp_auto_zoom=cmd.get('auto_zoom') cmd.set('auto_zoom', '0') if int(view): xyz1=cmd.get_position() tempname = cmd.get_unused_name('temp') ori_ax=[[0,0,0],[10,0,0],[0,0,10]] for a in range (0,len(ori_ax)): cmd.pseudoatom(tempname, resi=''+str(a+1)+'', pos=xyz1) cmd.translate(ori_ax[a], selection=''+tempname+' and resi '+str(a+1)+'', camera='1') ori_ax[a]=cmd.get_atom_coords(''+tempname+' and resi '+str(a+1)+'') cmd.delete(tempname) xyz1=ori_ax[0] xyz2=ori_ax[1] xyz3=ori_ax[2] else: xyz1 = get_coord(pos1) xyz2 = get_coord(pos2) xyz3 = get_coord(pos3) if (not startframe): startframe=cmd.get('frame') if (not endframe): endframe=cmd.count_frames() if endframe==0: endframe=1 if (startframe=='append'): startframe=cmd.count_frames()+1 try: endframe=int(endframe) cmd.madd('1 x'+str(endframe)) endframe=cmd.count_frames() except ValueError: raise Exception("Input error: Value for 'endframe' is not integer!") try: startframe=int(startframe) endframe=int(endframe) endframe/startframe startframe/endframe except ValueError: raise Exception("Input error: Failed to convert to integer!") except ZeroDivisionError: raise Exception("Error: unexpected zero value!") except: raise Exception("Unexpected error!") if (nstates==1): if not quiet: print("Creating one state object!") if startframe > endframe: startframe, endframe = endframe, startframe if not quiet: print("Inverted start and end frames!") ########## BEGIN OF FUNCTIONAL SCRIPT ########## #normalize and get orthogonal vector # define vectors from points xyz2 = cpv.sub(xyz2, xyz1) xyz3 = cpv.sub(xyz3, xyz1) #NB! cpv.get_system2 outputs normalized vectors [x,y,z] xyz4 = cpv.get_system2(xyz2,xyz3) xyz2 = xyz4[0] xyz3 = xyz4[1] for x in range(0,3): for z in range(0,3): if x==z: continue if xyz4[x]==xyz4[z]: raise Exception("Illegal vector settings!") xyz4 = cpv.negate(xyz4[2]) #overwrites original # transform origin to corner if mode==0: if npoints_x>1: xyz1 = cpv.sub(xyz1, cpv.scale(xyz2,length_x/2)) if npoints_z>1: xyz1 = cpv.sub(xyz1, cpv.scale(xyz3,length_z/2)) #defines array lines nlines=max([npoints_x, npoints_z]) # in case only one line max # create an empty array for xyz entries # this may contain more values than are actually drawn later, # but they are needed to draw lines in each direction grid_xyz = [] for x in range(0,nlines): grid_xyz.append([0.0,0.0,0.0]*nlines) # grid distance and steps # prevent zero divisions (lines=1) and enable calculations if lines=0 if (not (npoints_x-1<2)): gap_length_x = length_x/(npoints_x-1) step_line_x = 2*math.pi/(npoints_x-1) else: gap_length_x=length_x step_line_x=2*math.pi if (not (npoints_z-1<2)): gap_length_z = length_z/(npoints_z-1) step_line_z = 2*math.pi/(npoints_z-1) else: gap_length_z=length_z step_line_z=2*math.pi # calculate steps if nstates==1: step_state=0 else: step_state = 2*math.pi/(nstates-1) ########## BEGIN STATE ITERATION ########## # create a n-state object in PyMol for a in range(0,nstates): # Reset object obj = [] #assign color obj.extend( [ COLOR, color[0], color[1], color[2] ] ) #set width obj.extend( [ LINEWIDTH, thickness ] ) # Calculate xyz-coordinates for each line for x in range(0,nlines): for z in range(0,nlines): # update grid position in x-direction xyztemp=cpv.add(xyz1,cpv.scale(xyz2,gap_length_x*x)) # update grid position in z-direction xyztemp=cpv.add(xyztemp,cpv.scale(xyz3,gap_length_z*z)) # calculate amplitude for y-direction and update grid position y_amp=(\ gain_x*math.sin(offset_x+nwaves_x*((a*step_state)+(x*step_line_x)))/2+\ gain_z*math.sin(offset_z+nwaves_z*((a*step_state)+(z*step_line_z)))/2\ ) xyztemp=cpv.add(xyztemp,cpv.scale(xyz4,y_amp)) grid_xyz[x][z]=xyztemp #Now the coordinates for this state are defined! #Now the coordinates are read separately: # allow to run the loops as often as required #if npoints_x==0:npoints_x=npoints_z #lines along z in x direction for z in range(0,npoints_z): obj.extend( [ BEGIN, LINE_STRIP ] ) for x in range(0,npoints_x): obj.extend( [ VERTEX, grid_xyz[x][z][0], grid_xyz[x][z][1], grid_xyz[x][z][2] ] ) obj.append( END ) #lines along x in z direction for x in range(0,npoints_x): obj.extend( [ BEGIN, LINE_STRIP ] ) for z in range(0,npoints_z): obj.extend( [ VERTEX, grid_xyz[x][z][0], grid_xyz[x][z][1], grid_xyz[x][z][2] ] ) obj.append( END ) # Load state into PyMOL object: cmd.load_cgo(obj,name,a+1) # All states of object loaded! #reset auto zooming to previous value cmd.set('auto_zoom', temp_auto_zoom) # animate object using frames instead of states if (not endframe==startframe): framecount=0 countvar=1 for frame in range(startframe, endframe + 1): #increase count framecount=framecount+countvar # set state in frame cmd.mappend(frame, "/cmd.set('state', %s, %s)" % (repr(framecount), repr(name))) # Looping if framecount==nstates: if ((int(nwaves_x)!=nwaves_x) or (int(nwaves_z)!=nwaves_z)): #if not complete sinus wave #--> reverse wave in ongoing animation countvar=-1 else: #wave is complete --> repeat framecount=0 # count up from first state if framecount==1: countvar=1 if not quiet: print("object loaded and animated with frames!") else: if not quiet: print("object loaded!") #OUTPUT if not quiet: print("Grid variables for:",name) print("corner:", xyz1) print("vector 1:", xyz2) print("vector 2:", xyz3) print("length_x:",length_x) print("length_z:",length_z) print("npoints_x:", npoints_x) print("npoints_z:", npoints_z) print("nwaves_x:", nwaves_x) print("nwaves_z:", nwaves_z) print("offset_x:",offset_x) print("offset_z:",offset_z) print("gain_x:",gain_x) print("gain_z:",gain_z) print("thickness:",thickness) print("states", nstates) if (not endframe==startframe): print("frames: start:",startframe,"end:",endframe) return grid_xyz
def trans(sel, v): x, y, z = v.x, v.y, v.z cmd.translate([x, y, z], sel, 0, 0)
def cyspka(molecule, chain, residue, SeeProgress='yes', pH=7.2, MoveSGatom='no', SGatom=str((0, 0, 0))): # If SeeProgress='yes', computation time will take 10-20% extra, but nice to follow. cmd.refresh() RotationRange = 360 RotationDegree = 1 # For error checking, the energies can be printed out printMC = 'no' printSC = 'no' # Parameters DieElecSpheDist = 7.0 DieElecWaterDist = 1.4 DieElecWater = 78.5 DieElecCore = 4.0 BornPenaltyB = 1.0 AvogadroR = 8.31446216 Temp = 298 DeltapKMCSC = 0 pK1 = 9.25 pK2 = 8.0 NotPopuDist = 2.4 PopEnergyPenalty = 10000000 # Side chain discrete charges DieElecSC = 40.0 SCchargeASP = -1 SCchargeGLU = -1 SCchargeOXT = -1 SCchargeARG = +1 SCchargeHIS = +1 SCchargeLYS = +1 SCchargeMET1 = +1 # Main chain partial charges NrMainchainNeighBours = 5 DieElecMC = 22.0 MCchargeC = +0.55 MCchargeO = -0.55 MCchargeN = -0.35 MCchargeH = +0.35 MCchargeProCA = +0.1 MCchargeProCD = +0.1 MCchargeProN = -0.2 # Loading an Cys residue, give it a logic name, and aligning it. The oxygen atom can not be aligned in many cases, and are skipped. # We use only this molecule, to find the initial position of the SG atom, and to rotate the SG atom around the CA-CB bond. The molecule atom positions are not used for electric potential calculatons. Cysmolecule = str(molecule) + str(residue) + "Cys" cmd.fragment("cys") cmd.set_name('cys', Cysmolecule) # We use pair_fir, since align and super gets unstable with so few atoms pairfitCys(Cysmolecule, molecule, chain, residue) # Give nice representations quickly cmd.show("sticks", Cysmolecule) cmd.select(str(molecule) + str(residue) + "Res", "/" + molecule + "//" + chain + "/" + residue) print("/" + molecule + "//" + chain + "/" + residue) cmd.show("sticks", str(molecule) + str(residue) + "Res") cmd.disable(str(molecule) + str(residue) + "Res") # Find out what is the residuename we are investigating for Respdbstr = cmd.get_pdbstr(str(molecule) + str(residue) + "Res") Ressplit = Respdbstr.split() residueName = Ressplit[3] print("") print("# Hello, PyMOLers. It should take around 1 minute per residue.") print("# molecule: %s , chain: %s, residue: %s %s, pH: %s " % (molecule, chain, residueName, residue, pH)) # Determine the range of neighbour residues possible. Maxresidues = cmd.count_atoms("/" + molecule + "//" + chain + " and name CA") for i in range(NrMainchainNeighBours + 1): if int(residue) - i >= 1: Minresidue = int(residue) - i else: break for i in range(NrMainchainNeighBours + 1): if int(residue) + i <= Maxresidues: Maxresidue = int(residue) + i else: break # Get the position and the vector for the CA->CB bond. dihedN = "/" + Cysmolecule + "//" + "/" + "/N" dihedCA = "/" + Cysmolecule + "//" + "/" + "/CA" dihedCB = "/" + Cysmolecule + "//" + "/" + "/CB" dihedSG = "/" + Cysmolecule + "//" + "/" + "/SG" dihedralPosCA = cmd.get_atom_coords(dihedCA) dihedralPosSG = cmd.get_atom_coords(dihedSG) dihedralVector = AtomVector(dihedCA, dihedCB) # To compare with article, we can move the SGatom to a starting position. The rotation is still determined around the CA-CB bond. if MoveSGatom == 'yes': SGatom = [float(SGatom[1:-1].split(",")[0]), float(SGatom[1:-1].split(",")[1]), float(SGatom[1:-1].split(",")[2])] Translate = [(SGatom[0] - dihedralPosSG[0]), (SGatom[1] - dihedralPosSG[1]), (SGatom[2] - dihedralPosSG[2])] cmd.translate(Translate, dihedSG, state=0, camera=0) dihedralPosSG = cmd.get_atom_coords(dihedSG) # Create a pymol molecule, that in the end will hold and show all SG atoms. Gives the representation of the rotameric states. SGName = str(molecule) + str(residue) + "SG" cmd.create(SGName, "None") # Create a pymol molecule, that in the end will hold and show all Amide protons. Gives a nice representation, and easy to delete. AmideName = str(molecule) + str(residue) + "NH" cmd.create(AmideName, "None") # Check if there are any nearby SG atoms, which could make a SG-SG dimer formation. The breakDimer = "no" breakDimer = CheckDimer(dihedSG, molecule, chain, residue) # Create a list for appending the calculated energies. ListofEnergies = [] ListofRotamerDiscarded = [] # print "Angle before rotation", cmd.get_dihedral(dihedN,dihedCA,dihedCB,dihedSG) # Enter into the loop of rotameric states for i in range(int(math.floor(RotationRange / RotationDegree))): Angle = i * RotationDegree # Create pymol molecule/SG atom for which we will calculate for. SGNameAngle = str(residue) + "SG" + str(Angle) cmd.create(SGNameAngle, dihedSG) # Calculate new coordinates for rotation around CA->CB bond. Then translate the created SG atom. SGNewPos = fRotateAroundLine(dihedralPosSG, dihedralPosCA, dihedralVector, Angle) Translate = [(SGNewPos[0] - dihedralPosSG[0]), (SGNewPos[1] - dihedralPosSG[1]), (SGNewPos[2] - dihedralPosSG[2])] cmd.translate(Translate, SGNameAngle, state=0, camera=0) # If one wants to "see it happen" while its making the states. But it will take extra computation time. if SeeProgress == 'yes': cmd.refresh() # Calculate number of neighbours within 2.4 Angstrom. Amide hydrogens are not considered, and are actually not build yet. nameselect = "(((/" + molecule + "//" + chain + " and not /" + molecule + "//" + chain + "/" + residue + ") or /" + molecule + "//" + chain + "/" + residue + "/N+CA+C+O) within " + str(NotPopuDist) + " of /" + SGNameAngle + "//" + "/" + "/SG) and not resn HOH" # print nameselect cmd.select("NotPop", nameselect) NotPopNr = cmd.count_atoms("NotPop") # print Angle, NotPopNr, cmd.get_dihedral(dihedN,dihedCA,dihedCB,SGNameAngle) # If no neighbours, then proceed calculating if NotPopNr == 0: SumAllWMC = 0.0 # Now calculate the electric potential due to the side chains. SumWSC = fSumWSC(molecule, SGNameAngle, chain, residue, DieElecSC, SCchargeASP, SCchargeGLU, SCchargeOXT, SCchargeARG, SCchargeHIS, SCchargeLYS, SCchargeMET1, printSC) # Now we calculate for the flanking 5 peptide groups on each side of the Cysteine CA atom. # For the first residue, only calculate for the tailing C,O atom in the peptide bond. No test for Proline. SumWMCFirst = fSumWMCFirst(molecule, SGNameAngle, chain, residue, Minresidue, DieElecMC, MCchargeC, MCchargeO, printMC) # For the residue itself, we dont test for PRO, since it should be a Cysteine. SumWMCresidue = fSumWMCresidue(molecule, SGNameAngle, chain, residue, int(residue), DieElecMC, MCchargeC, MCchargeO, MCchargeN, MCchargeH, AmideName, printMC) # For the last residue, we test for Proline. We only calculate for the N,H atom, or if Proline, N,CA and CD atom. SumWMCLast = fSumWMCLast(molecule, SGNameAngle, chain, residue, Maxresidue, DieElecMC, MCchargeN, MCchargeH, MCchargeProCA, MCchargeProCD, MCchargeProN, AmideName, printMC) # Then loop over rest of the residues in the chain. for j in (list(range(Minresidue + 1, int(residue))) + list(range(int(residue) + 1, Maxresidue))): MCNeighbour = j # print "Looking at neighbour", j SumWMC = fSumWMC(molecule, SGNameAngle, chain, residue, MCNeighbour, DieElecMC, MCchargeC, MCchargeO, MCchargeN, MCchargeH, MCchargeProCA, MCchargeProCD, MCchargeProN, AmideName, printMC) SumAllWMC = SumAllWMC + SumWMC # print "Rotation: %s Neighbour: %s " % (Angle, j) # Since the SG atom is negative, we multiply with -1. SumMCSC = -1 * (SumWSC + SumWMCFirst + SumWMCresidue + SumWMCLast + SumAllWMC) # Makes the neighbour count. Everything in 'molecule" within 7 ang of aligned SG atom. Not counting 'residue'. Adding 5 for 'residue' N,CA,C,O,CB ListNeighbourCount = fNeighbourCount(molecule, SGNameAngle, chain, residue, DieElecSpheDist) # Calculate the weighted electric potential and alter the b factor for coloring. Then add the rotated SG into bucket of SG atoms. SG_MCSC_Weight = fBoltzSingleState(SumMCSC, AvogadroR, Temp) * SumMCSC cmd.alter(SGNameAngle, 'b="%s"' % SG_MCSC_Weight) cmd.alter(SGNameAngle, 'name="S%s"' % Angle) cmd.create(SGName, SGName + " + " + SGNameAngle) # Then save the calculated values ListofEnergies.append([Angle, SumMCSC, ListNeighbourCount, NotPopNr, SG_MCSC_Weight, cmd.get_atom_coords(SGNameAngle)]) cmd.delete(SGNameAngle) else: SumMCSCPenalty = PopEnergyPenalty ListNeighbourCount = fNeighbourCount(molecule, SGNameAngle, chain, residue, DieElecSpheDist) ListofRotamerDiscarded.append([Angle, SumMCSCPenalty, ListNeighbourCount, NotPopNr, 0, cmd.get_atom_coords(SGNameAngle)]) cmd.delete(SGNameAngle) # Now show all the SG atoms as the available rotameric states. cmd.show("nb_spheres", SGName) cmd.delete("NotPop") cmd.spectrum("b", selection=SGName) AvailRotStates = len(ListofEnergies) # print "Available Rotational States: ", AvailRotStates # Do the calculations according to eq 5. # Find the partition function BoltzPartition = 0.0 for i in range(len(ListofEnergies)): Boltz = fBoltzSingleState(ListofEnergies[i][1], AvogadroR, Temp) BoltzPartition = BoltzPartition + Boltz # Find the summed function BoltzSumNi = 0.0 for i in range(len(ListofEnergies)): BoltzNi = fBoltzSingleState(ListofEnergies[i][1], AvogadroR, Temp) * ListofEnergies[i][1] BoltzSumNi = BoltzSumNi + BoltzNi # Check if there was any possible rotamers nostates = "no" if len(ListofEnergies) == 0: print("####################################################") print("########### WARNING: No states available ###########") print("########### Did you mutate a Glycine? ###########") print("####################################################") BoltzSumNi = 0 BoltzPartition = 0 BoltzMCSC = 0 DeltapKMCSC = 99 NeighbourCount = 0 nostates = "yes" else: # Final calculation BoltzMCSC = (BoltzSumNi) / (BoltzPartition) DeltapKMCSC = fDeltapK(BoltzMCSC, AvogadroR, Temp) # Find average number of neighbours NCSum = 0.0 NCWeightedSum = 0.0 for i in range(len(ListofEnergies)): NCi = ListofEnergies[i][2] NCSum = NCSum + NCi NCWeightedi = fBoltzSingleState(ListofEnergies[i][1], AvogadroR, Temp) * ListofEnergies[i][2] / BoltzPartition NCWeightedSum = NCWeightedSum + NCWeightedi # print "Weighted neighbour", int(round(NCWeightedSum)) #NeighbourCount = int(round(NCSum/len(ListofEnergies))) NeighbourCount = round(NCWeightedSum, 1) # If we found dimers if breakDimer == "yes": print("####################################################") print("########### WARNING: Dimer formation? ###########") print("####################################################") BoltzSumNi = 0 BoltzPartition = 0 BoltzMCSC = 0 DeltapKMCSC = 99 NeighbourCount = 0 # Calculate the BornPenalty based on the neighbour count. It's a wrapper script for equation 13, 12, 11. EnergyBornPenalty = fEnergyBornPenalty(DieElecSpheDist, DieElecWaterDist, NeighbourCount, DieElecWater, DieElecCore, BornPenaltyB) DeltapKB = fDeltapK(EnergyBornPenalty, AvogadroR, Temp) # Do the calculations according to eq 3 and 9. pKm1 = fpKm1(DeltapKMCSC, pK1) pKm2 = fpKm2(DeltapKMCSC, DeltapKB, pK2) FracCysm1 = fFracCys(pKm1, pH) FracCysm2 = fFracCys(pKm2, pH) # Lets make a result file, and write out the angle, the SumMCSC, and the number of neighbours for this state. Currentdir = os.getcwd() Newdir = os.path.join(os.getcwd(), "Results") if not os.path.exists(Newdir): os.makedirs(Newdir) filename = os.path.join(".", "Results", "Result_" + molecule + "_" + chain + "_" + residue + ".txt") filenamelog = os.path.join(".", "Results", "Result_log.log") logfile = open(filenamelog, "a") outfile = open(filename, "w") timeforlog = strftime("%Y %b %d %a %H:%M:%S", localtime()) logfile.write("# " + timeforlog + "\n") logfile.write("# molecule: %s , chain: %s, residue: %s %s, pH: %s " % (molecule, chain, residueName, residue, pH) + "\n") logfile.write("# BoltzSumNi: BoltzPartition: BoltzMCSC" + "\n") logfile.write(("# %.4f %.4f %.4f" + '\n') % (BoltzSumNi, BoltzPartition, BoltzMCSC)) logfile.write("# Res NC States pKmcsc pK1 pKB pK2 pKm1 pKm2 f(C-)m1 f(C-)m2" + "\n") logfile.write(("; %s %s %s %s %.4f %s %.4f %s %.4f %.4f %.6f %.6f" + '\n') % (residueName, residue, NeighbourCount, AvailRotStates, DeltapKMCSC, pK1, DeltapKB, pK2, pKm1, pKm2, FracCysm1, FracCysm2)) if nostates == "yes": logfile.write("##### ERROR; No states available ###" + "\n") if breakDimer == "yes": logfile.write("##### ERROR; Dimer formation ###" + "\n") logfile.write('\n') outfile.write("# molecule: %s , chain: %s, residue: %s %s, pH: %s " % (molecule, chain, residueName, residue, pH) + "\n") outfile.write("# BoltzSumNi: BoltzPartition: BoltzMCSC" + "\n") outfile.write(("# %.4f %.4f %.4f" + '\n') % (BoltzSumNi, BoltzPartition, BoltzMCSC)) outfile.write("# Res NC States pKmcsc pK1 pKB pK2 pKm1 pKm2 f(C-)m1 f(C-)m2" + "\n") outfile.write(("; %s %s %s %s %.4f %s %.4f %s %.4f %.4f %.6f %.6f" + '\n') % (residueName, residue, NeighbourCount, AvailRotStates, DeltapKMCSC, pK1, DeltapKB, pK2, pKm1, pKm2, FracCysm1, FracCysm2)) if nostates == "yes": outfile.write("##### ERROR; No states available ###" + "\n") if breakDimer == "yes": outfile.write("##### ERROR; Dimer formation ###" + "\n") outfile.write('\n') outfile.write("#Ang SumMCSC NC rNC MCSC_Weight SG[X,Y,Z]" + "\n") for i in range(len(ListofEnergies)): outfile.write("%4.1d %10.3f %2.1d %1.1d %10.3f [%8.3f, %8.3f, %8.3f]" % (ListofEnergies[i][0], ListofEnergies[i][1], ListofEnergies[i][2], ListofEnergies[i][3], ListofEnergies[i][4], ListofEnergies[i][5][0], ListofEnergies[i][5][1], ListofEnergies[i][5][2]) + '\n') for i in range(len(ListofRotamerDiscarded)): outfile.write("%4.1d %10.3f %2.1d %1.1d %10.3f [%8.3f, %8.3f, %8.3f]" % (ListofRotamerDiscarded[i][0], ListofRotamerDiscarded[i][1], ListofRotamerDiscarded[i][2], ListofRotamerDiscarded[i][3], ListofRotamerDiscarded[i][4], ListofRotamerDiscarded[i][5][0], ListofRotamerDiscarded[i][5][1], ListofRotamerDiscarded[i][5][2]) + '\n') outfile.close() # Now, we are done. Just print out. The ; is for a grep command to select these lines in the output. print("# residue: %s %s. Average NeighbourCount NC= %s " % (residueName, residue, NeighbourCount)) print("# From residue %s to residue %s" % (Minresidue, Maxresidue)) print("# BoltzSumNi: BoltzPartition: BoltzMCSC") print("# %.4f %.4f %.4f" % (BoltzSumNi, BoltzPartition, BoltzMCSC)) print("# Result written in file: %s" % (filename)) print("# Res NC States pKmcsc pK1 pKB pK2 pKm1 pKm2 f(C-)m1 f(C-)m2") print("; %s %s %s %s %.4f %s %.4f %s %.4f %.4f %.6f %.6f" % (residueName, residue, NeighbourCount, AvailRotStates, DeltapKMCSC, pK1, DeltapKB, pK2, pKm1, pKm2, FracCysm1, FracCysm2)) if nostates == "yes": print("##### ERROR; No states available ###") if breakDimer == "yes": print("##### ERROR; Dimer formation ###")