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