Beispiel #1
0
def pir(selection='(all)', wrap=70):
    '''
DESCRIPTION

    Print sequence in PIR format

SEE ALSO

    fasta
    '''
    from . import one_letter
    from chempy import cpv
    wrap = int(wrap)
    for obj in cmd.get_object_list('(' + selection + ')'):
        seq = []
        prev_coord = None
        model = cmd.get_model('/%s////CA and guide and (%s)' % (obj, selection))
        for atom in model.atom:
            if prev_coord is not None and cpv.distance(atom.coord, prev_coord) > 4.0:
                seq.append('/\n')
            prev_coord = atom.coord
            seq.append(one_letter.get(atom.resn, 'X'))
        seq.append('*')
        print('>P1;%s' % (obj))
        print('structure:%s:%s:%s:%s:%s::::' % (obj,
                model.atom[0].resi,model.atom[0].chain,
                model.atom[-1].resi,model.atom[-1].chain))
        if wrap < 1:
            print(''.join(seq))
            continue
        for i in range(0, len(seq), wrap):
            print(''.join(seq[i:i+wrap]))
Beispiel #2
0
def pir(selection='(all)', wrap=70):
    '''
DESCRIPTION

    Print sequence in PIR format

SEE ALSO

    fasta
    '''
    from . import one_letter
    from chempy import cpv
    wrap = int(wrap)
    for obj in cmd.get_object_list('(' + selection + ')'):
        seq = []
        prev_coord = None
        model = cmd.get_model('/%s////CA and guide and (%s)' %
                              (obj, selection))
        for atom in model.atom:
            if prev_coord is not None and cpv.distance(atom.coord,
                                                       prev_coord) > 4.0:
                seq.append('/\n')
            prev_coord = atom.coord
            seq.append(one_letter.get(atom.resn, 'X'))
        seq.append('*')
        print('>P1;%s' % (obj))
        print('structure:%s:%s:%s:%s:%s::::' %
              (obj, model.atom[0].resi, model.atom[0].chain,
               model.atom[-1].resi, model.atom[-1].chain))
        if wrap < 1:
            print(''.join(seq))
            continue
        for i in range(0, len(seq), wrap):
            print(''.join(seq[i:i + wrap]))
Beispiel #3
0
 def callback(model, index, resn, coord):
     if cpv.distance(coord, prev) > 4.0:
         seq_list.append('#')
         idx_list.append(None)
     seq_list.append(one_letter.get(resn, '#'))
     idx_list.append((model,index))
     prev[:] = coord
Beispiel #4
0
 def callback(model, index, resn, coord):
     if cpv.distance(coord, prev) > 4.0:
         seq_list.append('#')
         idx_list.append(None)
     seq_list.append(one_letter.get(resn, '#'))
     idx_list.append((model, index))
     prev[:] = coord
Beispiel #5
0
 def testOrigin(self):
     from chempy import cpv
     cmd.pseudoatom('m1')
     cmd.pseudoatom('m2')
     cmd.pseudoatom('m3', pos=[1,0,0])
     # by selection
     cmd.origin('m3')
     cmd.rotate('y', 90, 'm1')
     # by position
     cmd.origin(position=[-1,0,0])
     cmd.rotate('y', 90, 'm2')
     coords = []
     cmd.iterate_state(1, 'm1 m2', 'coords.append([x,y,z])', space=locals())
     d = cpv.distance(*coords)
     self.assertAlmostEqual(d, 2 * 2**0.5)
Beispiel #6
0
 def testOrigin(self):
     from chempy import cpv
     cmd.pseudoatom('m1')
     cmd.pseudoatom('m2')
     cmd.pseudoatom('m3', pos=[1, 0, 0])
     # by selection
     cmd.origin('m3')
     cmd.rotate('y', 90, 'm1')
     # by position
     cmd.origin(position=[-1, 0, 0])
     cmd.rotate('y', 90, 'm2')
     coords = []
     cmd.iterate_state(1, 'm1 m2', 'coords.append([x,y,z])', space=locals())
     d = cpv.distance(*coords)
     self.assertAlmostEqual(d, 2 * 2**0.5)
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
Beispiel #8
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
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
Beispiel #10
0
def get_raw_distances(names='', state=1, selection='all', quiet=1):
    '''
DESCRIPTION

    Get the list of pair items from distance objects. Each list item is a
    tuple of (index1, index2, distance).

    Based on a script from Takanori Nakane, posted on pymol-users mailing list.
    http://www.mail-archive.com/[email protected]/msg10143.html

ARGUMENTS

    names = string: names of distance objects (no wildcards!) {default: all
    measurement objects}

    state = integer: object state {default: 1}

    selection = string: atom selection {default: all}

SEE ALSO

    select_distances, cmd.find_pairs, cmd.get_raw_alignment
    '''
    from chempy import cpv

    state, quiet = int(state), int(quiet)
    if state < 1:
        state = cmd.get_state()

    valid_names = cmd.get_names_of_type('object:measurement')
    if names == '':
        names = ' '.join(valid_names)
    else:
        for name in names.split():
            if name not in valid_names:
                print(' Error: no such distance object: ' + name)
                raise CmdException

    raw_objects = cmd.get_session(names, 1, 1, 0, 0)['names']

    xyz2idx = {}
    cmd.iterate_state(state, selection, 'xyz2idx[x,y,z] = (model,index)',
            space=locals())

    r = []
    for obj in raw_objects:
        try:
            points = obj[5][2][state-1][1]
            if points is None:
                raise ValueError
        except (KeyError, ValueError):
            continue
        for i in range(0, len(points), 6):
            xyz1 = tuple(points[i:i+3])
            xyz2 = tuple(points[i+3:i+6])
            try:
                r.append((xyz2idx[xyz1], xyz2idx[xyz2], cpv.distance(xyz1, xyz2)))
                if not quiet:
                    print(' get_raw_distances: ' + str(r[-1]))
            except KeyError:
                if quiet < 0:
                    print(' Debug: no index for %s %s' % (xyz1, xyz2))
    return r
