Пример #1
0
    def do_pick(self, picked_bond):
 
        # this shouldn't actually happen if going through the "do_select"
        if picked_bond:
            self.error = "Error: please select bonds, not atoms"
            print self.error
            return
 
        atom_name = self.object_prefix + str(self.pick_count)
        if self.pick_count < 2:
            self.pickNextAtom(atom_name)
        else:
            self.pickNextAtom(atom_name)
 
            point1 = cmd.get_atom_coords("(%s%s)" % (self.object_prefix, "0"))
            point2 = cmd.get_atom_coords("(%s%s)" % (self.object_prefix, "1"))
            point3 = cmd.get_atom_coords("(%s%s)" % (self.object_prefix, "2"))
            plane = planeFromPoints(point1, point2, point3, self.facetSize)
 
            planeName = "plane-%02d" % self.object_count
            self.object_count += 1
            makePrimitive(plane, planeName)
            cmd.show("cgo", "plane*")
 
            self.pick_count = 0
            self.reset()
Пример #2
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'))
Пример #3
0
def getxyz(Sel):
	if type(Sel)==list and len(Sel)==3:
		return Sel, "listXYZ"
	if type(Sel)==str and Sel[0]=="[" and Sel[-1]=="]":
		Selsplit = list(Sel[1:-1].split(","))
		Selsplit = [float(x) for x in Selsplit]
		return Selsplit, "strXYZ"
	if type(Sel)==str:
		pos = cmd.get_atom_coords(Sel)
		return pos, "selXYZ"
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 "distancetoatom: 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
Пример #5
0
 def get_coord(v):
     if not isinstance(v, str):
         return v
     if v.startswith('['):
         return cmd.safe_list_eval(v)
     return cmd.get_atom_coords(v)
def Coord(Input):
    print(cmd.get_atom_coords(Input))
Пример #7
0
def AtomVector(AtomStart, AtomEnd):
    PosStart = cmd.get_atom_coords(AtomStart)
    PosEnd = cmd.get_atom_coords(AtomEnd)
    VectorDiff = [(PosEnd[0] - PosStart[0]), (PosEnd[1] - PosStart[1]), (PosEnd[2] - PosStart[2])]
    return VectorDiff
Пример #8
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 ###")
Пример #9
0
def rpcGetAtomCoords(what='all', state=0):
  """ returns the results of cmd.get_atom_coords(what,state) """
  return cmd.get_atom_coords(what, state=state)
