forked from Pymol-Scripts/Pymol-script-repo
-
Notifications
You must be signed in to change notification settings - Fork 11
/
get_raw_distances.py
126 lines (94 loc) · 3.51 KB
/
get_raw_distances.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
'''
http://pymolwiki.org/index.php/get_raw_distances
(c) 2012 Takanori Nakane and Thomas Holder
License: BSD-2-Clause
'''
from pymol import cmd, CmdException
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
def select_distances(names='', name='sele', state=1, selection='all', cutoff=-1, quiet=1):
'''
DESCRIPTION
Turns a distance object into a named atom selection.
ARGUMENTS
names = string: names of distance objects (no wildcards!) {default: all
measurement objects}
name = a unique name for the selection {default: sele}
SEE ALSO
get_raw_distances
'''
state, cutoff, quiet = int(state), float(cutoff), int(quiet)
sele_dict = {}
distances = get_raw_distances(names, state, selection)
for idx1, idx2, dist in distances:
if cutoff <= 0.0 or dist <= cutoff:
sele_dict.setdefault(idx1[0], set()).add(idx1[1])
sele_dict.setdefault(idx2[0], set()).add(idx2[1])
cmd.select(name, 'none')
tmp_name = cmd.get_unused_name('_')
r = 0
for model in sele_dict:
cmd.select_list(tmp_name, model, list(sele_dict[model]), mode='index')
r = cmd.select(name, tmp_name, merge=1)
cmd.delete(tmp_name)
if not quiet:
print ' Selector: selection "%s" defined with %d atoms.' % (name, r)
return r
cmd.extend('get_raw_distances', get_raw_distances)
cmd.extend('select_distances', select_distances)
_auto_arg0_distances = [
lambda: cmd.Shortcut(cmd.get_names_of_type('object:measurement')),
'distance object', '']
cmd.auto_arg[0].update([
('get_raw_distances', _auto_arg0_distances),
('select_distances', _auto_arg0_distances),
])
# vi: ts=4:sw=4:smarttab:expandtab