Beispiel #11
0
def pmf(key,
        cutoff=7.0,
        selection1='(name CB)',
        selection2='',
        state=1,
        quiet=1):
    '''
DESCRIPTION
 
    Potential of Mean Force
 
ARGUMENTS
 
    key = string: aaindex key
 
    cutoff = float: distance cutoff {default: 7.0}
    cutoff = (float, float): distance shell
 
    selection1 = string: atom selection {default: (name CB)}
 
    selection2 = string: atom selection {default: selection1}
 
NOTES
 
    Does also support a list of keys and a list of cutoffs to deal with
    multiple distance shells.
 
EXAMPLES
 
    # distance dependent c-beta contact potentials
    pmf SIMK990101, 5,         /2x19//A//CB
    pmf SIMK990102, [5, 7.5],  /2x19//A//CB
    pmf [SIMK990101, SIMK990102, SIMK990103], [0, 5, 7.5, 10], /2x19//A//CB
 
    # interface potential
    sidechaincenters 2x19_scc, 2x19
    pmf KESO980102, 7.0, /2x19_scc//A, /2x19_scc//B
    distance /2x19_scc//A, /2x19_scc//B, cutoff=7.0
    '''
    from pymol import cmd, stored
    from chempy import cpv
    if cmd.is_string(key):
        if key.lstrip().startswith('['):
            key = cmd.safe_alpha_list_eval(key)
        else:
            key = [key]
    if cmd.is_string(cutoff):
        cutoff = eval(cutoff)
    if not cmd.is_sequence(cutoff):
        cutoff = [cutoff]
    if len(cutoff) == len(key):
        cutoff = [0.0] + list(cutoff)
    if len(cutoff) != len(key) + 1:
        print 'Error: Number of keys and number of cutoffs inconsistent'
        return
    state = int(state)
    quiet = int(quiet)
    if len(selection2) == 0:
        selection2 = selection1
    if not quiet and len(key) > 1:
        print 'Distance shells:'
        for i in range(len(key)):
            print '%s %.1f-%.1f' % (key[i], cutoff[i], cutoff[i + 1])

    idmap = dict()
    cmd.iterate_state(state,
                      '(%s) or (%s)' % (selection1, selection2),
                      'idmap[model,index] = [(resn,name),(x,y,z)]',
                      space={'idmap': idmap})
    twoN = cmd.count_atoms(selection1) + cmd.count_atoms(selection2)
    pairs = cmd.find_pairs(selection1,
                           selection2,
                           cutoff=max(cutoff),
                           state1=state,
                           state2=state)
    if len(pairs) == 0:
        print 'Empty pair list'
        return 0.0

    matrix = map(get, key)
    for i in matrix:
        assert isinstance(i, MatrixRecord)

    i_list = range(len(key))
    u_sum = 0
    count = 0
    for id1, id2 in pairs:
        a1 = idmap[id1]
        a2 = idmap[id2]
        r = cpv.distance(a1[1], a2[1])
        for i in i_list:
            if cutoff[i] <= r and r < cutoff[i + 1]:
                try:
                    aa1 = to_one_letter_code[a1[0][0]]
                    aa2 = to_one_letter_code[a2[0][0]]
                    u_sum += matrix[i].get(aa1, aa2)
                    count += 1
                except:
                    print 'Failed for', a1[0], a2[0]

    value = float(u_sum) / twoN
    if not quiet:
        print 'PMF: %.4f (%d contacts, %d residues)' % (value, count, twoN)
    return value
Beispiel #12
0
def delaunay(selection='enabled', name=None, cutoff=10.0, as_cgo=0,
        qdelaunay_exe='qdelaunay', state=-1, quiet=1):
    '''
DESCRIPTION

    Full-atom Delaunay Tessalator

    Creates either a molecular object with delaunay edges as bonds, or a CGO
    object with edge colors according to edge length.

USAGE

    delaunay [ selection [, name [, cutoff=10.0 [, as_cgo=0 ]]]]

SEE ALSO

    PyDeT plugin: http://pymolwiki.org/index.php/PyDet
    '''
    from chempy import cpv, Bond
    if name is None:
        name = cmd.get_unused_name('delaunay')
    cutoff = float(cutoff)
    as_cgo = int(as_cgo)
    state, quiet = int(state), int(quiet)
    if state < 1:
        state = cmd.get_state()
    model = cmd.get_model(selection, state)
    regions_iter = qdelaunay((a.coord for a in model.atom), 3, len(model.atom),
            qdelaunay_exe=qdelaunay_exe)
    edges = set(tuple(sorted([region[i-1], region[i]]))
            for region in regions_iter for i in range(len(region)))

    edgelist=[]
    r = []

    minco = 9999
    maxco = 0

    for edge in edges:
        ii, jj = edge
        a = model.atom[ii]
        b = model.atom[jj]
        co = cpv.distance(a.coord, b.coord)
        if cutoff > 0.0 and co > cutoff:
            continue
        if as_cgo:
            minco=min(co,minco)
            maxco=max(co,maxco)
            edgelist.append(a.coord + b.coord + [co])
        else:
            bnd = Bond()
            bnd.index = [ii, jj]
            model.add_bond(bnd)
        r.append((a,b,co))

    if not as_cgo:
        cmd.load_model(model, name, 1)
        return r

    from pymol.cgo import CYLINDER

    difco = maxco-minco
    obj = []
    mm = lambda x: max(min(x, 1.0), 0.0)
    for e in edgelist:
        co = ((e[6]-minco)/difco)**(0.75)
        color = [mm(1-2*co), mm(1-abs(2*co-1)), mm(2*co-1)]
        obj.extend([CYLINDER] + e[0:6] + [0.05] + color + color)

    cmd.load_cgo(obj, name)
    return r
