def visualize_orientation(direction, center=[0, 0, 0], scale=1.0, symmetric=False, color="green", color2="red"):
    """
    Draw an arrow. Helper function for "helix_orientation" etc.
    """
    from pymol import cgo

    color_list = cmd.get_color_tuple(color)
    color2_list = cmd.get_color_tuple(color2)
    if symmetric:
        scale *= 0.5
    end = cpv.add(center, cpv.scale(direction, scale))
    radius = 0.3
    obj = [cgo.SAUSAGE]
    obj.extend(center)
    obj.extend(end)
    obj.extend([radius, 0.8, 0.8, 0.8])
    obj.extend(color_list)
    if symmetric:
        start = cpv.sub(center, cpv.scale(direction, scale))
        obj.append(cgo.SAUSAGE)
        obj.extend(center)
        obj.extend(start)
        obj.extend([radius, 0.8, 0.8, 0.8])
        obj.extend(color2_list)
    coneend = cpv.add(end, cpv.scale(direction, 4.0 * radius))
    if cmd.get_version()[1] >= 1.2:
        obj.append(cgo.CONE)
        obj.extend(end)
        obj.extend(coneend)
        obj.extend([radius * 1.75, 0.0])
        obj.extend(color_list * 2)
        obj.extend([1.0, 1.0])  # Caps
    cmd.load_cgo(obj, get_unused_name("oriVec"), zoom=0)
Ejemplo n.º 2
0
def planeFromPoints(point1, point2, point3, facetSize):
    v1 = cpv.normalize(cpv.sub(point2, point1))
    v2 = cpv.normalize(cpv.sub(point3, point1))
    normal = cpv.cross_product(v1, v2)
    v2 = cpv.cross_product(normal, v1)
    x = cpv.scale(v1, facetSize)
    y = cpv.scale(v2, facetSize)
    center = point2
    corner1 = cpv.add(cpv.add(center, x), y)
    corner2 = cpv.sub(cpv.add(center, x), y)
    corner3 = cpv.sub(cpv.sub(center, x), y)
    corner4 = cpv.add(cpv.sub(center, x), y)
    return plane(corner1, corner2, corner3, corner4, normal)
Ejemplo n.º 3
0
    def centerofmass(selection='(all)', state=-1, quiet=1, _self=cmd):
        '''
DESCRIPTION

    Calculates the center of mass. Considers atom mass and occupancy.

ARGUMENTS

    selection = string: atom selection {default: all}

    state = integer: object state, -1 for current state, 0 for all states
    {default: -1}

NOTES

    If occupancy is 0.0 for an atom, set it to 1.0 for the calculation
    (assume it was loaded from a file without occupancy information).

SEE ALSO

    get_extent
        '''
        from chempy import cpv
        state, quiet = int(state), int(quiet)

        if state < 0:
            states = [get_selection_state(selection)]
        elif state == 0:
            states = range(1, _self.count_states(selection)+1)
        else:
            states = [state]

        com = cpv.get_null()
        totmass = 0.0

        for state in states:
            model = _self.get_model(selection, state)
            for a in model.atom:
                m = a.get_mass() * (a.q or 1.0)
                com = cpv.add(com, cpv.scale(a.coord, m))
                totmass += m

        if not totmass:
            raise pymol.CmdException('mass is zero')

        com = cpv.scale(com, 1./totmass)
        if not quiet:
            print ' Center of Mass: [%8.3f,%8.3f,%8.3f]' % tuple(com)
        return com
Ejemplo n.º 4
0
def visualize_orientation(direction, center=[0.0]*3, scale=1.0, symmetric=False, color='green', color2='red'):
    '''
DESCRIPTION

    Draw an arrow. Helper function for "helix_orientation" etc.
    '''
    from pymol import cgo

    color_list = cmd.get_color_tuple(color)
    color2_list = cmd.get_color_tuple(color2)

    if symmetric:
        scale *= 0.5
    end = cpv.add(center, cpv.scale(direction, scale))
    radius = 0.3

    obj = [cgo.SAUSAGE]
    obj.extend(center)
    obj.extend(end)
    obj.extend([
        radius,
        0.8, 0.8, 0.8,
    ])
    obj.extend(color_list)

    if symmetric:
        start = cpv.sub(center, cpv.scale(direction, scale))
        obj.append(cgo.SAUSAGE)
        obj.extend(center)
        obj.extend(start)
        obj.extend([
            radius,
            0.8, 0.8, 0.8,
        ])
        obj.extend(color2_list)

    coneend = cpv.add(end, cpv.scale(direction, 4.0*radius/cpv.length(direction)))
    obj.append(cgo.CONE)
    obj.extend(end)
    obj.extend(coneend)
    obj.extend([
        radius * 1.75,
        0.0,
    ])
    obj.extend(color_list * 2)
    obj.extend([
        1.0, 1.0, # Caps
    ])
    cmd.load_cgo(obj, get_unused_name('oriVec'), zoom=0)
Ejemplo n.º 5
0
def gyradius(selection='(all)', state=-1, quiet=1):
    '''
DESCRIPTION
 
    Radius of gyration

    Based on: http://pymolwiki.org/index.php/Radius_of_gyration

SEE ALSO

    centerofmass
    '''
    from chempy import cpv
    state, quiet = int(state), int(quiet)
    if state < 0:
        states = [cmd.get_state()]
    elif state == 0:
        states = list(range(1, cmd.count_states(selection)+1))
    else:
        states = [state]
    rg_sq_list = []
    for state in states:
        model = cmd.get_model(selection, state)
        x = [i.coord for i in model.atom]
        mass = [i.get_mass() * i.q for i in model.atom if i.q > 0]
        xm = [cpv.scale(v,m) for v,m in zip(x,mass)]
        tmass = sum(mass)
        rr = sum(cpv.dot_product(v,vm) for v,vm in zip(x,xm))
        mm = sum((sum(i)/tmass)**2 for i in zip(*xm))
        rg_sq_list.append(rr/tmass - mm)
    rg = (sum(rg_sq_list)/len(rg_sq_list))**0.5
    if not quiet:
        print(' Radius of gyration: %.2f' % (rg))
    return rg
Ejemplo n.º 6
0
def cgo_tetrahedron(x, y, z, r):
    vertices = [cpv.add((x,y,z), cpv.scale(v, r)) for v in [
        [0., 1., 0.],
        [0.0, -0.3338068592337708, 0.9426414910921784],
        [0.8163514779470693, -0.3338068592337708, -0.471320745546089],
        [-0.816351477947069, -0.3338068592337708, -0.4713207455460897]
    ]]
    return [
       cgo.BEGIN, cgo.TRIANGLES,
       cgo.NORMAL, 0.8165448970931916, 0.33317549135767066, 0.4714324161421696,
       cgo.VERTEX ] + vertices[0] + [
       cgo.VERTEX ] + vertices[1] + [
       cgo.VERTEX ] + vertices[2] + [
       cgo.NORMAL, 0., 0.3331754913576707, -0.9428648322843389,
       cgo.VERTEX ] + vertices[0] + [
       cgo.VERTEX ] + vertices[2] + [
       cgo.VERTEX ] + vertices[3] + [
       cgo.NORMAL, -0.8165448970931919, 0.3331754913576705, 0.4714324161421693,
       cgo.VERTEX ] + vertices[0] + [
       cgo.VERTEX ] + vertices[3] + [
       cgo.VERTEX ] + vertices[1] + [
       cgo.NORMAL,  0.,  -1., 0.,
       cgo.VERTEX ] + vertices[1] + [
       cgo.VERTEX ] + vertices[2] + [
       cgo.VERTEX ] + vertices[3] + [
       cgo.END,
   ]
Ejemplo n.º 7
0
def centerofmass(selection='(all)', state=-1, quiet=1):
    '''
DESCRIPTION

    Calculates the center of mass. Considers atom mass and occupancy.

ARGUMENTS

    selection = string: atom selection {default: all}

    state = integer: object state, -1 for current state, 0 for all states
    {default: -1}

EXAMPLE

    from psico.querying import *
    x = centerofmass('chain A')
    r = gyradius('chain A')
    cmd.pseudoatom('com', pos=x, vdw=r)

SEE ALSO

    gyradius
    '''
    from chempy import cpv
    state, quiet = int(state), int(quiet)
    if state < 0:
        states = [cmd.get_state()]
    elif state == 0:
        states = list(range(1, cmd.count_states(selection)+1))
    else:
        states = [state]
    com = cpv.get_null()
    totmass = 0.0
    for state in states:
        model = cmd.get_model(selection, state)
        for a in model.atom:
            if a.q == 0.0:
                continue
            m = a.get_mass() * a.q
            com = cpv.add(com, cpv.scale(a.coord, m))
            totmass += m
    com = cpv.scale(com, 1./totmass)
    if not quiet:
        print(' Center of Mass: [%8.3f,%8.3f,%8.3f]' % tuple(com))
    return com
Ejemplo n.º 8
0
def _cgo_quad(pos, normal, radius):
    '''Return a CGO list specifying a quad.'''
    v1 = cpv.normalize(_perp_vec(normal))
    v2 = cpv.cross_product(normal, v1)
    v1 = cpv.scale(v1, radius)
    v2 = cpv.scale(v2, radius)
    obj = [ cgo.BEGIN,
            cgo.TRIANGLE_STRIP,
            cgo.NORMAL]
    obj.extend(normal)
    obj.append(cgo.VERTEX)
    obj.extend(cpv.add(pos, v1))
    obj.append(cgo.VERTEX)
    obj.extend(cpv.add(pos, v2))
    obj.append(cgo.VERTEX)
    obj.extend(cpv.sub(pos, v2))
    obj.append(cgo.VERTEX)
    obj.extend(cpv.sub(pos, v1))
    obj.append(cgo.END)
    return obj
Ejemplo n.º 9
0
Archivo: cgo07.py Proyecto: Almad/pymol
def random_ellipsoid(box, size, min_axis):

    # return a random ellipsoid record of the form:
    # [ ELLIPSOID, x_pos, y_pos, z_pos, size, x0, y0, z0, x1, y1, z2, x2, y2, z2 ]
    # where the xyz vectors are orthogonal and of length 1.0 or less.
    
    box = box - size
    tmp0 = cpv.random_vector()
    tmp1 = cpv.random_vector()
    tmp2 = cpv.cross_product(tmp1, tmp0)
    tmp3 = cpv.cross_product(tmp1, tmp2)
    tmp4 = cpv.cross_product(tmp2, tmp3)
    tmp2 = cpv.normalize(tmp2)
    tmp3 = cpv.normalize(tmp3)
    tmp4 = cpv.normalize(tmp4)
    primary = cpv.scale(tmp2, random())
    secondary = cpv.scale(tmp3,random())
    tertiary = cpv.scale(tmp4,random())
    factor = 1.0 / max( cpv.length(primary), cpv.length(secondary), cpv.length(tertiary))
    primary = cpv.scale(primary, factor)
    secodary = cpv.scale(secondary, factor)
    tertiary = cpv.scale(tertiary, factor)
    return [ ELLIPSOID,
             size + random() * box, size + random() * box, size + random() * box,
             max(random() * size, min_axis),
             ] + primary + secondary + tertiary
