File: roi_table.py

package info (click to toggle)
seqan2 2.4.0%2Bdfsg-16
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 224,180 kB
  • sloc: cpp: 256,886; ansic: 91,672; python: 8,330; sh: 995; xml: 570; makefile: 252; awk: 51; javascript: 21
file content (181 lines) | stat: -rwxr-xr-x 5,272 bytes parent folder | download | duplicates (3)
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
#!/usr/bin/env python3
"""ROI Table Generator

Generates a HTML page with a table of ROI record details.  Besides showing the
numeric ROI information, it also gives little roi plots in a column.

For the little ROI plots, it calls the program roi_plot_thumbnails that has to
be in the PATH.
"""

__author__    = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
__copyright__ = 'Copyring 2013, Freie Universitaet Berlin'
__license__   = 'BSD 3-clause'


# TODO(holtgrew): Actually call roi_plot_thumbnails
# TODO(holtgrew): from __future__ use print_function


try:
    import argparse
except ImportError:
    import argparse26 as argparse
import math
import os.path
import sys

import Cheetah.Template

import ngs_roi.app
import ngs_roi.argparse
import ngs_roi.io


# Main template.
PAGE_TPL = """
<html>
  <head><title>ROI Table</title></head>
  <body>
    <h1>ROI Table</h1>
    $table
    <div><code>$args</code></div>
  </body>
</html>
"""

# Template for a table.
TABLE_TPL = """
<table border="1">
  <tr>
    <th>plot</th>
    <th>chr</th>
    <th>start</th>
    <th>end</th>
    <th>name</th>
    <th>length</th>
    <th>strand</th>
    <th>max_count</th>
    #for i, key in enumerate($data_keys)
    <th>$key</th>
    #end for
  </tr>
  #for id, roi in enumerate($records)
  <tr>
    <td><div style="width:${args.plot_width}; margin:2px; height:${args.plot_height+1}; background:url(thumbnail_${imgId($id)}.png) -${imgX($id)} -${imgY($id)};"></div></td>
    <td>$roi.ref</td>
    <td style="text-align:right;">$fmtPos($roi.start_pos + 1)</td>
    <td style="text-align:right;">$fmtPos($roi.end_pos)</td>
    <td><a href="$href($roi)">$roi.region_name</a></td>
    <td style="text-align:right;">$fmtPos($roi.region_length)</td>
    <td style="text-align:center;">$roi.strand</td>
    <td style="text-align:right;">$roi.max_count</td>
    #for i, key in enumerate($data_keys)
    <td>$roi.data[$i]</td>
    #end for
  </tr>
  #end for
</table>
"""


class RoiTable(object):
    """A table of ROI records with small plots."""

    def __init__(self, args, keys, records, app):
        self.args = args
        self.keys = keys
        self.records = records
        self.app = app

    def tplFuncs(self):
        def intWithCommas(x):
            if type(x) not in [type(0), type(0)]:
                raise TypeError("Parameter must be an integer.")
            if x < 0:
                return '-' + intWithCommas(-x)
            result = ''
            while x >= 1000:
                x, r = divmod(x, 1000)
                result = ",%03d%s" % (r, result)
            return "%d%s" % (x, result)

        def imgId(idx):
            """Image id from roi record id."""
            return idx / (self.args.num_rows * self.args.num_cols)

        def imgX(idx):
            """x position in image from record id."""
            x = idx % self.args.num_cols
            res = x * self.args.plot_width
            if x > 0:
                res += (x - 1) * 2
            return res

        def imgY(idx):
            """y position in image from record id."""
            y = idx / self.args.num_cols
            res = y * self.args.plot_height
            res += y * 2
            return res

        return {'fmtPos': intWithCommas, 'imgId': imgId, 'imgX': imgX, 'imgY': imgY}

    def render(self):
        """Returns string with rendered table."""
        vals = {'data_keys': self.keys, 'records': self.records, 'args': self.args,
                'href': lambda x:self.app.buildHref(x.ref, x.start_pos, x.end_pos)}
        vals.update(self.tplFuncs())
        t = Cheetah.Template.Template(TABLE_TPL, searchList=vals)
        return str(t)


class TableApp(ngs_roi.app.App):
    def __init__(self, args):
        # Call parent's constructor and create output directory.
        ngs_roi.app.App.__init__(self, args)
        self.prepareOutDir()

    def run(self):
        # Load ROI records.
        print('Loading ROI', file=sys.stderr)
        records = ngs_roi.io.load(self.args.in_file, self.args.max_rois)
        keys = []
        if records:
            keys = records[0].data_keys

        # Create plots.
        print('Creating plots...', file=sys.stderr)
        runner = ngs_roi.app.PlotThumbnailsRunner(self.args)
        runner.run()

        # Create table.
        print('Creating table...', file=sys.stderr)
        self.createHtml(self.args.out_file, keys, records)
        return 0

    def createHtml(self, file_name, keys, records):
        print('Writing %s' % self.args.out_file, file=sys.stderr)
        vals = {'table': RoiTable(self.args, keys, records, self).render(),
                'args': self.args}
        t = Cheetah.Template.Template(PAGE_TPL, searchList=vals)
        with open(self.args.out_file, 'wb') as f:
            f.write(str(t))


def main():
    parser = argparse.ArgumentParser(description='Plot ROI file.')

    ngs_roi.argparse.addFileArguments(parser)
    ngs_roi.argparse.addPlotGridArguments(parser, default_plot_height=60,
                                          default_plot_width=90)
    ngs_roi.argparse.addLinkArguments(parser)
    args = parser.parse_args()
    ngs_roi.argparse.applyFileDefaults(args)

    app = TableApp(args)
    return app.run()


if __name__ == '__main__':
    sys.exit(main())