Beispiel #13
0
def get_raw_distances(names='',
                      state=1,
                      selection='all',
                      fc=2.0,
                      amber=0,
                      gro=0,
                      label='ID',
                      quiet=1,
                      *,
                      _self=cmd):
    '''
DESCRIPTION
    Get the list of pair items from distance objects. Each list item is a
    tuple of (ID1, ID2, distance).
    Based on a script from Takanori Nakane, posted on pymol-users mailing list.
    http://www.mail-archive.com/[email protected]/msg10143.html
ARGUMENTS
    names = string: names of distance objects (no wildcards!) {default: all
    measurement objects}
    state = integer: object state {default: 1}
    selection = string: atom selection {default: all}
    amber = integer: generate AMBER rst file {default: 0}
    gro = integer: generate GROMACS rst file {default: 0}
    label = string: label type ('ID' or 'index') {default: ID}
SEE ALSO
    select_distances, cmd.find_pairs, cmd.get_raw_alignment
    '''
    from chempy import cpv

    state, quiet, fc = int(state), int(quiet), float(fc)
    if state < 1:
        state = _self.get_state()

    valid_names = _self.get_names_of_type('object:measurement')
    if names == '':
        names = ' '.join(valid_names)
    else:
        for name in names.split():
            if name not in valid_names:
                print(' Error: no such distance object: ' + name)
                raise CmdException

    raw_objects = _self.get_session(names, 1, 1, 0, 0)['names']

    xyz2idx = {}
    cmd.iterate_state(state,
                      selection,
                      'xyz2idx[x,y,z] = (model, resi, resn, name, ' + label +
                      ')',
                      space=locals())

    r = []
    for obj in raw_objects:
        try:
            points = obj[5][2][state - 1][1]
            if points is None:
                raise ValueError
        except (KeyError, ValueError):
            continue
        for i in range(0, len(points), 6):
            xyz1 = tuple(points[i:i + 3])
            xyz2 = tuple(points[i + 3:i + 6])
            try:
                r.append(
                    (xyz2idx[xyz1], xyz2idx[xyz2], cpv.distance(xyz1, xyz2)))
                if not quiet:
                    print(' get_raw_distances: ' + str(r[-1]))
            except KeyError:
                if quiet < 0:
                    print(' Debug: no index for %s %s' % (xyz1, xyz2))
    # print(r)
    # for generate amber MD restraint file.
    if (int(amber)):
        for i in r:
            print("""# {0}{1}  {2} - {3}{4}  {5}
&rst
   iat={6}, {7},
   r1=0, r2=0.5,
   r3={8:.2f}, r4=8,
   rk2={9}, rk3={9},
/""".format(str(i[0][1]), str(i[0][2]), str(i[0][3]), str(i[1][1]),
            str(i[1][2]), str(i[1][3]), str(i[0][4]), str(i[1][4]),
            float(i[2]), float(fc)))

    # for generate GROMACS MD restraint file.
    if (int(gro)):
        for i in r:
            print(
                "{6} {7} 10 0.00 {8:.3f} 0.800 800 ; {0}{1} {2} - {3}{4} {5} 2kcal/mol/A2"
                .format(str(i[0][1]), str(i[0][2]), str(i[0][3]), str(i[1][1]),
                        str(i[1][2]), str(i[1][3]), str(i[0][4]), str(i[1][4]),
                        float(i[2]) / 10))

    return r
Beispiel #14
0
def colorbyrmsd(mobile, target, doAlign=1, doPretty=1, guide=1, method='super', quiet=1):
    '''
DESCRIPTION

    Align two structures and show the structural deviations in color to more
    easily see variable regions.

    Colors each mobile/target atom-pair by distance (the name is a bit
    misleading).

    Modifies the B-factor columns in your original structures.

ARGUMENTS

    mobile = string: atom selection for mobile atoms
    
    target = string: atom selection for target atoms

    doAlign = 0 or 1: Superpose selections before calculating distances
    {default: 1}

    doPretty = 0 or 1: Show nice representation and colors {default: 1}

EXAMPLE

    fetch 1ake 4ake, async=0
    remove chain B
    colorbyrmsd 1ake, 4ake
    '''
    from chempy import cpv
    # import pdb
    doAlign, doPretty = int(doAlign), int(doPretty)
    guide, quiet = int(guide), int(quiet)
    aln, seleboth = '_aln', '_objSelBoth'

    try:
        align = cmd.keyword[method][0]
    except:
        print ' Error: no such method:', method
        raise CmdException

    if guide:
        mobile = '(%s) and guide' % mobile
        target = '(%s) and guide' % target

    try:
        if doAlign:
            # superpose
            zz=align(mobile, target, object=aln)
        else:
        # get alignment without superposing
            zz=align(mobile, target, cycles=0, transform=0, object=aln)
        if not quiet:
            print "RMSD = ", zz[0]
    except:
        print ' Error: Alignment with method %s failed' % (method)
        raise CmdException

    cmd.select(seleboth, '(%s) or (%s)' % (mobile, target))

    idx2coords = dict()
    cmd.iterate_state(-1, seleboth, 'idx2coords[model,index] = (x,y,z)', space=locals())

    if cmd.count_atoms('?' + aln, 1, 1) == 0:
        # this should ensure that "aln" will be available as selectable object
        cmd.refresh()

    b_dict = dict()
    for col in cmd.get_raw_alignment(aln):
        assert len(col) == 2
        b = cpv.distance(idx2coords[col[0]], idx2coords[col[1]])
        for idx in col:
            b_dict[idx] = b
    #pdb.set_trace()
    cmd.alter(seleboth, 'b = b_dict.get((model, index), -1)', space=locals())

    if doPretty:
        cmd.orient(seleboth)
        cmd.show_as('cartoon', 'byobj ' + seleboth)
        cmd.color('gray', seleboth)
        cmd.spectrum('b', 'blue_red', seleboth + ' and b > -0.5')

    if not quiet:
        print " ColorByRMSD: Minimum Distance: %.2f" % (min(b_dict.values()))
        print " ColorByRMSD: Maximum Distance: %.2f" % (max(b_dict.values()))
        print " ColorByRMSD: Average Distance: %.2f" % (sum(b_dict.values()) / len(b_dict))

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

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

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

USAGE

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

ARGUMENTS

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

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

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

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

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

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

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

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

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

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

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

    if ((not quiet) and (filename)):
        # Hijack stdout to print to file and console
        class logboth(object):
            def __init__(self, *files):
                self.files = files

            def write(self, obj):
                for f in self.files:
                    f.write(obj)

        originalstdout = sys.stdout
        sys.stdout = logboth(sys.stdout, report)

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

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

    if (not quiet):
        if property_name:
            print('Distances saved to property: %s' % str(property_name))
        else:
            print('Distances NOT saved to property (illegal custom property)')

    # remove temp. selection
    cmd.delete(tempsel)

    # return list for potential use:
    if coordinates:
        if len(distance_list) > 2:  # prevents crash if list is otherwise empty
            distance_list2 = list(map(distance_list.__getitem__, [1, 4]))
            return distance_list2
        else:
            return distance_list
    else:
        return distance_list
