Mercurial > repos > holtgrewe > ngs_roi
comparison roi_plot_thumbnails.py @ 0:61d9bdb6d519 draft
Uploaded
| author | holtgrewe |
|---|---|
| date | Thu, 18 Apr 2013 08:03:38 -0400 |
| parents | |
| children | 0ac4f6f3d984 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:61d9bdb6d519 |
|---|---|
| 1 #!/usr/bin/env python | |
| 2 """Thumbnail Plot Generator. | |
| 3 | |
| 4 This report generator uses the binary roi_plot_thumbnails (C++ program, must | |
| 5 be in PATH) to generate many PNG images with small ROI plots. It then creates | |
| 6 a HTML file that includes the PNG and adds an overlay image link map such that | |
| 7 when the user clicks on a plot, she is transfered to the according position in | |
| 8 a local IGV or the UCSC genome browser, for example. | |
| 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 # TODO(holtgrew): Use Cheetah templates to generate HTML. | |
| 16 # TODO(holtgrew): Call roi_plot_thumbnails from Python script. | |
| 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 ngs_roi.app | |
| 26 import ngs_roi.argparse | |
| 27 import ngs_roi.io | |
| 28 | |
| 29 | |
| 30 class LinkRegion(object): | |
| 31 """Region on picture with genomic interval.""" | |
| 32 | |
| 33 def __init__(self, x1, y1, x2, y2, ref, begin_pos, end_pos): | |
| 34 self.x1 = x1 | |
| 35 self.x2 = x2 | |
| 36 self.y1 = y1 | |
| 37 self.y2 = y2 | |
| 38 self.ref = ref | |
| 39 self.begin_pos = begin_pos | |
| 40 self.end_pos = end_pos | |
| 41 | |
| 42 | |
| 43 class RoiPlotGrid(object): | |
| 44 """A grid of ROI plots. | |
| 45 | |
| 46 width -- width one one plot | |
| 47 height -- height of one plot | |
| 48 """ | |
| 49 | |
| 50 # Border in each direction. | |
| 51 BORDER = 0 | |
| 52 # Spacing between plots. | |
| 53 SPACE = 2 | |
| 54 | |
| 55 def __init__(self, width, height, columns, rows, bg_plot=(0, 0, 0, 10), | |
| 56 frame_col=(80, 80, 80, 255), fg_col=(0, 0, 0, 255)): | |
| 57 # Properties of the grid. | |
| 58 self.width = float(width) | |
| 59 self.height = float(height) | |
| 60 self.columns = columns | |
| 61 self.rows = rows | |
| 62 # State. | |
| 63 self.idx = 0 # currently drawn plot | |
| 64 self.canvas_width = 2 * self.BORDER + columns * width + (columns - 1) * self.SPACE | |
| 65 self.canvas_height = 2 * self.BORDER + rows * height + (rows - 1) * self.SPACE | |
| 66 # Colors. | |
| 67 self.bg_plot = bg_plot | |
| 68 self.frame_col = frame_col | |
| 69 self.fg_color = fg_col | |
| 70 # List of link region for image map. | |
| 71 self.link_regions = [] | |
| 72 | |
| 73 def plotStart(self, idx): | |
| 74 """Return pair with start coordinates of plot.""" | |
| 75 row = idx / self.columns | |
| 76 col = idx % self.columns | |
| 77 x = self.BORDER + col * (self.width + self.SPACE) | |
| 78 y = self.BORDER + row * (self.height + self.SPACE) | |
| 79 return x, y | |
| 80 | |
| 81 def plotRecord(self, record): | |
| 82 """Register plotting of a record.""" | |
| 83 start_x, start_y = self.plotStart(self.idx) | |
| 84 self.idx += 1 | |
| 85 # Register link region. | |
| 86 self.link_regions.append(LinkRegion( | |
| 87 start_x, start_y, start_x + self.width, start_y + self.height, | |
| 88 record.ref, record.start_pos, record.end_pos)) | |
| 89 | |
| 90 | |
| 91 class GridLinks(object): | |
| 92 """Link information for one grid.""" | |
| 93 | |
| 94 def __init__(self, file_name, link_regions): | |
| 95 self.file_name = file_name | |
| 96 self.link_regions = link_regions | |
| 97 | |
| 98 | |
| 99 class PlotThumbnailsApp(ngs_roi.app.App): | |
| 100 def __init__(self, args): | |
| 101 # Call parent's constructor. | |
| 102 ngs_roi.app.App.__init__(self, args) | |
| 103 self.prepareOutDir() | |
| 104 # Initialize members. | |
| 105 self.grid = None | |
| 106 self.plot_idx = 0 | |
| 107 self.grid_links = [] | |
| 108 | |
| 109 def run(self): | |
| 110 # Load ROI records. | |
| 111 print >>sys.stderr, 'Loading ROI' | |
| 112 | |
| 113 # Create plots. | |
| 114 runner = ngs_roi.app.PlotThumbnailsRunner(self.args) | |
| 115 runner.run() | |
| 116 | |
| 117 # Create HTML. | |
| 118 print >>sys.stderr, 'Creating HTML...' | |
| 119 num_plots = self.args.num_cols * self.args.num_rows # plots on grid | |
| 120 for i, roi in enumerate(ngs_roi.io.RoiFile(self.args.in_file)): | |
| 121 if self.args.max_rois > 0 and i >= self.args.max_rois: | |
| 122 break | |
| 123 # Write out old grid (if any) and create new one. | |
| 124 if i % num_plots == 0: | |
| 125 if self.grid: | |
| 126 print >>sys.stderr, ' Writing plot %d...' % self.plot_idx | |
| 127 self.writeGrid() | |
| 128 self.grid = RoiPlotGrid(self.args.plot_width, self.args.plot_height, | |
| 129 self.args.num_cols, self.args.num_rows) | |
| 130 # Put the next plot on the grid. | |
| 131 self.grid.plotRecord(roi) | |
| 132 print >>sys.stderr, ' Writing plot %d...' % self.plot_idx | |
| 133 self.writeGrid() # Write last grid. | |
| 134 self.createHtml(self.args.out_file) | |
| 135 return 0 | |
| 136 | |
| 137 def writeGrid(self): | |
| 138 """Register writing of grid.""" | |
| 139 if not self.grid: | |
| 140 return | |
| 141 # Append grid info. | |
| 142 file_name = 'thumbnail_%d.png' % self.plot_idx | |
| 143 file_name = os.path.join(self.args.out_dir, file_name) | |
| 144 self.plot_idx += 1 | |
| 145 self.grid_links.append(GridLinks(os.path.basename(file_name), self.grid.link_regions)) | |
| 146 | |
| 147 def createHtml(self, file_name): | |
| 148 print >>sys.stderr, 'Writing HTML to %s' % file_name | |
| 149 with open(file_name, 'wb') as f: | |
| 150 f.write('<html><body>\n') | |
| 151 f.write('<iframe name="empty" height="0" width="0" src="about:blank"></iframe>\n') | |
| 152 for gl in self.grid_links: | |
| 153 vals = (gl.file_name, gl.file_name, self.grid.canvas_width, self.grid.canvas_height) | |
| 154 f.write('<img src="%s" usemap="#%s" width="%d" height="%d" />\n' % vals) | |
| 155 f.write('<map name="%s">\n' % gl.file_name) | |
| 156 for lr in gl.link_regions: | |
| 157 locus = (lr.ref, lr.begin_pos + 1, lr.end_pos) | |
| 158 vals = {'x1': lr.x1, 'x2': lr.x2, 'y1': lr.y1, 'y2': lr.y2, | |
| 159 'title': '%s %d-%d' % locus, | |
| 160 'href': self.buildHref(lr.ref, lr.begin_pos, lr.end_pos), | |
| 161 'onclick': ''} | |
| 162 # Add onclick handler to prevent opening of new window. | |
| 163 vals['target_attr'] = '' | |
| 164 if self.args.link_target: | |
| 165 vals['target_attr'] = ' target="%s"' % self.args.link_target | |
| 166 if self.args.link_type == 'local_igv': | |
| 167 vals['target_attr'] = ' target="empty"' | |
| 168 f.write(' <area shape="rect" coords="%(x1)d,%(y1)d,%(x2)d,%(y2)d" ' | |
| 169 'alt="%(title)s" title="%(title)s" href="%(href)s"%(target_attr)s />\n' % vals) | |
| 170 f.write('</map>\n') | |
| 171 f.write('</body></html>\n') | |
| 172 | |
| 173 | |
| 174 def main(): | |
| 175 """Program entry point.""" | |
| 176 parser = argparse.ArgumentParser(description='Plot ROI file.') | |
| 177 ngs_roi.argparse.addFileArguments(parser) | |
| 178 ngs_roi.argparse.addPlotGridArguments(parser) | |
| 179 ngs_roi.argparse.addLinkArguments(parser) | |
| 180 args = parser.parse_args() | |
| 181 ngs_roi.argparse.applyFileDefaults(args) | |
| 182 | |
| 183 app = PlotThumbnailsApp(args) | |
| 184 return app.run() | |
| 185 | |
| 186 | |
| 187 if __name__ == '__main__': | |
| 188 sys.exit(main()) |