Ejemplo n.º 10
0
def plane_orientation(selection, state=-1, visualize=1, quiet=1):
    '''
DESCRIPTION

    Fit plane (for example beta-sheet). Can also be used with
    angle_between_helices (even though this does not fit helices).

    Returns center and normal vector of plane.
    '''
    try:
        import numpy
    except ImportError:
        print ' Error: numpy not available'
        raise CmdException

    state, visualize, quiet = int(state), int(visualize), int(quiet)

    coords = list()
    cmd.iterate_state(state, '(%s) and guide' % (selection),
            'coords.append([x,y,z])', space=locals())

    if len(coords) < 3:
        print 'not enough guide atoms in selection'
        raise CmdException

    x = numpy.array(coords)
    U,s,Vh = numpy.linalg.svd(x - x.mean(0))

    # normal vector of plane is 3rd principle component
    vec = cpv.normalize(Vh[2])
    if cpv.dot_product(vec, x[-1] - x[0]) < 0:
        vec = cpv.negate(vec)

    center = x.mean(0).tolist()
    _common_orientation(selection, center, vec, visualize, 4.0, quiet)

    # plane visualize
    if visualize:
        from pymol import cgo

        dir1 = cpv.normalize(Vh[0])
        dir2 = cpv.normalize(Vh[1])
        sx = [max(i/4.0, 2.0) for i in s]

        obj = [ cgo.BEGIN, cgo.TRIANGLES, cgo.COLOR, 0.5, 0.5, 0.5 ]
        for vertex in [
                cpv.scale(dir1, sx[0]),
                cpv.scale(dir2, sx[1]),
                cpv.scale(dir2, -sx[1]),
                cpv.scale(dir1, -sx[0]),
                cpv.scale(dir2, -sx[1]),
                cpv.scale(dir2, sx[1]),
                ]:
            obj.append(cgo.VERTEX)
            obj.extend(cpv.add(center, vertex))
        obj.append(cgo.END)
        cmd.load_cgo(obj, cmd.get_unused_name('planeFit'))

    return center, vec
Ejemplo n.º 11
0
def cgo_arrow(atom1='pk1', atom2='pk2', radius=0.07, gap=0.0, hlength=-1, hradius=-1, color='blue red', name=''):
    from chempy import cpv
    radius, gap = float(radius), float(gap)
    hlength, hradius = float(hlength), float(hradius)

    try:
        color1, color2 = color.split()
    except:
        color1 = color2 = color
    color1 = list(cmd.get_color_tuple(color1))
    color2 = list(cmd.get_color_tuple(color2))

    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)

    xyz1 = get_coord(atom1)
    xyz2 = get_coord(atom2)
    normal = cpv.normalize(cpv.sub(xyz1, xyz2))

    if hlength < 0:
        hlength = radius * 3.0
    if hradius < 0:
        hradius = hlength * 0.6

    if gap:
        diff = cpv.scale(normal, gap)
        xyz1 = cpv.sub(xyz1, diff)
        xyz2 = cpv.add(xyz2, diff)

    xyz3 = cpv.add(cpv.scale(normal, hlength), xyz2)

    obj = [cgo.CYLINDER] + xyz1 + xyz3 + [radius] + color1 + color2 +           [cgo.CONE] + xyz3 + xyz2 + [hradius, 0.0] + color2 + color2 +           [1.0, 0.0]
    return obj
Ejemplo n.º 12
0
 def __init__(self, p1, p2, radius, color1,
              color2=None, color3=None,
              hlength=None, hradius=None,
              hlength_scale=3.0, hradius_scale=0.6):
     if hlength is None:
         hlength = radius * hlength_scale
     if hradius is None:
         hradius = hlength * hradius_scale
     normal = cpv.normalize(cpv.sub(p1, p2))
     pM = cpv.add(cpv.scale(normal, hlength), p2)
     line = Cylinder(p1, pM, radius, color1, color2)
     cone = Cone(
         pM, p2, hradius, color2 or color1, radius2=0, color2=color3
     )
     self._primitive = (line + cone).primitive
Ejemplo n.º 13
0
def _cgo_arrow(position=(0., 0., 0),
               direction=(1., 0., 0.),
               length=1.,
               radius=.2,
               offset=0.,
               color='red'):
    '''
    Generate and return an arrow CGO from (position + offset * direction) to
    (position + ((length + offset) * direction)).
    '''
    if isinstance(color, str):
        color = list(pymol.cmd.get_color_tuple(color))

    hlength = radius * 2.5
    hradius = radius * 2.0

    normal = cpv.normalize(direction)
    xyz1 = cpv.add(position, cpv.scale(normal, offset))
    xyz2 = cpv.add(position, cpv.scale(normal, length + offset))
    xyz3 = cpv.add(xyz2, cpv.scale(normal, hlength))

    return [cgo.CYLINDER] + xyz1 + xyz2 + [radius] + color + color + \
           [cgo.CONE] + xyz2 + xyz3 + [hradius, 0.0] + color + color + \
           [1.0, 0.0]
Ejemplo n.º 14
0
Archivo: cgo.py Proyecto: Almad/pymol
 def append_cyl(self):
     if self.l_vert and self.c_colr and self.l_radi:
         if self.tri_flag:
             self.tri_flag=0
             self.obj.append(END)
         self.obj.append(SAUSAGE)
         d = cpv.sub(self.l_vert[1],self.l_vert[0])
         d = cpv.normalize_failsafe(d)
         d0 = cpv.scale(d,self.l_radi/4.0)
         self.obj.extend(cpv.add(self.l_vert[0],d0))
         self.obj.extend(cpv.sub(self.l_vert[1],d0))
         self.obj.append(self.l_radi)
         self.obj.extend(self.c_colr[0])
         self.obj.extend(self.c_colr[1])
     self.l_vert=None
     self.c_colr=None
     self.l_radi=None
Ejemplo n.º 15
0
 def append_cyl(self):
     if self.l_vert and self.c_colr and self.l_radi:
         if self.tri_flag:
             self.tri_flag=0
             self.obj.append(END)
         self.obj.append(SAUSAGE)
         d = cpv.sub(self.l_vert[1],self.l_vert[0])
         d = cpv.normalize_failsafe(d)
         d0 = cpv.scale(d,self.l_radi/4.0)
         self.obj.extend(cpv.add(self.l_vert[0],d0))
         self.obj.extend(cpv.sub(self.l_vert[1],d0))
         self.obj.append(self.l_radi)
         self.obj.extend(self.c_colr[0])
         self.obj.extend(self.c_colr[1])
     self.l_vert=None
     self.c_colr=None
     self.l_radi=None
Ejemplo n.º 16
0
def loop_orientation(selection, state=STATE, visualize=1, quiet=1):
    '''
DESCRIPTION

    Get the center and approximate direction of a peptide. Works for any
    secondary structure.
    Averages direction of N(i)->C(i) pseudo bonds.

USAGE

    loop_orientation selection [, visualize ]

SEE ALSO

    helix_orientation
    '''
    state, visualize, quiet = int(state), int(visualize), int(quiet)

    coords = dict()
    cmd.iterate_state(state,
                      '(%s) and name N+C' % (selection),
                      'coords.setdefault(chain + resi, {})[name] = x,y,z',
                      space=locals())

    vec = cpv.get_null()
    center = cpv.get_null()

    count = 0
    for x in coords.values():
        if 'C' in x and 'N' in x:
            vec = cpv.add(vec, cpv.sub(x['C'], x['N']))
        for coord in x.values():
            center = cpv.add(center, coord)
            count += 1

    if count == 0:
        print('warning: count == 0')
        raise CmdException

    vec = cpv.normalize(vec)
    center = cpv.scale(center, 1. / count)

    _common_orientation(selection, center, vec, visualize, 2.0 * len(coords),
                        quiet)
    return center, vec
def _common_orientation(selection, vec, visualize=1, quiet=0):
    """
    Common part of different helix orientation functions. Does calculate
    the center of mass and does the visual feedback.
    """
    stored.x = []
    cmd.iterate_state(STATE, "(%s) and name CA" % (selection), "stored.x.append([x,y,z])")
    if len(stored.x) < 2:
        print("warning: count(CA) < 2")
        raise CmdException
    center = cpv.scale(_vec_sum(stored.x), 1.0 / len(stored.x))
    if visualize:
        scale = cpv.distance(stored.x[0], stored.x[-1])
        visualize_orientation(vec, center, scale, True)
        cmd.zoom(selection, buffer=2)
    if not quiet:
        print("Center: (%.2f, %.2f, %.2f) Direction: (%.2f, %.2f, %.2f)" % tuple(center + vec))
    return center, vec
Ejemplo n.º 18
0
def COM(selection='all', center=0, quiet=1):

    model = cmd.get_model(selection)
    nAtom = len(model.atom)

    COM = cpv.get_null()

    for a in model.atom:
        COM = cpv.add(COM, a.coord)
    COM = cpv.scale(COM, 1. / nAtom)

    if not int(quiet):
        print ' COM: [%8.3f,%8.3f,%8.3f]' % tuple(COM)

    if int(center):
        cmd.alter_state(1, selection, "(x,y,z)=sub((x,y,z), COM)",
                        space={'COM': COM, 'sub': cpv.sub})

    return COM
Ejemplo n.º 19
0
def _common_orientation(selection, vec, visualize=1, quiet=0):
    '''
    Common part of different helix orientation functions. Does calculate
    the center of mass and does the visual feedback.
    '''
    stored.x = []
    cmd.iterate_state(STATE, '(%s) and name CA' % (selection),
                      'stored.x.append([x,y,z])')
    if len(stored.x) < 2:
        print('warning: count(CA) < 2')
        raise CmdException
    center = cpv.scale(_vec_sum(stored.x), 1. / len(stored.x))
    if visualize:
        scale = cpv.distance(stored.x[0], stored.x[-1])
        visualize_orientation(vec, center, scale, True)
        cmd.zoom(selection, buffer=2)
    if not quiet:
        print('Center: (%.2f, %.2f, %.2f) Direction: (%.2f, %.2f, %.2f)' % tuple(center + vec))
    return center, vec
Ejemplo n.º 20
0
def centroid(selection='all', center=0, quiet=1):

    model = cmd.get_model(selection)
    nAtom = len(model.atom)

    centroid = cpv.get_null()

    for a in model.atom:
        centroid = cpv.add(centroid, a.coord)
    centroid = cpv.scale(centroid, 1. / nAtom)

    if not int(quiet):
        print ' centroid: [%8.3f,%8.3f,%8.3f]' % tuple(centroid)

    if int(move):
        cmd.alter_state(1, selection, "(x,y,z)=sub((x,y,z), centroid)",
                        space={'centroid': centroid, 'sub': cpv.sub})

    return centroid