Beispiel #16
0
def bbPlane(objSel='(all)', color='white', transp=0.0):
    """
DESCRIPTION
 
    Draws a plane across the backbone for a selection
 
ARGUMENTS
 
    objSel = string: protein object or selection {default: (all)}
 
    color = string: color name or number {default: white}
 
    transp = float: transparency component (0.0--1.0) {default: 0.0}
 
NOTES
 
    You need to pass in an object or selection with at least two
    amino acids.  The plane spans CA_i, O_i, N-H_(i+1), and CA_(i+1)
    """
    # format input
    transp = float(transp)
    stored.AAs = []
    coords = dict()
 
    # need hydrogens on peptide nitrogen
    cmd.h_add('(%s) and n. N' % objSel)
 
    # get the list of residue ids
    for obj in cmd.get_object_list(objSel):
        sel = obj + " and (" + objSel + ")"
        for a in cmd.get_model(sel + " and n. CA").atom:
            key = '/%s/%s/%s/%s' % (obj,a.segi,a.chain,a.resi)
            stored.AAs.append(key)
            coords[key] = [a.coord,None,None]
        for a in cmd.get_model(sel + " and n. O").atom:
            key = '/%s/%s/%s/%s' % (obj,a.segi,a.chain,a.resi)
            if key in coords:
                coords[key][1] = a.coord
        for a in cmd.get_model("(hydro or n. CD) and nbr. (" + sel + " and n. N)").atom:
            key = '/%s/%s/%s/%s' % (obj,a.segi,a.chain,a.resi)
            if key in coords:
                coords[key][2] = a.coord
 
    # need at least two amino acids
    if len(stored.AAs) <= 1:
        print "ERROR: Please provide at least two amino acids, the alpha-carbon on the 2nd is needed."
        return
 
    # prepare the cgo
    obj = [
        BEGIN, TRIANGLES,
        COLOR,
        ]
    obj.extend(cmd.get_color_tuple(color))
 
    for res in range(0, len(stored.AAs)-1):
        curIdx, nextIdx = str(stored.AAs[res]), str(stored.AAs[res+1])
 
        # populate the position array
        pos = [coords[curIdx][0], coords[curIdx][1], coords[nextIdx][2], coords[nextIdx][0]]
 
        # if the data are incomplete for any residues, ignore
        if None in pos:
            print 'peptide bond %s -> %s incomplete' % (curIdx, nextIdx)
            continue
 
        if cpv.distance(pos[0], pos[3]) > 4.0:
            print '%s and %s not adjacent' % (curIdx, nextIdx)
            continue
 
        # fill in the vertex data for the triangles; 
        for i in [0,1,2,3,2,1]:
            obj.append(VERTEX)
            obj.extend(pos[i])
 
    # finish the CGO
    obj.append(END)
 
    # update the UI
    newName =  cmd.get_unused_name("backbonePlane")
    cmd.load_cgo(obj, newName)
    cmd.set("cgo_transparency", transp, newName)
Beispiel #17
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)
Beispiel #18
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
def pmf(key, cutoff=7.0, selection1='(name CB)', selection2='', state=1, quiet=1):
    '''
DESCRIPTION

    Potential of Mean Force

ARGUMENTS

    key = string: aaindex key

    cutoff = float: distance cutoff {default: 7.0}
    cutoff = (float, float): distance shell

    selection1 = string: atom selection {default: (name CB)}

    selection2 = string: atom selection {default: selection1}

NOTES

    Does also support a list of keys and a list of cutoffs to deal with
    multiple distance shells.

EXAMPLES

    # distance dependent c-beta contact potentials
    pmf SIMK990101, 5,         /2x19//A//CB
    pmf SIMK990102, [5, 7.5],  /2x19//A//CB
    pmf [SIMK990101, SIMK990102, SIMK990103], [0, 5, 7.5, 10], /2x19//A//CB

    # interface potential
    sidechaincenters 2x19_scc, 2x19
    pmf KESO980102, 7.0, /2x19_scc//A, /2x19_scc//B
    distance /2x19_scc//A, /2x19_scc//B, cutoff=7.0
    '''
    from pymol import cmd, stored
    from chempy import cpv
    if cmd.is_string(key):
        if key.lstrip().startswith('['):
            key = cmd.safe_alpha_list_eval(key)
        else:
            key = [key]
    if cmd.is_string(cutoff):
        cutoff = eval(cutoff)
    if not cmd.is_sequence(cutoff):
        cutoff = [cutoff]
    if len(cutoff) == len(key):
        cutoff = [0.0] + list(cutoff)
    if len(cutoff) != len(key) + 1:
        print('Error: Number of keys and number of cutoffs inconsistent')
        return
    state = int(state)
    quiet = int(quiet)
    if len(selection2) == 0:
        selection2 = selection1
    if not quiet and len(key) > 1:
        print('Distance shells:')
        for i in range(len(key)):
            print('%s %.1f-%.1f' % (key[i], cutoff[i], cutoff[i + 1]))

    idmap = dict()
    cmd.iterate_state(state, '(%s) or (%s)' % (selection1, selection2),
                      'idmap[model,index] = [(resn,name),(x,y,z)]', space={'idmap': idmap})
    twoN = cmd.count_atoms(selection1) + cmd.count_atoms(selection2)
    pairs = cmd.find_pairs(selection1, selection2, cutoff=max(cutoff),
                           state1=state, state2=state)
    if len(pairs) == 0:
        print('Empty pair list')
        return 0.0

    matrix = list(map(get, key))
    for i in matrix:
        assert isinstance(i, MatrixRecord)

    i_list = list(range(len(key)))
    u_sum = 0
    count = 0
    for id1, id2 in pairs:
        a1 = idmap[id1]
        a2 = idmap[id2]
        r = cpv.distance(a1[1], a2[1])
        for i in i_list:
            if cutoff[i] <= r and r < cutoff[i + 1]:
                try:
                    aa1 = to_one_letter_code[a1[0][0]]
                    aa2 = to_one_letter_code[a2[0][0]]
                    u_sum += matrix[i].get(aa1, aa2)
                    count += 1
                except:
                    print('Failed for', a1[0], a2[0])

    value = float(u_sum) / twoN
    if not quiet:
        print('PMF: %.4f (%d contacts, %d residues)' % (value, count, twoN))
    return value
