forked from joiningdata/lollipops
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
225 lines (189 loc) · 8.14 KB
/
main.go
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
223
224
225
//
// Lollipops command-line diagram generator for genetic variations.
// Copyright (C) 2015 Jeremy Jay <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Command lollipops provides a command-line interface for generating lollipop-style
// genetic variation diagrams. It should be suitable for various scriptable pipelines
// and other internal workflows.
package main
import (
"flag"
"fmt"
"os"
"path"
"strings"
"github.com/inconshreveable/mousetrap"
"github.com/pbnjay/lollipops/data"
"github.com/pbnjay/lollipops/drawing"
)
var (
queryDB = flag.String("Q", "GENENAME", "Uniprot query database when -U not used")
uniprot = flag.String("U", "", "Uniprot accession instead of GENE_SYMBOL")
output = flag.String("o", "", "output SVG/PNG file (default GENE_SYMBOL.svg)")
width = flag.Int("w", 0, "output width (default automatic fit labels)")
dpi = flag.Float64("dpi", 72, "output DPI for PNG rasterization")
showLegend = flag.Bool("legend", false, "draw a legend for colored regions")
showLabels = flag.Bool("labels", false, "draw mutation labels above lollipops")
showDisordered = flag.Bool("show-disordered", false, "draw disordered regions on the backbone")
showMotifs = flag.Bool("show-motifs", false, "draw simple motif regions")
hideAxis = flag.Bool("hide-axis", false, "do not draw the aa position axis")
noPatterns = flag.Bool("no-patterns", false, "use solid fill instead of patterns for SVG output")
domainLabels = flag.String("domain-labels", "truncated", "how to apply domain labels")
synColor = flag.String("syn-color", "#0000ff", "color to use for synonymous lollipops")
mutColor = flag.String("mut-color", "#ff0000", "color to use for non-synonymous lollipops")
fontPath = flag.String("f", "", "Path to truetype font to use for drawing (defaults to Arial.ttf)")
localPath = flag.String("l", "", "Path to local json graphic data (Pfam response format)")
)
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [options] {-Q UNIPROT_DB IDENTIFER | -U UNIPROT_ID | GENE_SYMBOL} [PROTEIN CHANGES ...]\n", os.Args[0])
fmt.Fprintln(os.Stderr, `
Protein ID input:
GENE_SYMBOL is the official human HGNC gene symbol. This will use the
UniprotKB API to lookup the UNIPROT_ID.
You can provide a UniProt ID directly with -U (e.g. "-U P04637" for TP53)
For more advanced usage, query UniprotKB's database mappings directly using
a supported identifier with -Q DBNAME. Available DBNAMEs can be found here:
http://www.uniprot.org/help/programmatic_access#id_mapping_examples
RefSeq ID e.g. -Q P_REFSEQ_AC NP_001265252.1
Entrez GeneID e.g. -Q P_ENTREZGENEID 4336
Ensembl ID e.g. -Q ENSEMBL_ID ENSG00000168314
Protein changes:
Currently only point mutations are supported, and may be specified as:
<AMINO><CODON><AMINO><#COLOR><@COUNT>
Only CODON is required, and AMINO tags are not parsed.
Synonymous mutations are denoted if the first AMINO tag matches the second
AMINO tag, or if the second tag is not present. Otherwise the non-synonymous
mutation color is used. The COLOR tag will override using the #RRGGBB style
provided. The COUNT tag can be used to scale the lollipop marker size so that
the area is exponentially proportional to the count indicated. Examples:
R273C -- non-synonymous mutation at codon 273
T125@5 -- synonymous mutation at codon 125 with "5x" marker sizing
R248Q#00ff00 -- green lollipop at codon 248
R248Q#00ff00@131 -- green lollipop at codon 248 with "131x" marker sizing
(N.B. color must come before count in tags)
Diagram generation options:
-legend draw a legend for colored regions
-syn-color="#0000ff" color to use for synonymous mutation markers
-mut-color="#ff0000" color to use for non-synonymous mutation markers
-hide-axis do not draw the amino position x-axis
-show-disordered draw disordered regions on the backbone
-show-motifs draw simple motif regions
-labels draw label text above lollipop markers
-no-patterns use solid fill instead of patterns (SVG only)
-domain-labels=fit hot to apply domain labels (default="truncated")
"fit" = only if fits in space available
"off" = do not draw text in the domains
Output options:
-o=filename.png set output filename (.png or .svg supported)
-w=700 set diagram pixel width (default = automatic fit)
-dpi=300 set DPI (PNG output only)
Local file input:
-l=filename.json use local file instead of Pfam API for graphic data
see: http://pfam.xfam.org/help#tabview=tab9
`)
}
flag.Parse()
drawing.DefaultSettings.ShowLegend = *showLegend
drawing.DefaultSettings.ShowLabels = *showLabels
drawing.DefaultSettings.HideDisordered = !*showDisordered
drawing.DefaultSettings.HideMotifs = !*showMotifs
drawing.DefaultSettings.HideAxis = *hideAxis
drawing.DefaultSettings.SolidFillOnly = *noPatterns
drawing.DefaultSettings.DomainLabelStyle = *domainLabels
drawing.DefaultSettings.SynonymousColor = *synColor
drawing.DefaultSettings.MutationColor = *mutColor
drawing.DefaultSettings.GraphicWidth = float64(*width)
if *fontPath == "" {
err := drawing.LoadDefaultFont()
if err != nil {
fmt.Fprintln(os.Stderr, "ERROR: Unable to find Arial.ttf - Which is required for accurate font sizing.")
fmt.Fprintln(os.Stderr, " Please use -f=/path/to/arial.ttf or the TrueType (.ttf) font of your choice.")
// continue in the hopes that SVG rendering will be ok...
//os.Exit(1)
}
} else {
fname := path.Base(*fontPath)
fname = strings.TrimSuffix(fname, path.Ext(fname))
err := drawing.LoadFont(fname, *fontPath)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
var err error
varStart := 0
acc := ""
geneSymbol := ""
if *uniprot == "" && flag.NArg() > 0 {
geneSymbol = flag.Arg(0)
varStart = 1
if *queryDB == "GENENAME" {
fmt.Fprintln(os.Stderr, "HGNC Symbol: ", flag.Arg(0))
acc, err = data.GetProtID(flag.Arg(0))
} else {
fmt.Fprintln(os.Stderr, "Searching for ID: ", flag.Arg(0))
acc, err = data.GetProtMapping(*queryDB, flag.Arg(0))
}
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Fprintln(os.Stderr, "Uniprot/SwissProt Accession: ", acc)
}
if *uniprot != "" {
acc = *uniprot
}
if flag.NArg() == 0 && *uniprot == "" {
flag.Usage()
if mousetrap.StartedByExplorer() {
fmt.Fprintln(os.Stderr, `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
This is a command-line utility for pipeline processing, you probably don't want
to double-click it! Open your command prompt with 'cmd.exe' and try again.
Press Enter/Ctrl-C to quit.`)
fmt.Scanln(&acc)
}
os.Exit(1)
}
var d *data.PfamGraphicResponse
if *localPath != "" {
d, err = data.GetLocalPfamGraphicData(*localPath)
} else {
d, err = data.GetPfamGraphicData(acc)
}
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if geneSymbol == "" {
geneSymbol = d.Metadata.Identifier
fmt.Fprintln(os.Stderr, "Pfam Symbol: ", geneSymbol)
}
if *output == "" {
*output = geneSymbol + ".svg"
}
f, err := os.OpenFile(*output, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer f.Close()
fmt.Fprintln(os.Stderr, "Drawing diagram to", *output)
if strings.HasSuffix(strings.ToLower(*output), ".png") {
drawing.DrawPNG(f, *dpi, flag.Args()[varStart:], d)
} else {
drawing.DrawSVG(f, flag.Args()[varStart:], d)
}
}