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