Ejemplo n.º 21
0
def COM(selection='all', center=0, quiet=1):

        model = cmd.get_model(selection)
        nAtom = len(model.atom)
 
        COM = cpv.get_null()
 
        for a in model.atom:
                COM = cpv.add(COM, a.coord)
        COM = cpv.scale(COM, 1./nAtom)
 
        if not int(quiet):
                print ' COM: [%8.3f,%8.3f,%8.3f]' % tuple(COM)
 
        if int(center):
                cmd.alter_state(1, selection, "(x,y,z)=sub((x,y,z), COM)",
                        space={'COM': COM, 'sub': cpv.sub})
 
        return COM
Ejemplo n.º 22
0
def loop_orientation(selection, state=STATE, visualize=1, quiet=1):
    '''
DESCRIPTION

    Get the center and approximate direction of a peptide. Works for any
    secondary structure.
    Averages direction of N(i)->C(i) pseudo bonds.

USAGE

    loop_orientation selection [, visualize ]

SEE ALSO

    helix_orientation
    '''
    state, visualize, quiet = int(state), int(visualize), int(quiet)

    coords = dict()
    cmd.iterate_state(state, '(%s) and name N+C' % (selection),
            'coords.setdefault(chain + resi, {})[name] = x,y,z', space=locals())

    vec = cpv.get_null()
    center = cpv.get_null()

    count = 0
    for x in coords.itervalues():
        if 'C' in x and 'N' in x:
            vec = cpv.add(vec, cpv.sub(x['C'], x['N']))
        for coord in x.itervalues():
            center = cpv.add(center, coord)
            count += 1

    if count == 0:
        print 'warning: count == 0'
        raise CmdException

    vec = cpv.normalize(vec)
    center = cpv.scale(center, 1./count)

    _common_orientation(selection, center, vec, visualize, 2.0*len(coords), quiet)
    return center, vec
Ejemplo n.º 23
0
Archivo: cgo08.py Proyecto: Almad/pymol
def random_conic(box, size, min_axis):

    # return a random ellipsoid record of the form:
    # [ ELLIPSOID, x_pos, y_pos, z_pos, size, x0, y0, z0, x1, y1, z2, x2, y2, z2 ]
    # where the xyz vectors are orthogonal and of length 1.0 or less.
    
    box = box - size
    tmp0 = [ size + random() * box, size + random() * box, size + random() * box ]
    tmp1 = cpv.random_vector()
    tmp2 = cpv.scale(tmp1,box/10)
    tmp1 = cpv.add(tmp2,tmp0)
    
    return [ CONE,
             tmp0[0], tmp0[1], tmp0[2], # coordinates 
             tmp1[0], tmp1[1], tmp1[2],
             (abs(random())*0.4+0.2) * size, # radii
             (abs(random())*0.1+0.01) * size,
             random(), random(), random(), # colors
             random(), random(), random(),
             1.0, 1.0 ]
Ejemplo n.º 24
0
    def append_tri(self):
        if self.l_vert:
            d0 = cpv.sub(self.l_vert[0],self.l_vert[1])
            d1 = cpv.sub(self.l_vert[0],self.l_vert[2])
            n0 = cpv.cross_product(d0,d1)
            n0 = cpv.normalize_failsafe(n0)

            if not self.tri_flag:
                self.obj.append(BEGIN)
                self.obj.append(TRIANGLES)
                self.tri_flag = 1

            indices = [0, 1, 2]

            if not self.l_norm:
                # TODO could simplify this if ray tracing would support
                # object-level two_sided_lighting. Duplicating the
                # face with an offset is a hack and produces visible
                # lines on edges.
                n1 = [-n0[0],-n0[1],-n0[2]]
                ns = cpv.scale(n0,0.002)
                indices = [0, 1, 2, 4, 3, 5]
                l_vert_offsetted =     [cpv.add(v, ns) for v in self.l_vert]
                l_vert_offsetted.extend(cpv.sub(v, ns) for v in self.l_vert)
                self.l_vert = l_vert_offsetted
                self.l_norm = [n0, n0, n0, n1, n1, n1]
            elif cpv.dot_product(self.l_norm[0], n0) < 0:
                indices = [0, 2, 1]

            for i in indices:
                self.obj.append(COLOR) # assuming unicolor
                self.obj.extend(self.t_colr[i % 3])
                self.obj.append(NORMAL)
                self.obj.extend(self.l_norm[i])
                self.obj.append(VERTEX)
                self.obj.extend(self.l_vert[i])

        self.l_vert=None
        self.t_colr=None
        self.l_norm=None
Ejemplo n.º 25
0
    def append_tri(self):
        if self.l_vert:
            d0 = cpv.sub(self.l_vert[0],self.l_vert[1])
            d1 = cpv.sub(self.l_vert[0],self.l_vert[2])
            n0 = cpv.cross_product(d0,d1)
            n0 = cpv.normalize_failsafe(n0)

            if not self.tri_flag:
                self.obj.append(BEGIN)
                self.obj.append(TRIANGLES)
                self.tri_flag = 1

            indices = [0, 1, 2]

            if not self.l_norm:
                # TODO could simplify this if ray tracing would support
                # object-level two_sided_lighting. Duplicating the
                # face with an offset is a hack and produces visible
                # lines on edges.
                n1 = [-n0[0],-n0[1],-n0[2]]
                ns = cpv.scale(n0,0.002)
                indices = [0, 1, 2, 4, 3, 5]
                l_vert_offsetted =     [cpv.add(v, ns) for v in self.l_vert]
                l_vert_offsetted.extend(cpv.sub(v, ns) for v in self.l_vert)
                self.l_vert = l_vert_offsetted
                self.l_norm = [n0, n0, n0, n1, n1, n1]
            elif cpv.dot_product(self.l_norm[0], n0) < 0:
                indices = [0, 2, 1]

            for i in indices:
                self.obj.append(COLOR) # assuming unicolor
                self.obj.extend(self.t_colr[i % 3])
                self.obj.append(NORMAL)
                self.obj.extend(self.l_norm[i])
                self.obj.append(VERTEX)
                self.obj.extend(self.l_vert[i])

        self.l_vert=None
        self.t_colr=None
        self.l_norm=None
Ejemplo n.º 26
0
def find_center_of_mass(selection='(all)', state=-1):
    """
    Find center of mass of the selection and return the value

    USAGE

        find_center_of_mass selection
        find_center_of_mass selection, state=state

    ARGUMENTS

        selection   a selection-expression
        state       a state index if positive int, 0 to all, or -1 to current

    """
    state = utils.int_to_state(state)
    model = cmd.get_model(selection, state=state)
    com = cpv.get_null()
    # iterate all atoms and add vectors of center of mass of each atoms
    for atom in model.atom:
        com = cpv.add(com, atom.coord)
    com = cpv.scale(com, 1.0 / len(model.atom))
    return com
Ejemplo n.º 27
0
def find_center_of_mass(selection='(all)', state=-1):
    """
    Find center of mass of the selection and return the value

    USAGE

        find_center_of_mass selection
        find_center_of_mass selection, state=state

    ARGUMENTS

        selection   a selection-expression
        state       a state index if positive int, 0 to all, or -1 to current

    """
    state = utils.int_to_state(state)
    model = cmd.get_model(selection, state=state)
    com = cpv.get_null()
    # iterate all atoms and add vectors of center of mass of each atoms
    for atom in model.atom:
        com = cpv.add(com, atom.coord)
    com = cpv.scale(com, 1.0 / len(model.atom))
    return com
Ejemplo n.º 28
0
    def compute_surface_normals():
        '''
        Compute average normals from all adjacent triangles
        on each vertex
        '''
        from functools import reduce

        # don't use cpv.normalize which has an RSMALL4 limit
        normalize = lambda v: cpv.scale(v, 1. / cpv.length(v))

        for face in table['face']:
            if 'vertex_index' in face:
                indices = face['vertex_index']
            elif 'vertex_indices' in face:
                indices = face['vertex_indices']
            else:
                return

            f_vert = [vertices[i] for i in indices]
            f_xyz = [(v['x'], v['y'], v['z']) for v in f_vert]

            try:
                normal = normalize(cpv.cross_product(
                    cpv.sub(f_xyz[1], f_xyz[0]),
                    cpv.sub(f_xyz[2], f_xyz[1])))
            except ZeroDivisionError:
                continue

            for v in f_vert:
                v.setdefault('normals', []).append(normal)

        for v in vertices:
            try:
                v['nx'], v['ny'], v['nz'] = normalize(
                        reduce(cpv.add, v.pop('normals')))
            except (KeyError, ZeroDivisionError):
                continue
Ejemplo n.º 29
0
    def compute_surface_normals():
        '''
        Compute average normals from all adjacent triangles
        on each vertex
        '''
        from functools import reduce

        # don't use cpv.normalize which has an RSMALL4 limit
        normalize = lambda v: cpv.scale(v, 1. / cpv.length(v))

        for face in table['face']:
            if 'vertex_index' in face:
                indices = face['vertex_index']
            elif 'vertex_indices' in face:
                indices = face['vertex_indices']
            else:
                return

            f_vert = [vertices[i] for i in indices]
            f_xyz = [(v['x'], v['y'], v['z']) for v in f_vert]

            try:
                normal = normalize(cpv.cross_product(
                    cpv.sub(f_xyz[1], f_xyz[0]),
                    cpv.sub(f_xyz[2], f_xyz[1])))
            except ZeroDivisionError:
                continue

            for v in f_vert:
                v.setdefault('normals', []).append(normal)

        for v in vertices:
            try:
                v['nx'], v['ny'], v['nz'] = normalize(
                        reduce(cpv.add, v.pop('normals')))
            except (KeyError, ZeroDivisionError):
                continue
Ejemplo n.º 30
0
def centroid(selection='all', center=0, quiet=1):

    model = cmd.get_model(selection)
    nAtom = len(model.atom)

    centroid = cpv.get_null()

    for a in model.atom:
        centroid = cpv.add(centroid, a.coord)
    centroid = cpv.scale(centroid, 1. / nAtom)

    if not int(quiet):
        print(' centroid: [%8.3f,%8.3f,%8.3f]' % tuple(centroid))

    if int(center):
        cmd.alter_state(1,
                        selection,
                        "(x,y,z)=sub((x,y,z), centroid)",
                        space={
                            'centroid': centroid,
                            'sub': cpv.sub
                        })

    return centroid
