root/galaxy-central/tools/mutation/visualize.py @ 2

リビジョン 2, 11.8 KB (コミッタ: hatakeyama, 14 年 前)

import galaxy-central

行番号 
1#!/usr/bin/env python
2
3'''
4Mutation Visualizer tool
5'''
6
7from __future__ import division
8
9import sys, csv, os, math
10import optparse
11
12from galaxy import eggs
13import pkg_resources
14pkg_resources.require( "SVGFig" )
15import svgfig as svg
16
17COLS_PER_SAMPLE = 7
18HEADER_COLS = 4
19
20HEIGHT = 6
21WIDTH = 12
22BAR_WIDTH = 1.5
23GAP = 2
24
25
26colors = {'A':'blue', 'C':'green', 'G':'orange', 'T':'red'}
27bases = ['A', 'C', 'G', 'T' ]
28
29SVGPan = """
30/**
31 *  SVGPan library 1.2
32 * ====================
33 *
34 * Given an unique existing element with id "viewport", including the
35 * the library into any SVG adds the following capabilities:
36 *
37 *  - Mouse panning
38 *  - Mouse zooming (using the wheel)
39 *  - Object dargging
40 *
41 * Known issues:
42 *
43 *  - Zooming (while panning) on Safari has still some issues
44 *
45 * Releases:
46 *
47 * 1.2, Sat Mar 20 08:42:50 GMT 2010, Zeng Xiaohui
48 *      Fixed a bug with browser mouse handler interaction
49 *
50 * 1.1, Wed Feb  3 17:39:33 GMT 2010, Zeng Xiaohui
51 *      Updated the zoom code to support the mouse wheel on Safari/Chrome
52 *
53 * 1.0, Andrea Leofreddi
54 *      First release
55 *
56 * This code is licensed under the following BSD license:
57 *
58 * Copyright 2009-2010 Andrea Leofreddi (a.leofreddi@itcharm.com). All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without modification, are
61 * permitted provided that the following conditions are met:
62 *
63 *    1. Redistributions of source code must retain the above copyright notice, this list of
64 *       conditions and the following disclaimer.
65 *
66 *    2. Redistributions in binary form must reproduce the above copyright notice, this list
67 *       of conditions and the following disclaimer in the documentation and/or other materials
68 *       provided with the distribution.
69 *
70 * THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi ``AS IS'' AND ANY EXPRESS OR IMPLIED
71 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
72 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR
73 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
74 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
75 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
76 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
77 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
78 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79 *
80 * The views and conclusions contained in the software and documentation are those of the
81 * authors and should not be interpreted as representing official policies, either expressed
82 * or implied, of Andrea Leofreddi.
83 */
84
85var root = document.documentElement;
86
87var state = 'none', stateTarget, stateOrigin, stateTf;
88
89setupHandlers(root);
90
91/**
92 * Register handlers
93 */
94function setupHandlers(root){
95        setAttributes(root, {
96                "onmouseup" : "add(evt)",
97                "onmousedown" : "handleMouseDown(evt)",
98                "onmousemove" : "handleMouseMove(evt)",
99                "onmouseup" : "handleMouseUp(evt)",
100                //"onmouseout" : "handleMouseUp(evt)", // Decomment this to stop the pan functionality when dragging out of the SVG element
101        });
102
103        if(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0)
104                window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari
105        else
106                window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
107}
108
109/**
110 * Instance an SVGPoint object with given event coordinates.
111 */
112function getEventPoint(evt) {
113        var p = root.createSVGPoint();
114
115        p.x = evt.clientX;
116        p.y = evt.clientY;
117
118        return p;
119}
120
121/**
122 * Sets the current transform matrix of an element.
123 */
124function setCTM(element, matrix) {
125        var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
126
127        element.setAttribute("transform", s);
128}
129
130/**
131 * Dumps a matrix to a string (useful for debug).
132 */
133function dumpMatrix(matrix) {
134        var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\\n  " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\\n  0, 0, 1 ]";
135
136        return s;
137}
138
139/**
140 * Sets attributes of an element.
141 */
142function setAttributes(element, attributes){
143        for (i in attributes)
144                element.setAttributeNS(null, i, attributes[i]);
145}
146
147/**
148 * Handle mouse move event.
149 */
150function handleMouseWheel(evt) {
151        if(evt.preventDefault)
152                evt.preventDefault();
153
154        evt.returnValue = false;
155
156        var svgDoc = evt.target.ownerDocument;
157
158        var delta;
159
160        if(evt.wheelDelta)
161                delta = evt.wheelDelta / 3600; // Chrome/Safari
162        else
163                delta = evt.detail / -90; // Mozilla
164
165        var z = 1 + delta; // Zoom factor: 0.9/1.1
166
167        var g = svgDoc.getElementById("viewport");
168       
169        var p = getEventPoint(evt);
170
171        p = p.matrixTransform(g.getCTM().inverse());
172
173        // Compute new scale matrix in current mouse position
174        var k = root.createSVGMatrix().translate(p.x, p.y).scale(z).translate(-p.x, -p.y);
175
176        setCTM(g, g.getCTM().multiply(k));
177
178        stateTf = stateTf.multiply(k.inverse());
179}
180
181/**
182 * Handle mouse move event.
183 */
184function handleMouseMove(evt) {
185        if(evt.preventDefault)
186                evt.preventDefault();
187
188        evt.returnValue = false;
189
190        var svgDoc = evt.target.ownerDocument;
191
192        var g = svgDoc.getElementById("viewport");
193
194        if(state == 'pan') {
195                // Pan mode
196                var p = getEventPoint(evt).matrixTransform(stateTf);
197
198                setCTM(g, stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
199        } else if(state == 'move') {
200                // Move mode
201                var p = getEventPoint(evt).matrixTransform(g.getCTM().inverse());
202
203                setCTM(stateTarget, root.createSVGMatrix().translate(p.x - stateOrigin.x, p.y - stateOrigin.y).multiply(g.getCTM().inverse()).multiply(stateTarget.getCTM()));
204
205                stateOrigin = p;
206        }
207}
208
209/**
210 * Handle click event.
211 */
212function handleMouseDown(evt) {
213        if(evt.preventDefault)
214                evt.preventDefault();
215
216        evt.returnValue = false;
217
218        var svgDoc = evt.target.ownerDocument;
219
220        var g = svgDoc.getElementById("viewport");
221
222        if(evt.target.tagName == "svg") {
223                // Pan mode
224                state = 'pan';
225
226                stateTf = g.getCTM().inverse();
227
228                stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
229        }
230        /*else {
231                // Move mode
232                state = 'move';
233
234                stateTarget = evt.target;
235
236                stateTf = g.getCTM().inverse();
237
238                stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
239        }*/
240}
241/**
242 * Handle mouse button release event.
243 */
244function handleMouseUp(evt) {
245        if(evt.preventDefault)
246                evt.preventDefault();
247
248        evt.returnValue = false;
249
250        var svgDoc = evt.target.ownerDocument;
251
252        if(state == 'pan' || state == 'move') {
253                // Quit pan mode
254                state = '';
255        }
256}
257"""
258
259
260def mainsvg(opts, args):
261    s = svg.SVG('g', id='viewport')
262   
263    # display legend
264    for i, b in enumerate( bases ):
265        bt = svg.SVG("tspan", b, style="font-family:Verdana;font-size:20%")
266        s.append(svg.SVG("text", bt, x=12+(i*10), y=3, stroke="none", fill="black"))
267        s.append(svg.SVG("rect", x=14+(i*10), y=0, width=4, height=3,
268                         stroke="none", fill=colors[b], fill_opacity=0.5))
269
270    reader = open(opts.input_file, 'U')
271
272    samples = []
273    for i in range(int(len(args)/3)):
274        index = i*3
275        samples.append(dict(name=args[index],
276                            a_col=args[index+1],
277                            totals_col=args[index+2]))
278
279    if opts.zoom == 'interactive':
280        y = 35
281    else:
282        y = 25
283    for i, sample in enumerate(samples):
284        x = 23+(i*(WIDTH+GAP))
285        t = svg.SVG("text", svg.SVG("tspan", sample['name'], style="font-family:Verdana;font-size:25%"),
286                    x=x, y=y, transform="rotate(-90 %i,%i)" % (x, y), stroke="none", fill="black")
287        s.append(t)
288   
289    count=1
290    for line in reader:
291        row = line.split('\t')
292        highlighted_position = False
293        show_pos = True
294        position = row[int(opts.position_col)-1]
295        ref = row[int(opts.ref_col)-1]
296        # display positions
297        if opts.zoom == 'interactive':
298            textx = 0
299        else:
300            textx = 7
301        bt = svg.SVG("tspan", str(position), style="font-family:Verdana;font-size:25%")
302        s.append(svg.SVG("text", bt, x=textx, y=34+(count*(HEIGHT+GAP)), stroke="none", fill="black"))
303        s.append(svg.SVG("rect", x=0, y=30+(count*(HEIGHT+GAP)), width=14, height=HEIGHT,
304                         stroke='none', fill=colors[ref.upper()], fill_opacity=0.2))
305       
306        for sample_index, sample in enumerate(samples):
307            n_a = int(row[int(sample['a_col'])-1])
308            n_c = int(row[int(sample['a_col'])+1-1])
309            n_g = int(row[int(sample['a_col'])+2-1])
310            n_t = int(row[int(sample['a_col'])+3-1])
311            total = int(row[int(sample['totals_col'])-1])
312            imp = 1 #int(row[start_col+6])
313            if total:
314                x = 16+(sample_index*(WIDTH+GAP))
315                y = 30+(count*(HEIGHT+GAP))
316                width = WIDTH
317                height = HEIGHT
318               
319                if imp == 1:
320                    fill_opacity = 0.1
321                elif imp == 2:
322                    fill_opacity = 0.2
323                else:
324                    fill_opacity = 0.3
325
326                if count%2:
327                    s.append(svg.SVG("rect", x=x, y=y, width=width, height=height,
328                                     stroke='none', fill='grey', fill_opacity=0.25))
329                else:
330                    s.append(svg.SVG("rect", x=x, y=y, width=width, height=height,
331                                     stroke='none', fill='grey', fill_opacity=0.25))
332               
333                for base, value in enumerate([n_a, n_c, n_g, n_t]):
334                    width = int(math.ceil(value / total * WIDTH))
335                    s.append(svg.SVG("rect", x=x, y=y, width=width, height=BAR_WIDTH,
336                                     stroke='none', fill=colors[bases[base]], fill_opacity=0.6))
337                    y = y + BAR_WIDTH
338
339        count=count+1
340       
341    if opts.zoom == 'interactive':
342        canv = svg.canvas(s)
343        canv.save(opts.output_file)
344        import fileinput
345        flag = False
346        for line in fileinput.input(opts.output_file, inplace=1):
347            if line.startswith('<svg'):
348                print '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">'
349                flag = True
350                continue
351            else:
352                if flag:
353                    print '<script type="text/javascript">%s</script>' % SVGPan
354                flag = False
355            print line,
356    else:
357        zoom = int(opts.zoom)
358        w = "%ipx" % (x*(10+zoom))
359        h = "%ipx" % (y*(2+zoom))
360        canv = svg.canvas(s, width=w, height=h, viewBox="0 0 %i %i" %(x+100, y+100))
361        canv.save(opts.output_file)
362
363if __name__ == '__main__':
364    parser = optparse.OptionParser()
365    parser.add_option('-i', '--input-file', dest='input_file', action='store')
366    parser.add_option('-o', '--output-file', dest='output_file', action='store')
367    parser.add_option('-z', '--zoom', dest='zoom', action='store', default='1')
368    parser.add_option('-p', '--position_col', dest='position_col', action='store', default='c0')
369    parser.add_option('-r', '--ref_col', dest='ref_col', action='store', default='c1')
370    (opts, args) = parser.parse_args()
371    mainsvg(opts, args)
372    sys.exit(1)
373
374   
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。