|
0
|
1 #!/usr/bin/env python
|
|
|
2 """ROI Table Generator
|
|
|
3
|
|
|
4 Generates a HTML page with a table of ROI record details. Besides showing the
|
|
|
5 numeric ROI information, it also gives little roi plots in a column.
|
|
|
6
|
|
|
7 For the little ROI plots, it calls the program roi_plot_thumbnails that has to
|
|
|
8 be in the PATH.
|
|
|
9 """
|
|
|
10
|
|
|
11 __author__ = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
|
|
|
12 __copyright__ = 'Copyring 2013, Freie Universitaet Berlin'
|
|
|
13 __license__ = 'BSD 3-clause'
|
|
|
14
|
|
|
15
|
|
|
16 # TODO(holtgrew): Actually call roi_plot_thumbnails
|
|
|
17 # TODO(holtgrew): from __future__ use print_function
|
|
|
18
|
|
|
19
|
|
5
|
20 try:
|
|
|
21 import argparse
|
|
|
22 except ImportError:
|
|
|
23 import argparse26 as argparse
|
|
0
|
24 import math
|
|
|
25 import os.path
|
|
|
26 import sys
|
|
|
27
|
|
|
28 import Cheetah.Template
|
|
|
29
|
|
|
30 import ngs_roi.app
|
|
|
31 import ngs_roi.argparse
|
|
|
32 import ngs_roi.io
|
|
|
33
|
|
|
34
|
|
|
35 # Main template.
|
|
|
36 PAGE_TPL = """
|
|
|
37 <html>
|
|
|
38 <head><title>ROI Table</title></head>
|
|
|
39 <body>
|
|
|
40 <h1>ROI Table</h1>
|
|
|
41 $table
|
|
1
|
42 <div><code>$args</code></div>
|
|
0
|
43 </body>
|
|
|
44 </html>
|
|
|
45 """
|
|
|
46
|
|
|
47 # Template for a table.
|
|
|
48 TABLE_TPL = """
|
|
|
49 <table border="1">
|
|
|
50 <tr>
|
|
|
51 <th>plot</th>
|
|
|
52 <th>chr</th>
|
|
|
53 <th>start</th>
|
|
|
54 <th>end</th>
|
|
|
55 <th>name</th>
|
|
|
56 <th>length</th>
|
|
|
57 <th>strand</th>
|
|
|
58 <th>max_count</th>
|
|
|
59 #for i, key in enumerate($data_keys)
|
|
|
60 <th>$key</th>
|
|
|
61 #end for
|
|
|
62 </tr>
|
|
|
63 #for id, roi in enumerate($records)
|
|
|
64 <tr>
|
|
|
65 <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>
|
|
|
66 <td>$roi.ref</td>
|
|
|
67 <td style="text-align:right;">$fmtPos($roi.start_pos + 1)</td>
|
|
|
68 <td style="text-align:right;">$fmtPos($roi.end_pos)</td>
|
|
|
69 <td><a href="$href($roi)">$roi.region_name</a></td>
|
|
|
70 <td style="text-align:right;">$fmtPos($roi.region_length)</td>
|
|
|
71 <td style="text-align:center;">$roi.strand</td>
|
|
|
72 <td style="text-align:right;">$roi.max_count</td>
|
|
|
73 #for i, key in enumerate($data_keys)
|
|
|
74 <td>$roi.data[$i]</td>
|
|
|
75 #end for
|
|
|
76 </tr>
|
|
|
77 #end for
|
|
|
78 </table>
|
|
|
79 """
|
|
|
80
|
|
|
81
|
|
|
82 class RoiTable(object):
|
|
|
83 """A table of ROI records with small plots."""
|
|
|
84
|
|
|
85 def __init__(self, args, keys, records, app):
|
|
|
86 self.args = args
|
|
|
87 self.keys = keys
|
|
|
88 self.records = records
|
|
|
89 self.app = app
|
|
|
90
|
|
|
91 def tplFuncs(self):
|
|
|
92 def intWithCommas(x):
|
|
|
93 if type(x) not in [type(0), type(0L)]:
|
|
|
94 raise TypeError("Parameter must be an integer.")
|
|
|
95 if x < 0:
|
|
|
96 return '-' + intWithCommas(-x)
|
|
|
97 result = ''
|
|
|
98 while x >= 1000:
|
|
|
99 x, r = divmod(x, 1000)
|
|
|
100 result = ",%03d%s" % (r, result)
|
|
|
101 return "%d%s" % (x, result)
|
|
|
102
|
|
|
103 def imgId(idx):
|
|
|
104 """Image id from roi record id."""
|
|
|
105 return idx / (self.args.num_rows * self.args.num_cols)
|
|
|
106
|
|
|
107 def imgX(idx):
|
|
|
108 """x position in image from record id."""
|
|
|
109 x = idx % self.args.num_cols
|
|
|
110 res = x * self.args.plot_width
|
|
|
111 if x > 0:
|
|
|
112 res += (x - 1) * 2
|
|
|
113 return res
|
|
|
114
|
|
|
115 def imgY(idx):
|
|
|
116 """y position in image from record id."""
|
|
|
117 y = idx / self.args.num_cols
|
|
|
118 res = y * self.args.plot_height
|
|
|
119 res += y * 2
|
|
|
120 return res
|
|
|
121
|
|
|
122 return {'fmtPos': intWithCommas, 'imgId': imgId, 'imgX': imgX, 'imgY': imgY}
|
|
|
123
|
|
|
124 def render(self):
|
|
|
125 """Returns string with rendered table."""
|
|
|
126 vals = {'data_keys': self.keys, 'records': self.records, 'args': self.args,
|
|
|
127 'href': lambda x:self.app.buildHref(x.ref, x.start_pos, x.end_pos)}
|
|
|
128 vals.update(self.tplFuncs())
|
|
|
129 t = Cheetah.Template.Template(TABLE_TPL, searchList=vals)
|
|
|
130 return str(t)
|
|
|
131
|
|
|
132
|
|
|
133 class TableApp(ngs_roi.app.App):
|
|
|
134 def __init__(self, args):
|
|
|
135 # Call parent's constructor and create output directory.
|
|
|
136 ngs_roi.app.App.__init__(self, args)
|
|
|
137 self.prepareOutDir()
|
|
|
138
|
|
|
139 def run(self):
|
|
|
140 # Load ROI records.
|
|
|
141 print >>sys.stderr, 'Loading ROI'
|
|
|
142 records = ngs_roi.io.load(self.args.in_file, self.args.max_rois)
|
|
|
143 keys = []
|
|
|
144 if records:
|
|
|
145 keys = records[0].data_keys
|
|
|
146
|
|
|
147 # Create plots.
|
|
|
148 print >>sys.stderr, 'Creating plots...'
|
|
|
149 runner = ngs_roi.app.PlotThumbnailsRunner(self.args)
|
|
|
150 runner.run()
|
|
|
151
|
|
|
152 # Create table.
|
|
|
153 print >>sys.stderr, 'Creating table...'
|
|
|
154 self.createHtml(self.args.out_file, keys, records)
|
|
|
155 return 0
|
|
|
156
|
|
|
157 def createHtml(self, file_name, keys, records):
|
|
|
158 print >>sys.stderr, 'Writing %s' % self.args.out_file
|
|
4
|
159 vals = {'table': RoiTable(self.args, keys, records, self).render(),
|
|
|
160 'args': self.args}
|
|
0
|
161 t = Cheetah.Template.Template(PAGE_TPL, searchList=vals)
|
|
|
162 with open(self.args.out_file, 'wb') as f:
|
|
4
|
163 f.write(str(t))
|
|
0
|
164
|
|
|
165
|
|
|
166 def main():
|
|
|
167 parser = argparse.ArgumentParser(description='Plot ROI file.')
|
|
|
168
|
|
|
169 ngs_roi.argparse.addFileArguments(parser)
|
|
|
170 ngs_roi.argparse.addPlotGridArguments(parser, default_plot_height=60,
|
|
|
171 default_plot_width=90)
|
|
|
172 ngs_roi.argparse.addLinkArguments(parser)
|
|
|
173 args = parser.parse_args()
|
|
|
174 ngs_roi.argparse.applyFileDefaults(args)
|
|
|
175
|
|
|
176 app = TableApp(args)
|
|
|
177 return app.run()
|
|
|
178
|
|
|
179
|
|
|
180 if __name__ == '__main__':
|
|
|
181 sys.exit(main())
|