Ejemplo n.º 31
0
def helix_orientation(selection,
                      state=STATE,
                      visualize=1,
                      cutoff=3.5,
                      quiet=1):
    '''
DESCRIPTION

    Get the center and direction of a helix as vectors. Will only work
    for alpha helices and gives slightly different results than
    cafit_orientation. Averages direction of C(i)->O(i)->N(i+4).

USAGE

    helix_orientation selection [, visualize [, cutoff ]]

ARGUMENTS

    selection = string: atom selection of helix

    visualize = 0 or 1: show fitted vector as arrow {default: 1}

    cutoff = float: maximal hydrogen bond distance {default: 3.5}

SEE ALSO

    angle_between_helices, loop_orientation, cafit_orientation
    '''
    state, visualize, quiet = int(state), int(visualize), int(quiet)
    cutoff = float(cutoff)

    atoms = {'C': dict(), 'O': dict(), 'N': dict()}
    cmd.iterate_state(state,
                      '(%s) and name N+O+C' % (selection),
                      'atoms[name][resv] = x,y,z',
                      space={'atoms': atoms})

    vec_list = []
    for resi in atoms['C']:
        resi_other = resi + 4
        try:
            aC = atoms['C'][resi]
            aO = atoms['O'][resi]
            aN = atoms['N'][resi_other]
        except KeyError:
            continue

        dist = cpv.distance(aN, aO)
        dist_weight = 1. - (2.8 - dist)
        angle = cpv.get_angle_formed_by(aC, aO, aN)
        angle_weight = 1. - (3.1 - angle)

        if dist_weight > 0.0 and angle_weight > 0.0:
            if not quiet:
                print(' weight:', angle_weight * dist_weight)
            vec = cpv.scale(cpv.sub(aN, aC), angle_weight * dist_weight)
            vec_list.append(vec)

    if len(vec_list) == 0:
        print('warning: count == 0')
        raise CmdException

    center = cpv.scale(_vec_sum(atoms['O'].values()), 1. / len(atoms['O']))
    vec = _vec_sum(vec_list)
    vec = cpv.normalize(vec)

    _common_orientation(selection, center, vec, visualize, 1.5 * len(vec_list),
                        quiet)
    return center, vec
Ejemplo n.º 32
0
Archivo: cgo.py Proyecto: Almad/pymol
    def append_tri(self):
        if self.l_vert and not self.l_norm:
            d0 = cpv.sub(self.l_vert[0],self.l_vert[1])
            d1 = cpv.sub(self.l_vert[0],self.l_vert[2])
            n0 = cpv.cross_product(d0,d1)
            n0 = cpv.normalize_failsafe(n0)
            n1 = [-n0[0],-n0[1],-n0[2]]
            ns = cpv.scale(n0,0.002)
            if not self.tri_flag:
                self.obj.append(BEGIN)
                self.obj.append(TRIANGLES)
                self.tri_flag = 1
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[0])
            self.obj.append(NORMAL)
            self.obj.extend(n0)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.add(self.l_vert[0],ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[1])
            self.obj.append(NORMAL)
            self.obj.extend(n0)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.add(self.l_vert[1],ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[2])
            self.obj.append(NORMAL)
            self.obj.extend(n0)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.add(self.l_vert[2],ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[0])
            self.obj.append(NORMAL)
            self.obj.extend(n1)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.sub(self.l_vert[0],ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[1])
            self.obj.append(NORMAL)
            self.obj.extend(n1)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.sub(self.l_vert[1],ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[2])
            self.obj.append(NORMAL)
            self.obj.extend(n1)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.sub(self.l_vert[2],ns))

        elif self.l_vert and self.t_colr and self.l_norm:
            if not self.tri_flag:
                self.obj.append(BEGIN)
                self.obj.append(TRIANGLES)
                self.tri_flag = 1
            self.obj.append(COLOR) # assuming unicolor
            self.obj.extend(self.t_colr[0])
            self.obj.append(NORMAL)
            self.obj.extend(self.l_norm[0])
            self.obj.append(VERTEX)
            self.obj.extend(self.l_vert[0])
            self.obj.append(COLOR) # assuming unicolor
            self.obj.extend(self.t_colr[1])
            self.obj.append(NORMAL)
            self.obj.extend(self.l_norm[1])
            self.obj.append(VERTEX)
            self.obj.extend(self.l_vert[1])
            self.obj.append(COLOR) # assuming unicolor
            self.obj.extend(self.t_colr[2])
            self.obj.append(NORMAL)
            self.obj.extend(self.l_norm[2])
            self.obj.append(VERTEX)
            self.obj.extend(self.l_vert[2])
        self.l_vert=None
        self.t_colr=None
        self.l_norm=None
Ejemplo n.º 33
0
def cgo_arrow(atom1='pk1',
              atom2='pk2',
              radius=0.5,
              gap=0.0,
              hlength=-1,
              hradius=-1,
              color='blue red',
              name=''):
    '''
DESCRIPTION

  Create a CGO arrow between two picked atoms.

ARGUMENTS

  atom1 = string: single atom selection or list of 3 floats {default: pk1}

  atom2 = string: single atom selection or list of 3 floats {default: pk2}

  radius = float: arrow radius {default: 0.5}

  gap = float: gap between arrow tips and the two atoms {default: 0.0}

  hlength = float: length of head

  hradius = float: radius of head

  color = string: one or two color names {default: blue red}

  name = string: name of CGO object
  '''
    from chempy import cpv

    radius, gap = float(radius), float(gap)
    hlength, hradius = float(hlength), float(hradius)

    try:
        color1, color2 = color.split()
    except:
        color1 = color2 = color
    color1 = list(cmd.get_color_tuple(color1))
    color2 = list(cmd.get_color_tuple(color2))

    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)

    xyz1 = get_coord(atom1)
    xyz2 = get_coord(atom2)
    normal = cpv.normalize(cpv.sub(xyz1, xyz2))

    if hlength < 0:
        hlength = radius * 3.0
    if hradius < 0:
        hradius = hlength * 0.6

    if gap:
        diff = cpv.scale(normal, gap)
        xyz1 = cpv.sub(xyz1, diff)
        xyz2 = cpv.add(xyz2, diff)

    xyz3 = cpv.add(cpv.scale(normal, hlength), xyz2)

    obj = [cgo.CYLINDER] + xyz1 + xyz3 + [radius] + color1 + color2 + \
       [cgo.CONE] + xyz3 + xyz2 + [hradius, 0.0] + color2 + color2 + \
       [1.0, 0.0]
    #obj = [cgo.CYLINDER] + xyz1 + xyz3 + [radius] + color1 + color2 + \
    #[cgo.CONE] + xyz3 + xyz2 + [hradius, 0.0] + color2 + color2 + \
    #[1.0, 0.0]

    if not name:
        name = cmd.get_unused_name('arrow')

    cmd.load_cgo(obj, name)
Ejemplo n.º 34
0
    def drawmol(self,model):
        print 'drawmol'
        self.sphere_list= glGenLists(1)
        glNewList(self.sphere_list, GL_COMPILE)
        print 'making sphere list of ', len(model.atom),' atoms'
        for a in model.atom:
            try:
                z = a.get_number()
            except Exception:
                z = 0
            r,g,b = colours[z]

            glColor3f(r,g,b)
            glPushMatrix()
            x = a.coord[0]
            y = a.coord[1]
            zz = a.coord[2]
            glTranslatef (x, y, zz)
            fac = rcov[z] / 2.0
            glScale(fac,fac,fac)
            glutSolidSphere(0.4, 16, 16)
            glPopMatrix()
        glEndList()

        self.line_list= glGenLists(1)
        glNewList(self.line_list, GL_COMPILE)
        glLineWidth(2.0)
        glBegin(GL_LINES)
        line_count = 0
        for a in model.atom:
            try:
                c = a.conn
            except AttributeError:
                c = []
            for t in c:
                if t.get_index() > a.get_index():

                    line_count = line_count + 1
                    vec = cpv.sub(t.coord, a.coord)
                    mid = cpv.add(a.coord,cpv.scale(vec,0.5))

                    try:
                        z = a.get_number()
                    except Exception:
                        z = 0

                    r,g,b = colours[z]
                    glColor3f(r, g, b)
                    glVertex3f(a.coord[0],a.coord[1],a.coord[2])
                    glVertex3f(mid[0],mid[1],mid[2])

                    try:
                        z = t.get_number()
                    except Exception:
                        z = 0

                    r,g,b = colours[z]
                    glColor3f(r, g, b)
                    glVertex3f(mid[0],mid[1],mid[2])
                    glVertex3f(t.coord[0],t.coord[1],t.coord[2])

        glEnd()
        glEndList()
        print 'made line list of ', line_count, ' lines'
Ejemplo n.º 35
0
def visualize_orientation(direction,
                          center=[0.0] * 3,
                          scale=1.0,
                          symmetric=False,
                          color='green',
                          color2='red',
                          *,
                          _self=cmd):
    '''
DESCRIPTION

    Draw an arrow. Helper function for "helix_orientation" etc.
    '''
    from pymol import cgo

    color_list = _self.get_color_tuple(color)
    color2_list = _self.get_color_tuple(color2)

    if symmetric:
        scale *= 0.5
    end = cpv.add(center, cpv.scale(direction, scale))
    radius = 0.3

    obj = [cgo.SAUSAGE]
    obj.extend(center)
    obj.extend(end)
    obj.extend([
        radius,
        0.8,
        0.8,
        0.8,
    ])
    obj.extend(color_list)

    if symmetric:
        start = cpv.sub(center, cpv.scale(direction, scale))
        obj.append(cgo.SAUSAGE)
        obj.extend(center)
        obj.extend(start)
        obj.extend([
            radius,
            0.8,
            0.8,
            0.8,
        ])
        obj.extend(color2_list)

    coneend = cpv.add(
        end, cpv.scale(direction, 4.0 * radius / cpv.length(direction)))
    obj.append(cgo.CONE)
    obj.extend(end)
    obj.extend(coneend)
    obj.extend([
        radius * 1.75,
        0.0,
    ])
    obj.extend(color_list * 2)
    obj.extend([
        1.0,
        1.0,  # Caps
    ])
    _self.load_cgo(obj, _self.get_unused_name('oriVec'), zoom=0)
Ejemplo n.º 36
0
def helix_orientation(selection, state=STATE, visualize=1, cutoff=3.5, quiet=1):
    '''
DESCRIPTION

    Get the center and direction of a helix as vectors. Will only work
    for alpha helices and gives slightly different results than
    cafit_orientation. Averages direction of C(i)->O(i)->N(i+4).

USAGE

    helix_orientation selection [, visualize [, cutoff ]]

ARGUMENTS

    selection = string: atom selection of helix

    visualize = 0 or 1: show fitted vector as arrow {default: 1}

    cutoff = float: maximal hydrogen bond distance {default: 3.5}

SEE ALSO

    angle_between_helices, loop_orientation, cafit_orientation
    '''
    state, visualize, quiet = int(state), int(visualize), int(quiet)
    cutoff = float(cutoff)

    atoms = {'C': dict(), 'O': dict(), 'N': dict()}
    cmd.iterate_state(state, '(%s) and name N+O+C' % (selection),
            'atoms[name][resv] = x,y,z', space={'atoms': atoms})

    vec_list = []
    for resi in atoms['C']:
        resi_other = resi + 4
        try:
            aC = atoms['C'][resi]
            aO = atoms['O'][resi]
            aN = atoms['N'][resi_other]
        except KeyError:
            continue

        dist = cpv.distance(aN, aO)
        dist_weight = 1. - (2.8 - dist)
        angle = cpv.get_angle_formed_by(aC, aO, aN)
        angle_weight = 1. - (3.1 - angle)

        if dist_weight > 0.0 and angle_weight > 0.0:
            if not quiet:
                print ' weight:', angle_weight * dist_weight
            vec = cpv.scale(cpv.sub(aN, aC), angle_weight * dist_weight)
            vec_list.append(vec)

    if len(vec_list) == 0:
        print 'warning: count == 0'
        raise CmdException

    center = cpv.scale(_vec_sum(atoms['O'].itervalues()), 1./len(atoms['O']))
    vec = _vec_sum(vec_list)
    vec = cpv.normalize(vec)

    _common_orientation(selection, center, vec, visualize, 1.5*len(vec_list), quiet)
    return center, vec
