SelInside

From PyMOLWiki
Jump to navigation Jump to search

selInside selects all atoms of a certain type that are located within the bounding box defined by some selection. See examples.

Usage

# find all atoms inside the box spanned by (0,0,0) and (10,10,10)
# for the example PDB, 1hpv
fetch 1hpv
pseudoatom b1, pos=[0,0,0]
pseudoatom b2, pos=[10,10,10]
selInside b1 or b2


The Code

import pymol
from pymol import cmd, stored
from random import randint

def selInside(bounding_object, target="*", radius=None):
    """
    Selects all atoms of a given target type inside some selection that acts like a bounding box.

    PARAMS:
        bounding_object -- [PyMOL object/selection] the object/selection inside of which we want to choose atoms
        target -- [PyMOL selection] that defines the atoms to select.  Use "solvent" to select
                  only solvent atoms inside the selection
        radius -- [float] expand the box by this many angstroms on all sides

    RETURNS:
        (string) name of the selection created

    NOTES:
       assumes a single-state setup; for multi-state you must modify this script
    """

    # get the extents of the bounding object into two arrays
    (bMin, bMax) = cmd.get_extent(bounding_object)

    # if the user supplied a size by which we need to expand the box, we do that here
    if radius!=None:
        try:
            # try to convert a string to a float
            radius = float(str(radius))
        except ValueError:
            print "ERROR: Invalid radius declared.  Please make sure the radius is a number or left blank"
            return
        # add/subtract the radius to the bounds
        bMin = map( lambda f: f-radius, bMin)
        bMax = map( lambda f: f+radius, bMax)
 
    # initialize a selection; selections starting with underscores are hidden by PyMOL
    cmd.select("__toRemove", "None")

    # for each atom in the target selection, if it's inside the box, add it to the selection
    for at in cmd.get_model(target).atom:
        if at.coord[0] > bMin[0] and at.coord[0] < bMax[0] and at.coord[1] > bMin[1] and at.coord[1] < bMax[1] and at.coord[2] > bMin[2] and at.coord[2] < bMax[2] :
           cmd.select("__toRemove", "__toRemove or index %d" % at.index)

    # prepare the return values
    rName = "insideBoundingObj"
    cmd.set_name("__toRemove", rName)

    return rName

cmd.extend("selInside", selInside)