Пример #10
0
def elbow_angle(obj, light='L', heavy='H', limit_l=107, limit_h=113, draw=0):
    """

DESCRIPTION

    Calculates the integer elbow angle of an antibody Fab complex and 
    optionally draws a graphical representation of the vectors used to 
    determine the angle.

ARGUMENTS

    obj = string: object

    light/heavy = strings: chain ID of light and heavy chains, respectively

    limit_l/limit_h = integers: residue numbers of the last residue in the 
    light and heavy chain variable domains, respectively    

    draw = boolean: Choose whether or not to draw the angle visualization

REQUIRES: com.py, transformations.py, numpy (see above)


    """

    # store current view
    orig_view = cmd.get_view()

    limit_l = int(limit_l)
    limit_h = int(limit_h)
    draw = int(draw)

    # for temp object names
    tmp_prefix = "tmp_elbow_"

    prefix = tmp_prefix + obj + '_'

    # names
    vl = prefix + 'VL'
    vh = prefix + 'VH'
    cl = prefix + 'CL'
    ch = prefix + 'CH'

    # selections
    vl_sel = 'polymer and %s and chain %s and resi 1-%i' % (obj, light, limit_l)
    vh_sel = 'polymer and %s and chain %s and resi 1-%i' % (obj, heavy, limit_h)
    cl_sel = 'polymer and %s and chain %s and not resi 1-%i' % (obj, light, limit_l)
    ch_sel = 'polymer and %s and chain %s and not resi 1-%i' % (obj, heavy, limit_h)
    v_sel = '((' + vl_sel + ') or (' + vh_sel + '))'
    c_sel = '((' + cl_sel + ') or (' + ch_sel + '))'

    # create temp objects
    cmd.create(vl, vl_sel)
    cmd.create(vh, vh_sel)
    cmd.create(cl, cl_sel)
    cmd.create(ch, ch_sel)

    # superimpose vl onto vh, calculate axis and angle
    Rv = calc_super_matrix(vl, vh)
    angle_v, direction_v, point_v = transformations.rotation_from_matrix(Rv)

    # superimpose cl onto ch, calculate axis and angle
    Rc = calc_super_matrix(cl, ch)
    angle_c, direction_c, point_c = transformations.rotation_from_matrix(Rc)

    # delete temporary objects
    cmd.delete(vl)
    cmd.delete(vh)
    cmd.delete(cl)
    cmd.delete(ch)

    # if dot product is positive, angle is acute
    if (numpy.dot(direction_v, direction_c) > 0):
        direction_c = direction_c * -1   # ensure angle is > 90 (need to standardize this)

        # TODO: make both directions point away from the elbow axis.

    elbow = int(numpy.degrees(numpy.arccos(numpy.dot(direction_v, direction_c))))
    # while (elbow < 90):
    # elbow = 180 - elbow   # limit to physically reasonable range

    # compare the direction_v and direction_c axes to the vector defined by
    # the C-alpha atoms of limit_l and limit_h of the original fab
    hinge_l_sel = "%s//%s/%s/CA" % (obj, light, limit_l)
    hinge_h_sel = "%s//%s/%s/CA" % (obj, heavy, limit_h)
    hinge_l = cmd.get_atom_coords(hinge_l_sel)
    hinge_h = cmd.get_atom_coords(hinge_h_sel)
    hinge_vec = numpy.array(hinge_h) - numpy.array(hinge_l)

    test = numpy.dot(hinge_vec, numpy.cross(direction_v, direction_c))
    if (test > 0):
        elbow = 360 - elbow

    print "    Elbow angle: %i degrees" % elbow

    if (draw == 1):
        # there is probably a more elegant way to do this, but
        # it works so I'm not going to mess with it for now

        pre = obj + '_elbow_'

        # draw hinge vector
        cmd.pseudoatom(pre + "hinge_l", pos=hinge_l)
        cmd.pseudoatom(pre + "hinge_h", pos=hinge_h)
        cmd.distance(pre + "hinge_vec", pre + "hinge_l", pre + "hinge_h")
        cmd.set("dash_gap", 0)

        # draw the variable domain axis
        com_v = com.COM(v_sel)
        start_v = [a - 10 * b for a, b in zip(com_v, direction_v)]
        end_v = [a + 10 * b for a, b in zip(com_v, direction_v)]
        cmd.pseudoatom(pre + "start_v", pos=start_v)
        cmd.pseudoatom(pre + "end_v", pos=end_v)
        cmd.distance(pre + "v_vec", pre + "start_v", pre + "end_v")

        # draw the constant domain axis
        com_c = com.COM(c_sel)
        start_c = [a - 10 * b for a, b in zip(com_c, direction_c)]
        end_c = [a + 10 * b for a, b in zip(com_c, direction_c)]
        cmd.pseudoatom(pre + "start_c", pos=start_c)
        cmd.pseudoatom(pre + "end_c", pos=end_c)
        cmd.distance(pre + "c_vec", pre + "start_c", pre + "end_c")

        # customize appearance
        cmd.hide("labels", pre + "hinge_vec")
        cmd.hide("labels", pre + "v_vec")
        cmd.hide("labels", pre + "c_vec")
        cmd.color("green", pre + "hinge_l")
        cmd.color("red", pre + "hinge_h")
        cmd.color("black", pre + "hinge_vec")
        cmd.color("black", pre + "start_v")
        cmd.color("black", pre + "end_v")
        cmd.color("black", pre + "v_vec")
        cmd.color("black", pre + "start_c")
        cmd.color("black", pre + "end_c")
        cmd.color("black", pre + "c_vec")
        # draw spheres
        cmd.show("spheres", pre + "hinge_l or " + pre + "hinge_h")
        cmd.show("spheres", pre + "start_v or " + pre + "start_c")
        cmd.show("spheres", pre + "end_v or " + pre + "end_c")
        cmd.set("sphere_scale", 2)
        cmd.set("dash_gap", 0, pre + "hinge_vec")
        cmd.set("dash_width", 5)
        cmd.set("dash_radius", 0.3)

        # group drawing objects
        cmd.group(pre, pre + "*")

    # restore original view
    cmd.set_view(orig_view)

    return 0