Ejemplo n.º 37
0
def cgo_modevec(atom1='pk1', atom2='pk2', radius=0.05, gap=0.0, hlength=-1, hradius=-1,
              color='green', name='',scalefactor=10.0, cutoff=0.6, transparency=1.0): #was 0.6cut 12 scale
## scalefactor was 10.0 
    '''
DESCRIPTION

    Create a CGO mode vector starting at atom1 and pointint in atom2 displacement

ARGUMENTS

    atom1 = string: single atom selection or list of 3 floats {default: pk1}

    atom2 = string: displacement to atom1 for modevec

    radius = float: arrow radius {default: 0.5}

    gap = float: gap between arrow tips and the two atoms {default: 0.0}

    hlength = float: length of head

    hradius = float: radius of head

    color = string: one or two color names {default: blue red}

    name = string: name of CGO object
    
    scalefactor = scale how big of an arrow to make. Default 5

    transparency = 0.0 ~ 1.0, default=1.0 means being totally opaque
    '''
    from chempy import cpv

    radius, gap = float(radius), float(gap)
    hlength, hradius = float(hlength), float(hradius)
    scalefactor, cutoff = float(scalefactor), float(cutoff)
    transparency = float(transparency)
    try:
        color1, color2 = color.split()
    except:
        color1 = color2 = color
    color1 = list(cmd.get_color_tuple(color1))
    color2 = list(cmd.get_color_tuple(color2))

    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)

    xyz1 = get_coord(atom1)
    xyz2 = get_coord(atom2)
    newxyz2 = cpv.scale(xyz2, scalefactor)
    newxyz2 = cpv.add(newxyz2, xyz1)
    xyz2 = newxyz2
#    xyz2 = xyz2[0]*scalefactor, xyz2[1]*scalefactor, xyz2[2]*scalefactor
    normal = cpv.normalize(cpv.sub(xyz1, xyz2))

    if hlength < 0:
        hlength = radius * 3.0
    if hradius < 0:
        hradius = hlength * 0.6

    if gap:
        diff = cpv.scale(normal, gap)
        xyz1 = cpv.sub(xyz1, diff)
        xyz2 = cpv.add(xyz2, diff)

    xyz3 = cpv.add(cpv.scale(normal, hlength), xyz2)

# dont draw arrow if distance is too small
    distance = cpv.distance(xyz1, xyz2)
    if distance <= cutoff:
        return

#### generate transparent arrows; 
#### The original codes are the next block
####  --Ran
    obj = [25.0, transparency, 9.0] + xyz1 + xyz3 + [radius] + color1 + color2 + \
          [25.0, transparency, 27.0] + xyz3 + xyz2 + [hradius, 0.0] + color2 + color2 + \
          [1.0, 0.0]

#    obj = [cgo.CYLINDER] + xyz1 + xyz3 + [radius] + color1 + color2 + \
#          [cgo.CONE] + xyz3 + xyz2 + [hradius, 0.0] + color2 + color2 + \
#          [1.0, 0.0]

    if not name:
        name = cmd.get_unused_name('arrow')

    cmd.load_cgo(obj, name)
Ejemplo n.º 38
0
def obscure(selection, hiding="medium", keep=0, state=-1, name_map='', name_iso='', quiet=0, _self=cmd):
    """
DESCRIPTION

    Given an object or selection, usually a small molecule, obscure it
    to protect its exact identity.

USAGE

    obscure selection [, hiding [, keep ]]

ARGUMENTS

    selection = str: atom selection to hide

    hiding = low|medium|high: level to which PyMOL obscures the object {default: medium}

    keep = 0/1: by default, PyMOL removes the obscured atoms from your file,
    this flag will keep the atoms in the file.  Be careful!

NOTES

    Large molecules are very slow.
    """
    from chempy.cpv import add, scale, random_vector

    keep = bool(keep) if not keep else int(keep)
    quiet = int(quiet)

    hiding = hiding_sc.auto_err(hiding, 'hiding level')
    hiding = ['low', 'medium', 'high'].index(hiding)

    # these parameters are fine-tuned for a good visual experience
    resolution, grid, level = [
        [2.00, 0.18, 2.00], # low
        [3.75, 0.25, 2.50], # medium
        [4.00, 0.33, 2.00], # high
    ][hiding]

    # detect if we're hiding a subset of a molecule, then add one bond, so ensure that what sticks out looks good
    tmp_sele = _self.get_unused_name("_target")
    natoms = _self.select(tmp_sele,  "(%s) extend 1" % (selection), 0)

    if not quiet:
        print(' Obscuring %d atoms' % natoms)

    # get a new name for the map/surf
    if not name_map:
        name_map = _self.get_unused_name("obsc_map")
    if not name_iso:
        name_iso = _self.get_unused_name("obsc_surf")

    if not keep:
        # randomize the coordinates
        _self.alter_state(state, tmp_sele, "(x,y,z)=perturb([x,y,z])", space={'perturb':
            lambda v: add(v, scale(random_vector(), 0.4))})

        # clear out charge and b-factor
        _self.alter(tmp_sele, "(b,q) = (10.0, 1.0)")

    # make the gaussian map and draw its surface
    _self.map_new(name_map, "gaussian", grid, tmp_sele, resolution=resolution, quiet=quiet)
    _self.isosurface(name_iso, name_map, level, quiet=quiet)

    if not keep:
        if natoms == _self.count_atoms('byobject (%s)' % (tmp_sele)):
            names = ' '.join(_self.get_object_list('(%s)' % (selection)))
            if not quiet:
                print(' Deleting object:', names)
            _self.delete(names)
        else:
            _self.remove(selection, quiet=quiet)

    _self.delete(tmp_sele)
Ejemplo n.º 39
0
def sidechaincenters(object='scc', selection='all', method='bahar1996', name='PS1', *, _self=cmd):
    '''
DESCRIPTION

    Creates an object with sidechain representing pseudoatoms for each residue
    in selection.

    Two methods are available:
    (1) Sidechain interaction centers as defined by Bahar and Jernigan 1996
        http://www.ncbi.nlm.nih.gov/pubmed/9080182
    (2) Sidechain centroids, the pseudoatom is the centroid of all atoms except
        hydrogens and backbone atoms (N, C and O).

NOTE

    With method "bahar1996", if a residue has all relevant sidechain center
    atoms missing (for example a MET without SD), it will be missing in the
    created pseudoatom object.

    With method "centroid", if you want to exclude C-alpha atoms from
    sidechains, modify the selection like in this example:

    sidechaincenters newobject, all and (not name CA or resn GLY), method=2

USAGE

    sidechaincenters object [, selection [, method ]]

ARGUMENTS

    object = string: name of object to create

    selection = string: atoms to consider {default: (all)}

    method = string: bahar1996 or centroid {default: bahar1996}

    name = string: atom name of pseudoatoms {default: PS1}

SEE ALSO

    pseudoatom
    '''
    from chempy import Atom, cpv, models

    atmap = dict()
    if method in ['bahar1996', '1', 1]:
        modelAll = _self.get_model('(%s) and resn %s' % (selection, '+'.join(sidechaincenteratoms)))
        for at in modelAll.atom:
            if at.name in sidechaincenteratoms[at.resn]:
                atmap.setdefault((at.segi, at.chain, at.resn, at.resi), []).append(at)
    elif method in ['centroid', '2', 2]:
        modelAll = _self.get_model('(%s) and polymer and not (hydro or name C+N+O)' % selection)
        for at in modelAll.atom:
            atmap.setdefault((at.segi, at.chain, at.resn, at.resi), []).append(at)
    else:
        raise CmdException('unknown method: {}'.format(method))

    model = models.Indexed()
    for centeratoms in atmap.values():
        center = cpv.get_null()
        for at in centeratoms:
            center = cpv.add(center, at.coord)
        center = cpv.scale(center, 1./len(centeratoms))
        atom = Atom()
        atom.coord = center
        atom.index = model.nAtom + 1
        atom.name = name
        for key in [
                'segi',
                'chain',
                'resi_number',
                'resi',
                'resn',
                'hetatm',
                'ss',
                'b',
        ]:
            setattr(atom, key, getattr(at, key))
        model.add_atom(atom)
    model.update_index()
    if object in _self.get_object_list():
        _self.delete(object)
    _self.load_model(model, object)
    return model
Ejemplo n.º 40
0
        normal = normalize(cross_product(x,y))
    else:
        (y,x) = basis[0:2]
        normal = normalize(cross_product(y,x))

    obj.extend( [BEGIN, TRIANGLE_STRIP] +
                [COLOR, 1.0, 1.0, 1.0] +
                [NORMAL] + normal )

    for i in range(sampling+1):
        x1 = edge
        y1 = edge*i/sampling
        vlen = sqrt(x1*x1+y1*y1)
        x0 = radius*x1/vlen
        y0 = radius*y1/vlen
        v0 = add( scale(x, x0 ), scale(y,y0) )
        v1 = add( scale(x, x1 ), scale(y,y1) )

        if hand:
            obj.extend( [ VERTEX ] + v0 + [ VERTEX ] + v1 )
        else:
            obj.extend( [ VERTEX ] + v1 + [ VERTEX ] + v0 )

    obj.extend( [END] )

# then we load it into PyMOL

cmd.load_cgo(obj,'cgo05')

# move the read clipping plane back a bit to that that is it brighter
Ejemplo n.º 41
0
                (y,x) = basis[0:2]
            else:
                (x,y) = basis[0:2]
            normal = normalize(cross_product(y,x))
                
        obj.extend( [BEGIN, TRIANGLE_STRIP] +
                    [COLOR, 1.0, 1.0, 1.0] +
                    [NORMAL] + normal )

        for i in range(sampling+1):
            x1 = edge
            y1 = edge*i/sampling
            vlen = sqrt(x1*x1+y1*y1)
            x0 = radius*x1/vlen
            y0 = radius*y1/vlen
            v0 = add( add( scale(x, x0 ), scale(y,y0) ), scale(normal,z1) )
            v1 = add( add( scale(x, x1 ), scale(y,y1) ), scale(normal,z1) )

            if hand:
                obj.extend( [ VERTEX ] + v0 + [ VERTEX ] + v1 )
            else:
                obj.extend( [ VERTEX ] + v1 + [ VERTEX ] + v0 )

        obj.extend( [END] )


        obj.extend( [BEGIN, TRIANGLE_STRIP] +
                    [COLOR, 1.0, 1.0, 1.0])

        for i in range(sampling+1):
            x1 = edge
