Split Object Along Axis

From PyMOLWiki
Revision as of 16:54, 13 April 2010 by Bhannigan (talk | contribs) (Created page with '== Overview == I have a number of small molecules that I am looking at. Many of these small molecules have distinct sections which are connected by a single bond. In a separate…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Overview

I have a number of small molecules that I am looking at. Many of these small molecules have distinct sections which are connected by a single bond. In a separate program I am writing, I would like to rotate each section around the given bond. I wanted a script that would allow me to select a bond, and then generate 2 selections: one for the selection of all atoms that are on one side of this bond, and the other selection for the atoms on the other side of the bond. If there is a 2nd bond which connects the 2 sections of atoms, the script will still run and terminate, but the two selections won't make much sense!

To use, just call splitObjAlongAxis(axisSelection, outFileName) where: axisSelection is a selection that includes 2 atoms. These atoms define the axis which we are splitting across. outFileName is an optional file name where the script will spit three lines. The first line will be the two atom id's of the axis. The second line will be a list of atom id's in the selection generated, and the third line will be a list of atom id's in the second selection generated.

Source Code

def findAttachedAtoms(objModel, atomIndex, excludeAtomIndex, atoms):
    atoms += [objModel.atom[atomIndex]]
    
    for b in objModel.bond:
        if((atomIndex in b.index) and (excludeAtomIndex not in b.index)):
            newAtomIndex = -1
            if(b.index[0] == atomIndex):
                newAtomIndex = b.index[1]
            else:
                newAtomIndex = b.index[0]

            newAtom = objModel.atom[newAtomIndex]
            if(newAtom not in atoms):
                atoms += [newAtom]
                findAttachedAtoms(objModel, newAtomIndex, excludeAtomIndex, atoms)


def getNewSelection(objModel, atomId, excludeAtomId):
    atomIndex = -1
    excludeAtomIndex = -1

    for i in range(len(objModel.atom)):
        if(objModel.atom[i].id == atomId):
            atomIndex = i
        if(objModel.atom[i].id == excludeAtomId):
            excludeAtomIndex = i

    atoms = []
    findAttachedAtoms(objModel, atomIndex, excludeAtomIndex, atoms)

    return atoms

def outputSelections(leftSel, rightSel, axisModel, outFileName, append):
    mode = 'w'
    if(append):
        mode = 'a'

    of = open(outFileName, mode)
    line = str(axisModel.atom[0].id) + ',' + str(axisModel.atom[1].id) + '\n'
    of.write(line)

    line = ''
    for a in leftSel:
        line += str(a.id) + ','
    of.write(line[0:-1] + '\n')

    line = ''
    for a in rightSel:
        line += str(a.id) + ','
    of.write(line[0:-1] + '\n')

    of.close()


def splitObjAlongAxis(objName, axisSelection, outFileName = '', append = False):
    objModel = cmd.get_model(objName)
    axisModel = cmd.get_model(axisSelection)

    leftSel = []
    rightSel = []

    try:
        leftSel = getNewSelection(objModel, axisModel.atom[0].id, axisModel.atom[1].id)
        rightSel = getNewSelection(objModel, axisModel.atom[1].id, axisModel.atom[0].id)
    except:
        print 'Error in splitObjAlongAxis!'

    selection = ''
    for a in leftSel:
        selection += 'id ' + str(a.id) + ' or '
    selection = selection[0:-3]
    cmd.select('left',selection)

    selection = ''
    for a in rightSel:
        selection += 'id ' + str(a.id) + ' or '
    selection = selection[0:-3]
    cmd.select('right',selection)

    if(outFileName != ''):
        outputSelections(leftSel, rightSel, axisModel, outFileName, append)