forked from getcontacts/getcontacts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget_contact_flare.py
executable file
·222 lines (202 loc) · 8.77 KB
/
get_contact_flare.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#!/usr/bin/env python
"""
Takes a list of atomic contacts as input and generates a json representing a
temporal flare which can be visualized using flareplots.
A subset of interaction types can be selected using the --itypes argument which
specifies a list of abbreviated interaction types:
sb salt bridges
pc pi-cation
ps pi-stacking
ts t-stacking
vdw van der Waals
hb hydrogen bonds
lhb ligand hydrogen bonds
hbbb backbone-backbone hydrogen bonds
hbsb backbone-sidechain hydrogen bonds
hbss sidechain-sidechain hydrogen bonds
wb water bridges
wb2 extended water bridges
hbls ligand-sidechain residue hydrogen bonds
hblb ligand-backbone residue hydrogen bonds
lwb ligand water bridges
lwb2 extended ligand water bridges
By default, the labels on the plot will reflect the residue identifier.
Optionally, a "residue-label" file can be supplied which indicates how residue
identifiers should be translated to flare-plot labels. The residue-label file is
a tab-separated text-file where each line has one field that indicates a colon-
separated residue identifier and one field that indicates the corresponding
flareplot label. Dots in the flareplot labels can be used to group and organize
labels. A valid residue-label file would look like this:
A:ARG:4 Root.Helix1.1x30
A:LYS:5 Root.Helix1.1x31
...
A:PRO:45 Root.Helix2.2x36
A:MET:46 Root.Helix2.2x37
...
The residue-label file can also act as a filter, as interactions between residues
that are not included in the file will be excluded from the plot. For
convenience it's not necessary to include the second column if the label file
is just used as a filter. A third column can be supplied indicating a color in
CSS-format (e.g. '#FF0000' or 'red').
"""
from contact_calc.flare import *
from contact_calc.transformations import *
import contact_calc.argparsers as ap
import sys
def main(argv=None):
"""
Main function called once at the end of this module. Configures and parses command line arguments, parses input
files and generates output files.
"""
# Parse command line arguments
import argparse
parser = ap.PrintUsageParser(description=__doc__)
optional = parser._action_groups.pop()
required = parser.add_argument_group('required arguments')
parser._action_groups.append(optional) # added this line
required.add_argument('--input',
required=True,
type=argparse.FileType('r'),
help='A multi-frame contact-file generated by dynamic_contact.py')
required.add_argument('--output',
required=False,
type=str,
help='The json file to write flare to')
optional.add_argument('--itypes',
required=False,
default=["all"],
type=str,
nargs='*',
help='Interaction types to include (comma separated list) [default: all]')
optional.add_argument('--flarelabels',
required=False,
default=None,
type=argparse.FileType('r'),
help='Flare-label file')
args = parser.parse_args(argv)
if args.output:
print("Parsing contact types %s from %s" % (str(args.itypes), args.input.name))
# Read contacts and generate graph
itypes = parse_itypes(args.itypes)
contacts, num_frames = parse_contacts(args.input, itypes)
labels, colors = parse_residuelabels(args.flarelabels)
graph = create_flare(contacts, labels, colors) # create_graph(contacts, labels)
args.input.close()
if args.flarelabels is not None:
args.flarelabels.close()
# Write output
if args.output:
write_json(graph, args.output)
print("Done. Wrote flare-json to %s" % args.output)
else:
write_json(graph, sys.stdout)
def parse_itypes(itypes):
"""Parses the itype argument and returns a set of strings with all the selected interaction types """
if "all" in itypes:
return set(["sb", "pc", "ps", "ts", "vdw", "hb", "lhb", "hbbb", "hbsb", "hbss", "wb", "wb2", "hbls", "hblb",
"lwb", "lwb2"])
return set(itypes)
# def create_graph(contacts, resi_labels):
# """
# Creates a graph from the contacts and residue labels formatted as a dict that can be trivially dumped to a json that
# can be read by flareplot. An "edge" key mapping to a list of edge specifiers with "name1", "name2", and "frames"
# attributes will always be generated and if `resi_labels` isn't `None` then the "trees" and "tracks" will be
# generated as well.
#
# Parameters
# ----------
# contacts : list of tuples of (str, str, tuple, tuple [[, tuple], tuple])
# Each entry specifies a frame-number, an interaction type, and 2 to 4 atom-tuples depending on the interaction
# type. Water mediated and water-water mediated interactions will have waters in the third and fourth tuples.
#
# resi_labels : dict of (str : dict of (str : str))
# Each key is a residue identifier and the associated value is a dictionary with the label, tree-path, and color
# that are consistent with the format of flareplots.
#
# Returns
# -------
# dict of str : list
# The types of the list contents varies depending on the key, but the format corresponds to the specifications of
# jsons used as input for flareplot. For example
# >>> {
# >>> "edges": [
# >>> {"name1": "ARG1", "name2": "ALA3", "frames": [0,4,10]},
# >>> {"name1": "ALA3", "name2": "THR2", "frames": [1,2]}
# >>> ],
# >>> "trees": [
# >>> {"treeName": "DefaultTree", "treePaths": ["Group1.ARG1", "Group1.THR2", "Group2.ALA3", "Group2.CYS4"]}
# >>> ],
# >>> "tracks": [
# >>> {"trackName": "DefaultTrack", "trackProperties": [
# >>> {"nodeName": "ARG1", "size": 1.0, "color": "red"},
# >>> {"nodeName": "THR2", "size": 1.0, "color": "red"},
# >>> {"nodeName": "ALA3", "size": 1.0, "color": "blue"},
# >>> {"nodeName": "CYS4", "size": 1.0, "color": "blue"}
# >>> ]}
# >>> ]
# >>> }
# """
# ret = {
# "edges": []
# }
#
# # print(resi_labels)
# # Strip atom3, atom4, and atom names
# # unique_chains = set([c[2][0] for c in contacts] + [c[3][0] for c in contacts])
# contacts = [(c[0], c[1], c[2][0:3], c[3][0:3]) for c in contacts]
#
# resi_edges = {}
# for contact in contacts:
# # Compose a key for atom1 and atom2 that ignores the order of residues
# a1_key = ":".join(contact[2][0:3])
# a2_key = ":".join(contact[3][0:3])
# if a1_key == a2_key:
# continue
# if a1_key > a2_key:
# a1_key, a2_key = a2_key, a1_key
# contact_key = a1_key + a2_key
#
# # Look up labels
# if resi_labels:
# if a1_key not in resi_labels or a2_key not in resi_labels:
# print("Omitting contact "+str(contact)+" as it doesn't appear in flare-label file")
# continue
# a1_label = resi_labels[a1_key]["label"]
# a2_label = resi_labels[a2_key]["label"]
# else:
# a1_label = a1_key
# a2_label = a2_key
#
# # Create contact_key if it doesn't exist
# if contact_key not in resi_edges:
# edge = {"name1": a1_label, "name2": a2_label, "frames": []}
# resi_edges[contact_key] = edge
# ret["edges"].append(edge)
#
# resi_edges[contact_key]["frames"].append(int(contact[0]))
#
# # Sort edge frames and ensure that there are no duplicates
# for e in ret["edges"]:
# e["frames"] = sorted(set(e["frames"]))
#
# # Create "trees" and "tracks" sections if resi_labels specified
# if resi_labels is not None:
# tree = {"treeLabel": "DefaultTree", "treePaths": []}
# ret["trees"] = [tree]
#
# track = {"trackLabel": "DefaultTrack", "trackProperties": []}
# ret["tracks"] = [track]
#
# for rlabel in resi_labels.values():
# tree["treePaths"].append(rlabel["treepath"])
# track["trackProperties"].append({
# "nodeName": rlabel["label"],
# "color": rlabel["color"],
# "size": 1.0
# })
#
# return ret
if __name__ == "__main__":
main()
__author__ = 'Rasmus Fonseca <[email protected]>'
__license__ = "Apache License 2.0"