Ejemplo n.º 42
0
    def append_tri(self):
        if self.l_vert and not self.l_norm:
            d0 = cpv.sub(self.l_vert[0], self.l_vert[1])
            d1 = cpv.sub(self.l_vert[0], self.l_vert[2])
            n0 = cpv.cross_product(d0, d1)
            n0 = cpv.normalize_failsafe(n0)
            n1 = [-n0[0], -n0[1], -n0[2]]
            ns = cpv.scale(n0, 0.002)
            if not self.tri_flag:
                self.obj.append(BEGIN)
                self.obj.append(TRIANGLES)
                self.tri_flag = 1
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[0])
            self.obj.append(NORMAL)
            self.obj.extend(n0)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.add(self.l_vert[0], ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[1])
            self.obj.append(NORMAL)
            self.obj.extend(n0)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.add(self.l_vert[1], ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[2])
            self.obj.append(NORMAL)
            self.obj.extend(n0)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.add(self.l_vert[2], ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[0])
            self.obj.append(NORMAL)
            self.obj.extend(n1)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.sub(self.l_vert[0], ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[1])
            self.obj.append(NORMAL)
            self.obj.extend(n1)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.sub(self.l_vert[1], ns))
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[2])
            self.obj.append(NORMAL)
            self.obj.extend(n1)
            self.obj.append(VERTEX)
            self.obj.extend(cpv.sub(self.l_vert[2], ns))

        elif self.l_vert and self.t_colr and self.l_norm:
            if not self.tri_flag:
                self.obj.append(BEGIN)
                self.obj.append(TRIANGLES)
                self.tri_flag = 1
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[0])
            self.obj.append(NORMAL)
            self.obj.extend(self.l_norm[0])
            self.obj.append(VERTEX)
            self.obj.extend(self.l_vert[0])
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[1])
            self.obj.append(NORMAL)
            self.obj.extend(self.l_norm[1])
            self.obj.append(VERTEX)
            self.obj.extend(self.l_vert[1])
            self.obj.append(COLOR)  # assuming unicolor
            self.obj.extend(self.t_colr[2])
            self.obj.append(NORMAL)
            self.obj.extend(self.l_norm[2])
            self.obj.append(VERTEX)
            self.obj.extend(self.l_vert[2])
        self.l_vert = None
        self.t_colr = None
        self.l_norm = None
Ejemplo n.º 43
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 = map(sum, zip(v, [-1, -1, -1]))
                v = 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
Ejemplo n.º 44
0
def angle_between_helices(selection1, selection2, method='helix',
        state1=STATE, state2=STATE, visualize=1, quiet=1):
    '''
DESCRIPTION

    Calculates the angle between two helices

USAGE

    angle_between_helices selection1, selection2 [, method [, visualize]]

ARGUMENTS

    selection1 = string: atom selection of first helix

    selection2 = string: atom selection of second helix

    method = string: function to calculate orientation {default: helix_orientation}

    visualize = 0 or 1: show fitted vector as arrow {default: 1}

EXAMPLE

    fetch 2x19, async=0
    select hel1, /2x19//B/23-36/
    select hel2, /2x19//B/40-54/
    angle_between_helices hel1, hel2
    angle_between_helices hel1, hel2, cafit

SEE ALSO

    helix_orientation, loop_orientation, cafit_orientation, angle_between_domains
    '''
    import math

    state1, state2 = int(state1), int(state2)
    visualize, quiet = int(visualize), int(quiet)

    try:
        orientation = globals()[methods_sc[str(method)]]
    except KeyError:
        print 'no such method:', method
        raise CmdException

    if not int(quiet):
        print ' Using method:', orientation.__name__

    cen1, dir1 = orientation(selection1, state1, visualize, quiet=1)
    cen2, dir2 = orientation(selection2, state2, visualize, quiet=1)

    angle = cpv.get_angle(dir1, dir2)
    angle = math.degrees(angle)

    if not quiet:
        print ' Angle: %.2f deg' % (angle)

    if visualize:
        # measurement object for angle
        center = cpv.scale(cpv.add(cen1, cen2), 0.5)
        tmp = get_unused_name('_')
        for pos in [center,
                cpv.add(center, cpv.scale(dir1, 5.0)),
                cpv.add(center, cpv.scale(dir2, 5.0))]:
            cmd.pseudoatom(tmp, pos=list(pos), state=1)
        name = get_unused_name('angle')
        cmd.angle(name, *[(tmp, i) for i in [2,1,3]])
        cmd.delete(tmp)

        cmd.zoom('(%s) or (%s)' % (selection1, selection2), 2,
                state1 if state1 == state2 else 0)

    return angle
Ejemplo n.º 45
0
def angle_between_domains(selection1,
                          selection2,
                          method='align',
                          state1=STATE,
                          state2=STATE,
                          visualize=1,
                          quiet=1):
    '''
DESCRIPTION

    Angle by which a molecular selection would be rotated when superposing
    on a selection2.

    Do not use for measuring angle between helices, since the alignment of
    the helices might involve a rotation around the helix axis, which will
    result in a larger angle compared to the angle between helix axes.

USAGE

    angle_between_domains selection1, selection2 [, method ]

ARGUMENTS

    selection1 = string: atom selection of first helix

    selection2 = string: atom selection of second helix

    method = string: alignment command like "align" or "super" {default: align}

EXAMPLE

    fetch 3iplA 3iplB, bsync=0
    select domain1, resi 1-391
    select domain2, resi 392-475
    align 3iplA and domain1, 3iplB and domain1
    angle_between_domains 3iplA and domain2, 3iplB and domain2

SEE ALSO

    align, super, angle_between_helices
    '''
    import math

    try:
        import numpy
    except ImportError:
        print(' Error: numpy not available')
        raise CmdException

    state1, state2 = int(state1), int(state2)
    visualize, quiet = int(visualize), int(quiet)

    if cmd.is_string(method):
        try:
            method = cmd.keyword[method][0]
        except KeyError:
            print('no such method:', method)
            raise CmdException

    mobile_tmp = get_unused_name('_')
    cmd.create(mobile_tmp, selection1, state1, 1, zoom=0)
    try:
        method(mobile=mobile_tmp,
               target=selection2,
               mobile_state=1,
               target_state=state2,
               quiet=quiet)
        mat = cmd.get_object_matrix(mobile_tmp)
    except:
        print(' Error: superposition with method "%s" failed' %
              (method.__name__))
        raise CmdException
    finally:
        cmd.delete(mobile_tmp)

    try:
        # Based on transformations.rotation_from_matrix
        # Copyright (c) 2006-2012, Christoph Gohlke

        R33 = [mat[i:i + 3] for i in [0, 4, 8]]
        R33 = numpy.array(R33, float)

        # direction: unit eigenvector of R33 corresponding to eigenvalue of 1
        w, W = numpy.linalg.eig(R33.T)
        i = w.real.argmax()
        direction = W[:, i].real

        # rotation angle depending on direction
        m = direction.argmax()
        i, j, k, l = [[2, 1, 1, 2], [0, 2, 0, 2], [1, 0, 0, 1]][m]
        cosa = (R33.trace() - 1.0) / 2.0
        sina = (R33[i, j] +
                (cosa - 1.0) * direction[k] * direction[l]) / direction[m]

        angle = math.atan2(sina, cosa)
        angle = abs(math.degrees(angle))
    except:
        print(' Error: rotation from matrix failed')
        raise CmdException

    if not quiet:
        try:
            # make this import optional to support running this script standalone
            from .querying import centerofmass, gyradius
        except (ValueError, ImportError):
            gyradius = None
            try:
                # PyMOL 1.7.1.6+
                centerofmass = cmd.centerofmass
            except AttributeError:
                centerofmass = lambda s: cpv.scale(cpv.add(*cmd.get_extent(s)),
                                                   0.5)

        center1 = centerofmass(selection1)
        center2 = centerofmass(selection2)
        print(' Angle: %.2f deg, Displacement: %.2f angstrom' %
              (angle, cpv.distance(center1, center2)))

        if visualize:
            center1 = numpy.array(center1, float)
            center2 = numpy.array(center2, float)
            center = (center1 + center2) / 2.0

            if gyradius is not None:
                rg = numpy.array(gyradius(selection1), float)
            else:
                rg = 10.0

            h1 = numpy.cross(center2 - center1, direction)
            h2 = numpy.dot(R33, h1)
            h1 *= rg / cpv.length(h1)
            h2 *= rg / cpv.length(h2)

            for pos in [center1, center2, center1 + h1, center1 + h2]:
                cmd.pseudoatom(mobile_tmp, pos=list(pos), state=1)

            # measurement object for angle and displacement
            name = get_unused_name('measurement')
            cmd.distance(name, *['%s`%d' % (mobile_tmp, i) for i in [1, 2]])
            cmd.angle(name, *['%s`%d' % (mobile_tmp, i) for i in [3, 1, 4]])

            # CGO arrow for axis of rotation
            visualize_orientation(direction, center1, rg, color='blue')

            cmd.delete(mobile_tmp)

    return angle