Beispiel #20
0
def delaunay(selection='enabled',
             name=None,
             cutoff=10.0,
             as_cgo=0,
             qdelaunay_exe='qdelaunay',
             state=-1,
             quiet=1,
             *,
             _self=cmd):
    '''
DESCRIPTION

    Full-atom Delaunay Tessalator

    Creates either a molecular object with delaunay edges as bonds, or a CGO
    object with edge colors according to edge length.

USAGE

    delaunay [ selection [, name [, cutoff=10.0 [, as_cgo=0 ]]]]

SEE ALSO

    PyDeT plugin: http://pymolwiki.org/index.php/PyDet
    '''
    from chempy import cpv, Bond
    if name is None:
        name = _self.get_unused_name('delaunay')
    cutoff = float(cutoff)
    as_cgo = int(as_cgo)
    state, quiet = int(state), int(quiet)
    if state < 1:
        state = _self.get_state()
    model = _self.get_model(selection, state)
    regions_iter = qdelaunay((a.coord for a in model.atom),
                             3,
                             len(model.atom),
                             qdelaunay_exe=qdelaunay_exe)
    edges = set(
        tuple(sorted([region[i - 1], region[i]])) for region in regions_iter
        for i in range(len(region)))

    edgelist = []
    r = []

    minco = 9999
    maxco = 0

    for edge in edges:
        ii, jj = edge
        a = model.atom[ii]
        b = model.atom[jj]
        co = cpv.distance(a.coord, b.coord)
        if cutoff > 0.0 and co > cutoff:
            continue
        if as_cgo:
            minco = min(co, minco)
            maxco = max(co, maxco)
            edgelist.append(a.coord + b.coord + [co])
        else:
            bnd = Bond()
            bnd.index = [ii, jj]
            model.add_bond(bnd)
        r.append((a, b, co))

    if not as_cgo:
        _self.load_model(model, name, 1)
        return r

    from pymol.cgo import CYLINDER

    difco = maxco - minco
    obj = []
    mm = lambda x: max(min(x, 1.0), 0.0)
    for e in edgelist:
        co = ((e[6] - minco) / difco)**(0.75)
        color = [mm(1 - 2 * co), mm(1 - abs(2 * co - 1)), mm(2 * co - 1)]
        obj.extend([CYLINDER] + e[0:6] + [0.05] + color + color)

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

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

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

USAGE

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

ARGUMENTS

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (not quiet):
        if property_name: print 'Distances saved to property: %s' %str(property_name)
        else: print 'Distances NOT saved to property (illegal custom property)'
Beispiel #22
0
def rmsd(selection = "all", chains = "", doAlign = 1, doPretty = 1, \
         algorithm = 1, guide = 1, method = "super", quiet = 1, colorstyle = "blue_red", colormode = ""):
    """
DESCRIPTION

    Align all structures and show the structural.

ARGUMENTS

    Haves following arguments:
    selection = "all"
    chains = ""  : like {chains = ab"}
    doAlign = 0 or 1 : Superpose selections before calculating distances {default: 1}
    doPretty = 1 
    guide = 1
    algorithm = 0 or 1 :  
    method = "super"
    quiet = 1

EXAMPLE

    fetch

    """
    from chempy import cpv
    #initial parameters
    doAlign, doPretty = int(doAlign), int(doPretty)
    guide, quiet = int(guide), int(quiet)
    algorithm = int(algorithm)

    #get suitable align method
    try:
        align = cmd.keyword[method][0]
    except:
        print "Error: no such method:", method
        raise CmdException


#get object and store each atom's coordinate
    objects = set()
    idx2coords = dict()
    cmd.iterate_state(-1, selection, "objects.add(model) ", space=locals())
    #store the compared rmsd tree for each objects, like {obj:{obj1:{(model, index):(model1, index1)}}}

    rmsd_stored = dict()
    for obj in objects:
        rmsd_stored[obj] = {}
        for obj1 in objects:
            if obj != obj1:
                if guide:
                    guide = " and guide"
                else:
                    guide = ""
                rmsd_stored[obj][obj1] = {}
                total_values = {}
                if chains:
                    for eachchain in list(chains):
                        if doAlign:
                            align(obj1 + guide + " and chain " + eachchain,
                                  obj + guide + " and chain " + eachchain)
                        align(obj1 + " and chain " + eachchain,
                              obj + " and chain " + eachchain,
                              cycles=0,
                              transform=0,
                              object="aln")
                        cmd.iterate_state(-1,
                                          selection,
                                          "idx2coords[model,index] = (x,y,z)",
                                          space=locals())
                        if cmd.count_atoms('?' + "aln", 1, 1) == 0:
                            # this should ensure that "aln" will be available as selectable object
                            cmd.refresh()
                        for col in cmd.get_raw_alignment("aln"):
                            assert len(col) == 2
                            b = cpv.distance(idx2coords[col[0]],
                                             idx2coords[col[1]])
                            for idx in col:
                                total_values[idx] = b
                            if col[0][0] == obj:
                                rmsd_stored[obj][obj1][col[0]] = [col[1], b]
                            else:
                                rmsd_stored[obj][obj1][col[1]] = [col[0], b]
                        cmd.delete("aln")
                else:
                    if doAlign:
                        align(obj1 + guide, obj + guide)
                    align(obj1 + guide,
                          obj + guide,
                          cycles=0,
                          transform=0,
                          object="aln")
                    cmd.iterate_state(-1,
                                      selection,
                                      "idx2coords[model,index] = (x,y,z)",
                                      space=locals())
                    if cmd.count_atoms('?' + "aln", 1, 1) == 0:
                        # this should ensure that "aln" will be available as selectable object
                        cmd.refresh()
                    for col in cmd.get_raw_alignment("aln"):
                        assert len(col) == 2
                        b = cpv.distance(idx2coords[col[0]],
                                         idx2coords[col[1]])
                        for idx in col:
                            total_values[idx] = b
                        if col[0][0] == obj:
                            rmsd_stored[obj][obj1][col[0]] = [col[1], b]
                        else:
                            rmsd_stored[obj][obj1][col[1]] = [col[0], b]
                    cmd.delete("aln")
    if algorithm:

        def b_replace(model, index):
            n = 0
            bsum = 0

            for obj1 in objects:
                if model != obj1:
                    if (model, index) in rmsd_stored[model][obj1]:
                        nextmodel, nextindex = rmsd_stored[model][obj1][
                            model, index][0]
                        bsum += rmsd_stored[model][obj1][model, index][1]
                        n += 1
                        for nextobj1 in objects:
                            if nextmodel != nextobj1 and nextmodel != obj1:
                                if (nextmodel, nextindex
                                    ) in rmsd_stored[nextmodel][nextobj1]:
                                    bsum += rmsd_stored[nextmodel][nextobj1][
                                        nextmodel, nextindex][1]
                                    n += 1
            if n == 0:
                return -1
            else:
                return eval("bsum / n")

    else:

        def b_replace(model, index):
            n = 0
            bsum = 0

            for obj1 in objects:
                if model != obj1:
                    if (model, index) in rmsd_stored[model][obj1]:
                        bsum += rmsd_stored[model][obj1][model, index][1]
                        n += 1

            if n == 0:
                return -1
            else:
                return eval("bsum / n")

    cmd.alter(selection, 'b = b_replace(model, index)', space=locals())

    if doPretty:

        mini = min(total_values.values())
        maxi = max(total_values.values())
        if colormode:
            if colormode == "lowshow":
                maxi = sum(total_values.values()) / len(total_values)
                print("This is lowshow")
            elif colormode == "highshow":
                mini = sum(total_values.values()) / len(total_values)
                print("This is highshow")
            else:
                raise CmdException

        cmd.orient(selection)
        cmd.show_as('cartoon', 'byobj ' + selection)
        cmd.color('gray', selection)
        cmd.spectrum('b',
                     "blue_red",
                     selection + ' and b > -0.5',
                     minimum=mini,
                     maximum=maxi)
    if not quiet:
        print " ColorByRMSD: Minimum Distance: %.2f" % (min(
            total_values.values()))
        print " ColorByRMSD: Maximum Distance: %.2f" % (max(
            total_values.values()))
        print " ColorByRMSD: Average Distance: %.2f" % (
            sum(total_values.values()) / len(total_values))
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
Beispiel #24
0
def get_raw_distances(names='', state=1, selection='all', quiet=1):
    '''
DESCRIPTION

    Get the list of pair items from distance objects. Each list item is a
    tuple of (index1, index2, distance).

    Based on a script from Takanori Nakane, posted on pymol-users mailing list.
    http://www.mail-archive.com/[email protected]/msg10143.html

ARGUMENTS

    names = string: names of distance objects (no wildcards!) {default: all
    measurement objects}

    state = integer: object state {default: 1}

    selection = string: atom selection {default: all}

SEE ALSO

    select_distances, cmd.find_pairs, cmd.get_raw_alignment
    '''
    from chempy import cpv

    state, quiet = int(state), int(quiet)
    if state < 1:
        state = cmd.get_state()

    valid_names = cmd.get_names_of_type('object:measurement')
    if names == '':
        names = ' '.join(valid_names)
    else:
        for name in names.split():
            if name not in valid_names:
                print((' Error: no such distance object:', name))
                raise CmdException

    raw_objects = cmd.get_session(names, 1, 1, 0, 0)['names']

    xyz2idx = {}
    cmd.iterate_state(state,
                      selection,
                      'xyz2idx[x,y,z] = (model,index)',
                      space=locals())

    r = []
    for obj in raw_objects:
        try:
            points = obj[5][2][state - 1][1]
            if points is None:
                raise ValueError
        except (KeyError, ValueError):
            continue
        for i in range(0, len(points), 6):
            xyz1 = tuple(points[i:i + 3])
            xyz2 = tuple(points[i + 3:i + 6])
            try:
                r.append(
                    (xyz2idx[xyz1], xyz2idx[xyz2], cpv.distance(xyz1, xyz2)))
                if not quiet:
                    print((' get_raw_distances:', r[-1]))
            except KeyError:
                if quiet < 0:
                    print((' Debug: no index for', xyz1, xyz2))
    return r
