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 #2
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