Ejemplo n.º 46
0
def angle_between_domains(selection1, selection2, method='align',
        state1=STATE, state2=STATE, visualize=1, quiet=1):
    '''
DESCRIPTION

    Angle by which a molecular selection would be rotated when superposing
    on a selection2.

    Do not use for measuring angle between helices, since the alignment of
    the helices might involve a rotation around the helix axis, which will
    result in a larger angle compared to the angle between helix axes.

USAGE

    angle_between_domains selection1, selection2 [, method ]

ARGUMENTS

    selection1 = string: atom selection of first helix

    selection2 = string: atom selection of second helix

    method = string: alignment command like "align" or "super" {default: align}

EXAMPLE

    fetch 3iplA 3iplB, async=0
    select domain1, resi 1-391
    select domain2, resi 392-475
    align 3iplA and domain1, 3iplB and domain1
    angle_between_domains 3iplA and domain2, 3iplB and domain2

SEE ALSO

    align, super, angle_between_helices
    '''
    import math

    try:
        import numpy
    except ImportError:
        print ' Error: numpy not available'
        raise CmdException

    state1, state2 = int(state1), int(state2)
    visualize, quiet = int(visualize), int(quiet)

    if cmd.is_string(method):
        try:
            method = cmd.keyword[method][0]
        except KeyError:
            print 'no such method:', method
            raise CmdException

    mobile_tmp = get_unused_name('_')
    cmd.create(mobile_tmp, selection1, state1, 1,  zoom=0)
    try:
        method(mobile=mobile_tmp, target=selection2, mobile_state=1,
                target_state=state2, quiet=quiet)
        mat = cmd.get_object_matrix(mobile_tmp)
    except:
        print ' Error: superposition with method "%s" failed' % (method.__name__)
        raise CmdException
    finally:
        cmd.delete(mobile_tmp)

    try:
        # Based on transformations.rotation_from_matrix
        # Copyright (c) 2006-2012, Christoph Gohlke

        R33 = [mat[i:i+3] for i in [0,4,8]]
        R33 = numpy.array(R33, float)

        # direction: unit eigenvector of R33 corresponding to eigenvalue of 1
        w, W = numpy.linalg.eig(R33.T)
        i = w.real.argmax()
        direction = W[:, i].real

        # rotation angle depending on direction
        m = direction.argmax()
        i,j,k,l = [
            [2,1,1,2],
            [0,2,0,2],
            [1,0,0,1]][m]
        cosa = (R33.trace() - 1.0) / 2.0
        sina = (R33[i, j] + (cosa - 1.0) * direction[k] * direction[l]) / direction[m]

        angle = math.atan2(sina, cosa)
        angle = abs(math.degrees(angle))
    except:
        print ' Error: rotation from matrix failed'
        raise CmdException

    if not quiet:
        try:
            # make this import optional to support running this script standalone
            from .querying import centerofmass, gyradius
        except (ValueError, ImportError):
            gyradius = None
            try:
                # PyMOL 1.7.1.6+
                centerofmass = cmd.centerofmass
            except AttributeError:
                centerofmass = lambda s: cpv.scale(cpv.add(*cmd.get_extent(s)), 0.5)

        center1 = centerofmass(selection1)
        center2 = centerofmass(selection2)
        print ' Angle: %.2f deg, Displacement: %.2f angstrom' % (angle, cpv.distance(center1, center2))

        if visualize:
            center1 = numpy.array(center1, float)
            center2 = numpy.array(center2, float)
            center = (center1 + center2) / 2.0

            if gyradius is not None:
                rg = numpy.array(gyradius(selection1), float)
            else:
                rg = 10.0

            h1 = numpy.cross(center2 - center1, direction)
            h2 = numpy.dot(R33, h1)
            h1 *= rg / cpv.length(h1)
            h2 *= rg / cpv.length(h2)

            for pos in [center1, center2, center1 + h1, center1 + h2]:
                cmd.pseudoatom(mobile_tmp, pos=list(pos), state=1)

            # measurement object for angle and displacement
            name = get_unused_name('measurement')
            cmd.distance(name, *['%s`%d' % (mobile_tmp, i) for i in [1,2]])
            cmd.angle(name, *['%s`%d' % (mobile_tmp, i) for i in [3,1,4]])

            # CGO arrow for axis of rotation
            visualize_orientation(direction, center1, rg, color='blue')

            cmd.delete(mobile_tmp)

    return angle
Ejemplo n.º 47
0
def sidechaincenters(object='scc', selection='all', method='bahar1996', name='PS1'):
    '''
DESCRIPTION

    Creates an object with sidechain representing pseudoatoms for each residue
    in selection.

    Two methods are available:
    (1) Sidechain interaction centers as defined by Bahar and Jernigan 1996
        http://www.ncbi.nlm.nih.gov/pubmed/9080182
    (2) Sidechain centroids, the pseudoatom is the centroid of all atoms except
        hydrogens and backbone atoms (N, C and O).

NOTE

    With method "bahar1996", if a residue has all relevant sidechain center
    atoms missing (for example a MET without SD), it will be missing in the
    created pseudoatom object.

    With method "centroid", if you want to exclude C-alpha atoms from
    sidechains, modify the selection like in this example:

    sidechaincenters newobject, all and (not name CA or resn GLY), method=2

USAGE

    sidechaincenters object [, selection [, method ]]

ARGUMENTS

    object = string: name of object to create

    selection = string: atoms to consider {default: (all)}

    method = string: bahar1996 or centroid {default: bahar1996}

    name = string: atom name of pseudoatoms {default: PS1}

SEE ALSO

    pseudoatom
    '''
    from chempy import Atom, cpv, models

    atmap = dict()
    if method in ['bahar1996', '1', 1]:
        modelAll = cmd.get_model('(%s) and resn %s' % (selection, '+'.join(sidechaincenteratoms)))
        for at in modelAll.atom:
            if at.name in sidechaincenteratoms[at.resn]:
                atmap.setdefault((at.segi, at.chain, at.resn, at.resi), []).append(at)
    elif method in ['centroid', '2', 2]:
        modelAll = cmd.get_model('(%s) and polymer and not (hydro or name C+N+O)' % selection)
        for at in modelAll.atom:
            atmap.setdefault((at.segi, at.chain, at.resn, at.resi), []).append(at)
    else:
        print('Error: unknown method:', method)
        raise CmdException

    model = models.Indexed()
    for centeratoms in atmap.values():
        center = cpv.get_null()
        for at in centeratoms:
            center = cpv.add(center, at.coord)
        center = cpv.scale(center, 1./len(centeratoms))
        atom = Atom()
        atom.coord = center
        atom.index = model.nAtom + 1
        atom.name = name
        for key in ['resn','chain','resi','resi_number','hetatm','ss','segi']:
            atom.__dict__[key] = at.__dict__[key]
        model.add_atom(atom)
    model.update_index()
    if object in cmd.get_object_list():
        cmd.delete(object)
    cmd.load_model(model, object)
    return model
Ejemplo n.º 48
0
            if z1 == 0.0:
                (y, x) = basis[0:2]
            else:
                (x, y) = basis[0:2]
            normal = normalize(cross_product(y, x))

        obj.extend([BEGIN, TRIANGLE_STRIP] + [COLOR, 1.0, 1.0, 1.0] +
                   [NORMAL] + normal)

        for i in range(sampling + 1):
            x1 = edge
            y1 = edge * i / sampling
            vlen = sqrt(x1 * x1 + y1 * y1)
            x0 = radius * x1 / vlen
            y0 = radius * y1 / vlen
            v0 = add(add(scale(x, x0), scale(y, y0)), scale(normal, z1))
            v1 = add(add(scale(x, x1), scale(y, y1)), scale(normal, z1))

            if hand:
                obj.extend([VERTEX] + v0 + [VERTEX] + v1)
            else:
                obj.extend([VERTEX] + v1 + [VERTEX] + v0)

        obj.extend([END])

        obj.extend([BEGIN, TRIANGLE_STRIP] + [COLOR, 1.0, 1.0, 1.0])

        for i in range(sampling + 1):
            x1 = edge
            y1 = edge * i / sampling
            vlen = sqrt(x1 * x1 + y1 * y1)
Ejemplo n.º 49
0
def angle_between_helices(selection1,
                          selection2,
                          method='helix',
                          state1=STATE,
                          state2=STATE,
                          visualize=1,
                          quiet=1):
    '''
DESCRIPTION

    Calculates the angle between two helices

USAGE

    angle_between_helices selection1, selection2 [, method [, visualize]]

ARGUMENTS

    selection1 = string: atom selection of first helix

    selection2 = string: atom selection of second helix

    method = string: function to calculate orientation {default: helix_orientation}

    visualize = 0 or 1: show fitted vector as arrow {default: 1}

EXAMPLE

    fetch 2x19, bsync=0
    select hel1, /2x19//B/23-36/
    select hel2, /2x19//B/40-54/
    angle_between_helices hel1, hel2
    angle_between_helices hel1, hel2, cafit

SEE ALSO

    helix_orientation, loop_orientation, cafit_orientation, angle_between_domains
    '''
    import math

    state1, state2 = int(state1), int(state2)
    visualize, quiet = int(visualize), int(quiet)

    try:
        orientation = globals()[methods_sc[str(method)]]
    except KeyError:
        print('no such method:', method)
        raise CmdException

    if not int(quiet):
        print(' Using method:', orientation.__name__)

    cen1, dir1 = orientation(selection1, state1, visualize, quiet=1)
    cen2, dir2 = orientation(selection2, state2, visualize, quiet=1)

    angle = cpv.get_angle(dir1, dir2)
    angle = math.degrees(angle)

    if not quiet:
        print(' Angle: %.2f deg' % (angle))

    if visualize:
        # measurement object for angle
        center = cpv.scale(cpv.add(cen1, cen2), 0.5)
        tmp = get_unused_name('_')
        for pos in [
                center,
                cpv.add(center, cpv.scale(dir1, 5.0)),
                cpv.add(center, cpv.scale(dir2, 5.0))
        ]:
            cmd.pseudoatom(tmp, pos=list(pos), state=1)
        name = get_unused_name('angle')
        cmd.angle(name, *[(tmp, i) for i in [2, 1, 3]])
        cmd.delete(tmp)

        cmd.zoom('(%s) or (%s)' % (selection1, selection2), 2,
                 state1 if state1 == state2 else 0)

    return angle
Ejemplo n.º 50
0
def plane_orientation(selection, state=STATE, visualize=1, guide=0, quiet=1):
    '''
DESCRIPTION

    Fit plane (for example beta-sheet). Can also be used with
    angle_between_helices (even though this does not fit helices).

    Returns center and normal vector of plane.
    '''
    try:
        import numpy
    except ImportError:
        print(' Error: numpy not available')
        raise CmdException

    state, visualize, quiet = int(state), int(visualize), int(quiet)

    if int(guide):
        selection = '(%s) and guide' % (selection)

    coords = list()
    cmd.iterate_state(state,
                      selection,
                      'coords.append([x,y,z])',
                      space=locals())

    if len(coords) < 3:
        print('not enough guide atoms in selection')
        raise CmdException

    x = numpy.array(coords)
    U, s, Vh = numpy.linalg.svd(x - x.mean(0))

    # normal vector of plane is 3rd principle component
    vec = cpv.normalize(Vh[2])
    if cpv.dot_product(vec, x[-1] - x[0]) < 0:
        vec = cpv.negate(vec)

    center = x.mean(0).tolist()
    _common_orientation(selection, center, vec, visualize, 4.0, quiet)

    # plane visualize
    if visualize:
        from pymol import cgo

        dir1 = cpv.normalize(Vh[0])
        dir2 = cpv.normalize(Vh[1])
        sx = [max(i / 4.0, 2.0) for i in s]

        obj = [cgo.BEGIN, cgo.TRIANGLES, cgo.COLOR, 0.5, 0.5, 0.5]
        for vertex in [
                cpv.scale(dir1, sx[0]),
                cpv.scale(dir2, sx[1]),
                cpv.scale(dir2, -sx[1]),
                cpv.scale(dir1, -sx[0]),
                cpv.scale(dir2, -sx[1]),
                cpv.scale(dir2, sx[1]),
        ]:
            obj.append(cgo.VERTEX)
            obj.extend(cpv.add(center, vertex))
        obj.append(cgo.END)
        cmd.load_cgo(obj, get_unused_name('planeFit'))

    return center, vec