Beispiel #25
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
def colorbyrmsd(mobile,
                target,
                doAlign=1,
                doPretty=1,
                guide=1,
                method='super',
                quiet=1):
    '''
DESCRIPTION

    Align two structures and show the structural deviations in color to more
    easily see variable regions.

    Colors each mobile/target atom-pair by distance (the name is a bit
    misleading).

    Modifies the B-factor columns in your original structures.

ARGUMENTS

    mobile = string: atom selection for mobile atoms

    target = string: atom selection for target atoms

    doAlign = 0 or 1: Superpose selections before calculating distances
    {default: 1}

    doPretty = 0 or 1: Show nice representation and colors {default: 1}

EXAMPLE

    fetch 1ake 4ake, async=0
    remove chain B
    colorbyrmsd 1ake, 4ake
    '''
    from chempy import cpv

    doAlign, doPretty = int(doAlign), int(doPretty)
    guide, quiet = int(guide), int(quiet)
    aln, seleboth = '_aln', '_objSelBoth'

    try:
        align = cmd.keyword[method][0]
    except:
        print(' Error: no such method: ' + str(method))
        raise CmdException

    if guide:
        mobile = '(%s) and guide' % mobile
        target = '(%s) and guide' % target

    try:
        if doAlign:
            # superpose
            align(mobile, target)

        # get alignment without superposing
        align(mobile, target, cycles=0, transform=0, object=aln)
    except:
        print(' Error: Alignment with method %s failed' % (method))
        raise CmdException

    cmd.select(seleboth, '(%s) or (%s)' % (mobile, target))

    idx2coords = dict()
    cmd.iterate_state(-1,
                      seleboth,
                      'idx2coords[model,index] = (x,y,z)',
                      space=locals())

    if cmd.count_atoms('?' + aln, 1, 1) == 0:
        # this should ensure that "aln" will be available as selectable object
        cmd.refresh()

    b_dict = dict()
    for col in cmd.get_raw_alignment(aln):
        assert len(col) == 2
        b = cpv.distance(idx2coords[col[0]], idx2coords[col[1]])
        for idx in col:
            b_dict[idx] = b

    cmd.alter(seleboth, 'b = b_dict.get((model, index), -1)', space=locals())

    if doPretty:
        cmd.orient(seleboth)
        cmd.show_as('cartoon', 'byobj ' + seleboth)
        cmd.color('gray', seleboth)
        cmd.spectrum('b', 'blue_red', seleboth + ' and b > -0.5')

    if not quiet:
        print(" ColorByRMSD: Minimum Distance: %.2f" % (min(b_dict.values())))
        print(" ColorByRMSD: Maximum Distance: %.2f" % (max(b_dict.values())))
        print(" ColorByRMSD: Average Distance: %.2f" %
              (sum(b_dict.values()) / len(b_dict)))

    cmd.delete(aln)
    cmd.delete(seleboth)