def distancetoatom(
origin='pk1',
cutoff=10,
filename=None,
selection='all',
state=0,
property_name='p.dist',
coordinates=0,
decimals=3,
sort=1,
quiet=1
):
    '''
DESCRIPTION

    distancetoatom.py
    Described at: http://www.pymolwiki.org/Distancetoatom

    Prints all distanced between the specified atom/coordinate/center
    and all atoms within cutoff distance that are part of the selection.
    All coordinates and distances can be saved in a csv-style text file report
    and can be appended to a (custom) atom property, if defined.

USAGE

    distancetoatom [ origin [, cutoff [, filename [, selection
    [, state [, property_name [, coordinates [, decimals [, sort
    [, quiet ]]]]]]]]]]

ARGUMENTS

    NAME        TYPE    FUNCTION
    origin:     <list>  defines the coordinates for the origin and can be:
                <str>   1. a list with coordinates [x,y,z]
                        2. a single atom selection string {default='pk1'}
                        3. a multi-atom selection string (center will be used)
    cutoff      <float> sets the maximum distance {default: 10}
    filename    <str>   filename for optional output report. {default=None}
                        set to e.g. 'report.txt' to create a report
                        (omit or set to '', None, 0 or False to disable)
    selection   <str>   can be used to define/limit the measurment to specific
                        sub-selections {default='all'}
    state       <int>   object state, {default=0} # = current
    property_name <str> the distance will be stored in this property {p.dist}
                        set "" to disable
    coordinates <int>   toggle whether atom coordinated will be reported {0}
    decimals    <int>   decimals for coordinates and distance:
                        default = 3 # = max. PDB resolution
    sort        <int>   Sorting by distance?
                         1: ascending (default)
                         0: no sorting (by names)
                        -1: descending
    quiet       <bool>  toggle verbosity
    '''
    # keyword check
    try:
        selection = '(%s)'%selection
        ori=get_coord(origin)
        if not ori:
            print "distancetoatom: aborting - check input for 'origin'!"
            return False
        cutoff = abs(float(cutoff))
        filename = str(filename)
        state = abs(int(state))
        if (not int(state)):
            state=cmd.get_state()
        cmd.set('state', state) # distance by state
        property_name = str(property_name)
        decimals = abs(int(decimals))
        sort = int(sort)
        coordinates=bool(int(coordinates))
        quiet=bool(int(quiet))
    except:
        print 'distancetoatom: aborting - input error!'
        return False

    # round origin
    ori = [round(x,decimals) for x in ori]

    # report?
    if filename in ['', '0', 'False', 'None']:
        filename=False
    else:
        try:
            report=open(filename,'w') # file for writing
        except:
            print 'distancetoatom: Unable to open report file! - Aborting!'
            return False

    # temporary name for pseudoatom
    tempname = cmd.get_unused_name('temp_name')
    tempsel = cmd.get_unused_name('temp_sel')

    #origin
    cmd.pseudoatom(object=tempname, resi=1, pos=ori)

    # select atoms within cutoff
    cmd.select(tempsel, '(%s around %f) and (%s) and state %d' %(tempname, cutoff, selection, state))
    cmd.delete(tempname)

    # single atom ori and part of selection
    # avoid double reporting!
    single_atom_ori=False
    try:
        if cmd.count_atoms('(%s) and (%s) and (%s)'%(selection, tempsel, origin))==1:
            single_atom_ori=True
    except: pass
    # pass= coordinates or multi-atom or single, not selected --> report ori

    # atom list
    stored.temp=[]
    cmd.iterate(tempsel, 'stored.temp.append([model, segi, chain, resn, resi, name, alt])')

    # custom properties? # conditional disabling
    if (property_name==''): property_name=False
    if ((cmd.get_version()[1]<1.7) and (property_name not in ['b','q'])):
        property_name=False

    # calculate the distances, creating list
    distance_list=[]
    if (not single_atom_ori):
        distance_list.append(['ORIGIN: '+str(origin), ori[0], ori[1], ori[2], 0.0])
    for atom in stored.temp:
        atom_name = ('/%s/%s/%s/%s`%s/%s`%s'%(atom[0], atom[1], atom[2], atom[3], atom[4], atom[5], atom[6]))
        atom_xyz = [round(x, decimals) for x in cmd.get_atom_coords(atom_name)]
        atom_dist = round(cpv.distance(ori, atom_xyz), decimals)
        distance_list.append([atom_name,atom_xyz[0],atom_xyz[1],atom_xyz[2], atom_dist])
        # create property with distance (can be used for coloring, labeling etc)
        if property_name:
            try:
                cmd.alter(atom_name, '%s=%f'%(property_name, atom_dist))
            except:
                # I'm not sure alter raises exceptions if the property is illegal
                property_name=False

    # sort list, if selected
    if sort>0: distance_list.sort(key=lambda dist: dist[4])
    elif sort<0: distance_list.sort(key=lambda dist: dist[4], reverse=True)
    # add header
    distance_list=[['Atom Macro ID',
                    'x-coord',
                    'y-coord',
                    'z-coord',
                    'distance_to_origin']
                ]+distance_list

    if ((not quiet) and (filename)):
        # Hijack stdout to print to file and console
        class logboth(object):
            def __init__(self, *files):
                self.files = files
            def write(self, obj):
                for f in self.files:
                    f.write(obj)
        originalstdout = sys.stdout
        sys.stdout = logboth(sys.stdout, report)

    for entry in distance_list:
        if coordinates:
            output= '%s, %s, %s, %s, %s' %(entry[0],entry[1],entry[2],entry[3],entry[4]) #csv style
        else:
            output= '%s, %s' %(entry[0],entry[4]) #csv style
        if (not quiet):
            print output
        elif filename:
            report.write(output+'\n')

    # restore regular stdout
    if ((not quiet) and (filename)): sys.stdout = originalstdout
    # close file
    if filename: report.close()

    if (not quiet):
        if property_name: print 'Distances saved to property: %s' %str(property_name)
        else: print 'Distances NOT saved to property (illegal custom property)'
Пример #12
0
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
Пример #13
0
 def get_coord(v):
     if not isinstance(v, str):
         return v
     if v.startswith('['):
         return cmd.safe_list_eval(v)
     return cmd.get_atom_coords(v)