Ejemplo n.º 51
0
def cgo_arrow(atom1='pk1', atom2='pk2', radius=0.5, gap=0.0, hlength=-1, hradius=-1,
              color='black black', name=''):
    '''
#I modify the color the line just before
DESCRIPTION

    Create a CGO arrow between two picked atoms.

ARGUMENTS

    atom1 = string: single atom selection or list of 3 floats {default: pk1}

    atom2 = string: single atom selection or list of 3 floats {default: pk2}

    radius = float: arrow radius {default: 0.5}

    gap = float: gap between arrow tips and the two atoms {default: 0.0}

    hlength = float: length of head

    hradius = float: radius of head

    color = string: one or two color names {default: blue red}

    name = string: name of CGO object
    '''
    from chempy import cpv

    radius, gap = float(radius), float(gap)
    hlength, hradius = float(hlength), float(hradius)

    try:
        color1, color2 = color.split()
    except:
        color1 = color2 = color
    color1 = list(cmd.get_color_tuple(color1))
    color2 = list(cmd.get_color_tuple(color2))

    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)

    xyz1 = get_coord(atom1)
    xyz2 = get_coord(atom2)
    normal = cpv.normalize(cpv.sub(xyz1, xyz2))

    if hlength < 0:
        hlength = radius * 3.0
    if hradius < 0:
        hradius = hlength * 0.6

    if gap:
        diff = cpv.scale(normal, gap)
        xyz1 = cpv.sub(xyz1, diff)
        xyz2 = cpv.add(xyz2, diff)

    xyz3 = cpv.add(cpv.scale(normal, hlength), xyz2)

    obj = [cgo.CYLINDER] + xyz1 + xyz3 + [radius] + color1 + color2 + \
          [cgo.CONE] + xyz3 + xyz2 + [hradius, 0.0] + color2 + color2 + \
          [1.0, 0.0]

    if not name:
        name = cmd.get_unused_name('arrow')

    cmd.load_cgo(obj, name)
Ejemplo n.º 52
0
    def update_box(self):

        if self.points_name in self.cmd.get_names():

            model = self.cmd.get_model(self.points_name)

            self.coord = (
                model.atom[0].coord,
                model.atom[1].coord,
                model.atom[2].coord,
                model.atom[3].coord,
                )

            p = self.coord[0]

            d10 = sub(self.coord[1], p)
            d20 = sub(self.coord[2], p)
            d30 = sub(self.coord[3], p)

            x10_20 = cross_product(d10,d20)
            if self.mode != 'quad':
                if dot_product(d30,x10_20)<0.0:
                    p = model.atom[1].coord
                    d10 = sub(self.coord[0], p)
                    d20 = sub(self.coord[2], p)
                    d30 = sub(self.coord[3], p)

            n10_20 = normalize(x10_20)
            n10 = normalize(d10)

            d100 = d10
            d010 = remove_component(d20, n10)
            if self.mode != 'quad':
                d001 = project(d30, n10_20)
            else:
                d001 = n10_20

            n100 = normalize(d100)
            n010 = normalize(d010)
            n001 = normalize(d001)

            f100 = reverse(n100)
            f010 = reverse(n010)
            f001 = reverse(n001)

            if self.mode == 'quad':
                p000 = p
                p100 = add(p, remove_component(d10,n001))
                p010 = add(p, remove_component(d20,n001))
                p001 = add(p, remove_component(d30,n001))
            else:
                p000 = p
                p100 = add(p,d100)
                p010 = add(p,d010)
                p001 = add(p,d001)
                p110 = add(p100, d010)
                p011 = add(p010, d001)
                p101 = add(p100, d001)
                p111 = add(p110, d001)

            obj = []

            if self.mode == 'box': # standard box

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(f001)
                obj.append(VERTEX); obj.extend(p000)
                obj.append(VERTEX); obj.extend(p010)
                obj.append(VERTEX); obj.extend(p100)
                obj.append(VERTEX); obj.extend(p110)
                obj.append(END)

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(n001)
                obj.append(VERTEX); obj.extend(p001)
                obj.append(VERTEX); obj.extend(p101)
                obj.append(VERTEX); obj.extend(p011)
                obj.append(VERTEX); obj.extend(p111)
                obj.append(END)

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(f010)
                obj.append(VERTEX); obj.extend(p000)
                obj.append(VERTEX); obj.extend(p100)
                obj.append(VERTEX); obj.extend(p001)
                obj.append(VERTEX); obj.extend(p101)
                obj.append(END)

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(n010)
                obj.append(VERTEX); obj.extend(p010)
                obj.append(VERTEX); obj.extend(p011)
                obj.append(VERTEX); obj.extend(p110)
                obj.append(VERTEX); obj.extend(p111)
                obj.append(END)

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(f100)
                obj.append(VERTEX); obj.extend(p000)
                obj.append(VERTEX); obj.extend(p001)
                obj.append(VERTEX); obj.extend(p010)
                obj.append(VERTEX); obj.extend(p011)
                obj.append(END)

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(n100)
                obj.append(VERTEX); obj.extend(p100)
                obj.append(VERTEX); obj.extend(p110)
                obj.append(VERTEX); obj.extend(p101)
                obj.append(VERTEX); obj.extend(p111)
                obj.append(END)

                model.atom[0].coord = p000
                model.atom[1].coord = p100
                model.atom[2].coord = add(p010, scale(d100,0.5))
                model.atom[3].coord = add(add(p001, scale(d010,0.5)),d100)

            elif self.mode=='walls':

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(n001)
                obj.append(VERTEX); obj.extend(p000)
                obj.append(VERTEX); obj.extend(p100)
                obj.append(VERTEX); obj.extend(p010)
                obj.append(VERTEX); obj.extend(p110)
                obj.append(END)

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(n010)
                obj.append(VERTEX); obj.extend(p000)
                obj.append(VERTEX); obj.extend(p001)
                obj.append(VERTEX); obj.extend(p100)
                obj.append(VERTEX); obj.extend(p101)
                obj.append(END)

                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(n100)
                obj.append(VERTEX); obj.extend(p000)
                obj.append(VERTEX); obj.extend(p010)
                obj.append(VERTEX); obj.extend(p001)
                obj.append(VERTEX); obj.extend(p011)
                obj.append(END)

                model.atom[0].coord = p000
                model.atom[1].coord = p100
                model.atom[2].coord = p010
                model.atom[3].coord = p001
            elif self.mode=='plane':
                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(n001)
                obj.append(VERTEX); obj.extend(p000)
                obj.append(VERTEX); obj.extend(p100)
                obj.append(VERTEX); obj.extend(p010)
                obj.append(VERTEX); obj.extend(p110)
                obj.append(END)
                model.atom[0].coord = p000
                model.atom[1].coord = p100
                model.atom[2].coord = p010
                model.atom[3].coord = add(add(p001, scale(d010,0.5)),scale(d100,0.5))
            elif self.mode=='quad':
                obj.extend([ BEGIN, TRIANGLE_STRIP ])
                obj.append(NORMAL); obj.extend(n001)
                obj.append(VERTEX); obj.extend(p000)
                obj.append(VERTEX); obj.extend(p100)
                obj.append(VERTEX); obj.extend(p010)
                obj.append(VERTEX); obj.extend(p001)
                obj.append(END)
                model.atom[0].coord = p000
                model.atom[1].coord = p100
                model.atom[2].coord = p010
                model.atom[3].coord = p001

            self.cmd.load_model(model, '_tmp', zoom=0)
            self.cmd.update(self.points_name,"_tmp")
            self.cmd.delete("_tmp")

            # then we load it into PyMOL

            self.cmd.delete(self.cgo_name)
            self.cmd.load_cgo(obj,self.cgo_name,zoom=0)
            self.cmd.order(self.cgo_name+" "+self.points_name,sort=1,location='bottom')
            self.cmd.set("nonbonded_size",math.sqrt(dot_product(d10,d10))/10,self.points_name)
Ejemplo n.º 53
0
def cgo_arrow(origin, endpoint, color='blue', radius=0.10, gap=0.0, hlength=-1,  hradius=-1,
               type='electric', name='', scaling = 7):

    '''
       :param origin: List representing origin point of vector to be drawn
       :type origin: List of floats

       :param endpoint: List representing endpoint of vector to be drawn
       :type endpoint: List of floats

       :param color: Color of arrow
       :type color: String, optional - default blue

       :param radius: Radius of cylinder portion of arrow
       :type radius: Float, optional - default .1

       :param gap: Specifies a gap between the head and body of the arrow, if desired
       :type gap: Float, optional - default 0

       :param hlength: Length of the head of the arrow
       :type hlength: Float, optional - default -1

       :param hradius: Radius of the head of the arrow
       :type hradius: Float, optional - default -1

       :param type: Type of vector being drawn, electric or magnetic
       :type type: String, optional - default electric

       :param name: Name to be shown in PyMol for the cgo object
       :type name: String, optional - default blank

       :param scaling: Scaling factor that is passed to scale_endpoint function
       :type scaling: Int, optional - default 7


       :return: None
    '''
    from chempy import cpv
    #converting parameters to floats
    radius, gap = float(radius), float(gap)
    hlength, hradius = float(hlength), float(hradius)

    if type == 'electric':
        color = 'red'
        name = 'electric'+name
    if type == 'magnetic':
        color = 'blue'
        name = 'magnetic'+name
    try:
        color1, color2 = color.split()
    except:
        color1 = color2 = color
    color1 = list(cmd.get_color_tuple(color1))
    color2 = list(cmd.get_color_tuple(color2))

    if origin == 'sele':
        xyz1 = cmd.get_coords('sele', 1)
        xyz1 = xyz1.flatten()
        xyz1 = xyz1.tolist()
        length=np.linalg.norm(np.array(endpoint))
        xyz2 = scale_endpoint(endpoint,scaling)
        xyz2 = shift_vectors(xyz2, xyz1)
    else:
        xyz1 = origin
        length=np.linalg.norm(np.array(endpoint)-np.array(xyz1))
        xyz2 = scale_endpoint(endpoint,scaling)


    normal = cpv.normalize(cpv.sub(xyz1, xyz2))

    if hlength < 0:
        hlength = radius * 3.0
    if hradius < 0:
        hradius = hlength * 0.6
    if gap:
        diff = cpv.scale(normal, gap)
        xyz1 = cpv.sub(xyz1, diff)
        xyz2 = cpv.add(xyz2, diff)
    ##Location where cylinder switches to cone
    xyz3 = cpv.add(cpv.scale(normal, hlength), xyz2)

    obj = [cgo.CYLINDER] + xyz1 + xyz3 + [radius] + color1 + color1 + \
          [cgo.CONE] + xyz3 + xyz2 + [hradius, 0.0] + color1 + color2 + \
          [1.0, 0.0]
    print(obj)

    ##Place pseudoatom with label at midpoint of vector
    v0=np.array(xyz1)
    v1=np.array(xyz2)
    loc=(v0+v1)/2

    if not name:
        name = cmd.get_unused_name('arrow')

    cmd.load_cgo(obj, f"vec_{name}")
    ##For some reason pos fails, but it just happens to put it where I want
    cmd.pseudoatom(f"lab_{name}",name="lab_"+name,label=f"{length:.2f}")#,pos=loc
    cmd.group(name,members=f"lab_{name} vec_{name}")