Beispiel #27
0
def rmsd(selection = "all", chains = "", doAlign = 1, doPretty = 1, \
         algorithm = 1, guide = 1, method = "super", quiet = 1, colorstyle = "blue_red", colormode = ""):
    """
DESCRIPTION

    Align all structures and show the structural.

ARGUMENTS

    Haves following arguments:
    selection = "all"
    chains = ""  : like {chains = ab"}
    doAlign = 0 or 1 : Superpose selections before calculating distances {default: 1}
    doPretty = 1 
    guide = 1
    algorithm = 0 or 1 :  
    method = "super"
    quiet = 1

EXAMPLE

    fetch

    """
    from chempy import cpv
#initial parameters
    doAlign, doPretty = int(doAlign), int(doPretty)
    guide, quiet = int(guide), int(quiet)
    algorithm = int(algorithm)
    
#get suitable align method
    try:
        align = cmd.keyword[method][0]
    except:
        print "Error: no such method:", method
        raise CmdException

#get object and store each atom's coordinate
    objects = set()
    idx2coords = dict()
    cmd.iterate_state(-1, selection, "objects.add(model) ", space=locals())
#store the compared rmsd tree for each objects, like {obj:{obj1:{(model, index):(model1, index1)}}}

    rmsd_stored = dict()
    for obj in objects:
        rmsd_stored[obj] = {}
        for obj1 in objects:
            if obj != obj1:
                if guide:
                    guide = " and guide"
                else:
                    guide = ""
                rmsd_stored[obj][obj1] = {}
                total_values = {}
                if chains:
                    for eachchain in list(chains):
                        if doAlign:
                            align(obj1 + guide + " and chain " + eachchain, obj + guide + " and chain " + eachchain)
                        align(obj1 + " and chain " + eachchain, obj + " and chain " + eachchain, cycles = 0, transform = 0, object="aln")
                        cmd.iterate_state(-1, selection, "idx2coords[model,index] = (x,y,z)", space=locals())
                        if cmd.count_atoms('?' + "aln", 1, 1) == 0:
                            # this should ensure that "aln" will be available as selectable object
                            cmd.refresh()
                        for col in cmd.get_raw_alignment("aln"):
                            assert len(col) == 2
                            b = cpv.distance(idx2coords[col[0]], idx2coords[col[1]])
                            for idx in col:
                                total_values[idx] = b
                            if col[0][0] == obj:
                                rmsd_stored[obj][obj1][col[0]] = [col[1],b]
                            else:
                                rmsd_stored[obj][obj1][col[1]] = [col[0],b]
                        cmd.delete("aln")
                else:
                    if doAlign:
                        align(obj1 + guide, obj + guide)
                    align(obj1 + guide, obj + guide, cycles=0, transform=0, object="aln")
                    cmd.iterate_state(-1, selection, "idx2coords[model,index] = (x,y,z)", space=locals())
                    if cmd.count_atoms('?' + "aln", 1, 1) == 0:
                        # this should ensure that "aln" will be available as selectable object
                        cmd.refresh()
                    for col in cmd.get_raw_alignment("aln"):
                        assert len(col) == 2
                        b = cpv.distance(idx2coords[col[0]], idx2coords[col[1]])
                        for idx in col:
                                total_values[idx] = b
                        if col[0][0] == obj:
                            rmsd_stored[obj][obj1][col[0]] = [col[1],b]
                        else:
                            rmsd_stored[obj][obj1][col[1]] = [col[0],b]
                    cmd.delete("aln")
    if algorithm:
        def b_replace(model, index):
            n = 0
            bsum = 0

            for obj1 in objects:
                if model != obj1:
                    if (model, index) in rmsd_stored[model][obj1]:
                        nextmodel, nextindex = rmsd_stored[model][obj1][model, index][0]
                        bsum += rmsd_stored[model][obj1][model, index][1]
                        n += 1
                        for nextobj1 in objects:
                            if nextmodel != nextobj1 and nextmodel != obj1 :
                                if (nextmodel, nextindex) in rmsd_stored[nextmodel][nextobj1]:
                                    bsum += rmsd_stored[nextmodel][nextobj1][nextmodel, nextindex][1]
                                    n += 1
            if n == 0 :
                return -1
            else:
                return eval("bsum / n")
                        
        
        
    else:
        
        def b_replace(model, index):
            n = 0
            bsum = 0
           
            for obj1 in objects:
                if model != obj1:
                    if (model, index) in rmsd_stored[model][obj1]:
                        bsum += rmsd_stored[model][obj1][model, index][1]
                        n += 1
               
            if n == 0 :
                return -1
            else:
                return eval("bsum / n")
        
                
    cmd.alter(selection, 'b = b_replace(model, index)', space=locals())
    
           
    if doPretty:
        
        mini = min(total_values.values())
        maxi = max(total_values.values())
        if colormode:
            if colormode == "lowshow":
                maxi = sum(total_values.values()) / len(total_values)
                print("This is lowshow")
            elif colormode == "highshow":
                mini = sum(total_values.values()) / len(total_values)
                print("This is highshow")
            else:
                raise CmdException
                
        cmd.orient(selection)
        cmd.show_as('cartoon', 'byobj ' + selection)
        cmd.color('gray', selection)
        cmd.spectrum('b', "blue_red", selection + ' and b > -0.5',minimum = mini, maximum = maxi)
    if not quiet:
        print " ColorByRMSD: Minimum Distance: %.2f" % (min(total_values.values()))
        print " ColorByRMSD: Maximum Distance: %.2f" % (max(total_values.values()))
        print " ColorByRMSD: Average Distance: %.2f" % (sum(total_values.values()) / len(total_values))
Beispiel #28
0
def get_raw_distances(names='',
                      state=1,
                      selection='all',
                      quiet=1,
                      filename='intrs.txt'):
    '''
DESCRIPTION

    Get the list of pair items from distance objects. Each list item is a
    tuple of (index1, index2, distance).

    Based on a script from Takanori Nakane, posted on pymol-users mailing list.
    http://www.mail-archive.com/[email protected]/msg10143.html

ARGUMENTS

    names = string: names of distance objects (no wildcards!) {default: all
    measurement objects}

    state = integer: object state {default: 1}

    selection = string: atom selection {default: all}

    quiet = boolen

    filename

SEE ALSO

    select_distances, cmd.find_pairs, cmd.get_raw_alignment
    '''
    foo = cmd.do('l = [];')  ## ugly hack!
    from chempy import cpv

    state, quiet = int(state), int(quiet)
    if state < 1:
        state = cmd.get_state()

    valid_names = cmd.get_names_of_type('object:measurement')
    if names == '':
        names = ' '.join(valid_names)
    else:
        for name in names.split():
            if name not in valid_names:
                print(' Error: no such distance object: ' + name)
                raise CmdException

    raw_objects = cmd.get_session(names, 1, 1, 0, 0)['names']

    xyz2idx = {}
    cmd.iterate_state(state,
                      selection,
                      'xyz2idx[x,y,z] = (model,index)',
                      space=locals())

    r = []
    rresi = []
    for obj in raw_objects:
        try:
            points = obj[5][2][state - 1][1]
            if not quiet:
                print(points)
            if points is None:
                raise ValueError
        except (KeyError, ValueError):
            continue
        for i in range(0, len(points), 6):
            xyz1 = tuple(points[i:i + 3])
            xyz2 = tuple(points[i + 3:i + 6])
            try:
                r.append(
                    (xyz2idx[xyz1], xyz2idx[xyz2], cpv.distance(xyz1, xyz2)))
                # (('yC_5lj3_U6', 1183)
                if not quiet:
                    print(' get_raw_distances: ' + str(r[-1]))
                rresi.append([
                    unid(xyz2idx[xyz1][0], xyz2idx[xyz1][1]),
                    unid(xyz2idx[xyz2][0], xyz2idx[xyz2][1])
                ])
                if not quiet:
                    print('  ', unid(xyz2idx[xyz1][0], xyz2idx[xyz1][1]),
                          '<->', unid(xyz2idx[xyz2][0], xyz2idx[xyz2][1]))
            except KeyError:
                if quiet < 0:
                    print(' Debug: no index for %s %s' % (xyz1, xyz2))

    if rresi:
        with open(filename, 'w') as f:
            for r in rresi:
                # not fully correct
                # f.write('Prp8' +',' + r[0] + '\n')
                f.write(r[0] + ',' + r[1] + '\n')
        print('File saved:', filename)
    return r, rresi
Beispiel #29
0
def bbPlane(selection='(all)', color='gray', transp=0.3, state=-1, name=None, quiet=1):
    """
DESCRIPTION

    Draws a plane across the backbone for a selection

ARGUMENTS

    selection = string: protein object or selection {default: (all)}

    color = string: color name or number {default: white}

    transp = float: transparency component (0.0--1.0) {default: 0.0}

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

NOTES

    You need to pass in an object or selection with at least two
    amino acids.  The plane spans CA_i, O_i, N-H_(i+1), and CA_(i+1)
    """
    from pymol.cgo import BEGIN, TRIANGLES, COLOR, VERTEX, END
    from pymol import cgo
    from chempy import cpv

    # format input
    transp = float(transp)
    state, quiet = int(state), int(quiet)
    if name is None:
        name = cmd.get_unused_name("backbonePlane")

    if state < 0:
        state = cmd.get_state()
    elif state == 0:
        for state in range(1, cmd.count_states(selection) + 1):
            bbPlane(selection, color, transp, state, name, quiet)
        return

    AAs = []
    coords = dict()

    # need hydrogens on peptide nitrogen
    cmd.h_add('(%s) and n. N' % selection)

    # get the list of residue ids
    for obj in cmd.get_object_list(selection):
        sel = obj + " and (" + selection + ")"
        for a in cmd.get_model(sel + " and n. CA", state).atom:
            key = '/%s/%s/%s/%s' % (obj, a.segi, a.chain, a.resi)
            AAs.append(key)
            coords[key] = [a.coord, None, None]
        for a in cmd.get_model(sel + " and n. O", state).atom:
            key = '/%s/%s/%s/%s' % (obj, a.segi, a.chain, a.resi)
            if key in coords:
                coords[key][1] = a.coord
        for a in cmd.get_model(sel + " and ((n. N extend 1 and e. H) or (r. PRO and n. CD))", state).atom:
            key = '/%s/%s/%s/%s' % (obj, a.segi, a.chain, a.resi)
            if key in coords:
                coords[key][2] = a.coord

    # need at least two amino acids
    if len(AAs) <= 1:
        print("ERROR: Please provide at least two amino acids, the alpha-carbon on the 2nd is needed.")
        return

    # prepare the cgo
    obj = [
        BEGIN, TRIANGLES,
        COLOR,
    ]
    obj.extend(cmd.get_color_tuple(color))

    for res in range(0, len(AAs) - 1):
        curIdx, nextIdx = str(AAs[res]), str(AAs[res + 1])

        # populate the position array
        pos = [coords[curIdx][0], coords[curIdx][1], coords[nextIdx][2], coords[nextIdx][0]]

        # if the data are incomplete for any residues, ignore
        if None in pos:
            if not quiet:
                print(' bbPlane: peptide bond %s -> %s incomplete' % (curIdx, nextIdx))
            continue

        if cpv.distance(pos[0], pos[3]) > 4.0:
            if not quiet:
                print(' bbPlane: %s and %s not adjacent' % (curIdx, nextIdx))
            continue

        normal = cpv.normalize(cpv.cross_product(
            cpv.sub(pos[1], pos[0]),
            cpv.sub(pos[2], pos[0])))

        obj.append(cgo.NORMAL)
        obj.extend(normal)

        # need to order vertices to generate correct triangles for plane
        if cpv.dot_product(cpv.sub(pos[0], pos[1]), cpv.sub(pos[2], pos[3])) < 0:
            vorder = [0, 1, 2, 2, 3, 0]
        else:
            vorder = [0, 1, 2, 3, 2, 1]

        # fill in the vertex data for the triangles;
        for i in vorder:
            obj.append(VERTEX)
            obj.extend(pos[i])

    # finish the CGO
    obj.append(END)

    # update the UI
    cmd.load_cgo(obj, name, state, zoom=0)
    cmd.set("cgo_transparency", transp, name)
Beispiel #30
0
def cgo_arrow(atom1='pk1',
              atom2='pk2',
              radius=0.5,
              gap=0.0,
              hlength=-1,
              hradius=-1,
              color='blue red',
              name='',
              state=0):
    '''
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

    state = int: arrow state index
    '''
    from chempy import cpv

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

    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.CONE] + xyz3 + xyz2 + [hradius, 0.0
                                      ] + color2 + color2 + [1.0, 0.0]

    if cpv.distance(xyz1, xyz2) > hlength:  # draw cylinder
        obj += [cgo.CYLINDER] + xyz1 + xyz3 + [radius] + color1 + color2

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

    cmd.load_cgo(obj, name, state)