Mercurial > repos > nick > dna_visualizer
comparison visualize.py @ 8:534516105ca9
visualize.py: The second tool, for a more aesthetic, abstract visualization.
author | Nick Stoler <nstoler@psu.edu> |
---|---|
date | Sun, 02 Mar 2014 23:47:41 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
7:2d99feb4a8e3 | 8:534516105ca9 |
---|---|
1 #!/usr/bin/python | |
2 import sys | |
3 import random | |
4 import hashlib | |
5 import Image | |
6 import ImageDraw | |
7 | |
8 def main(): | |
9 | |
10 if len(sys.argv) == 1: | |
11 print """USAGE: | |
12 $ ./visualize.py genome.fa outfile.png pxsize | |
13 The last two arguments are optional, but must be in those positions. | |
14 If no outfile name is given, it will attempt to display the image directly. | |
15 If no pxsize is given, the default is 512. A power of 2 is highly | |
16 recommended as the resulting image will be much better laid out.""" | |
17 sys.exit(0) | |
18 | |
19 DEFAULT_SIZE = (512,512) | |
20 size = DEFAULT_SIZE | |
21 if len(sys.argv) > 3: | |
22 user_size = int(sys.argv[3]) | |
23 size = (user_size,user_size) | |
24 | |
25 # can skip hashing and specify the seed as an option (for testing) | |
26 if len(sys.argv) > 4: | |
27 seed = sys.argv[4] | |
28 else: | |
29 seed = get_hash(sys.argv[1]) | |
30 print "seed: "+seed | |
31 random.seed(seed) | |
32 level = 1 | |
33 layers = [] | |
34 image = draw_layer(size, level) | |
35 while 1: | |
36 level+=1 | |
37 layers.append(draw_layer(size, level)) | |
38 if layers[-1] == False: | |
39 break | |
40 # opacity = 256/2**level # opacity #1 | |
41 opacity = 256/2**(level-1) # opacity #2 | |
42 # opacity = 256*(level/2)/2**(level-1) # opacity #3 | |
43 # opacity = 256*(level/float(2**level)) # opacity #4 | |
44 print "opacity: "+str(int(opacity/2.56))+"%" | |
45 mask = Image.new("L", size, color=opacity) | |
46 image.paste(layers[-1], (0,0), mask) | |
47 | |
48 if len(sys.argv) > 2: | |
49 image.save(sys.argv[2], 'PNG') | |
50 else: | |
51 image.show() | |
52 | |
53 def draw_layer(image_size, level): | |
54 """Draw every block for a particular layer | |
55 (blocks of a particular pixel size). | |
56 Returns an image of the finished layer.""" | |
57 (image_width,image_height) = image_size | |
58 (width, height) = block_size(image_size, level) | |
59 if width < 1 or height < 1: | |
60 return False | |
61 print "width, height: "+str(width)+", "+str(height) | |
62 layer = Image.new("RGB", image_size, (0,0,0)) | |
63 draw = ImageDraw.Draw(layer) | |
64 (x,y) = (0,0) | |
65 while y < image_height: | |
66 while x < image_width: | |
67 draw.rectangle([(x,y), (x+width-1, y+height-1)], fill=randcolor()) | |
68 x += width | |
69 y += height | |
70 x = 0 | |
71 return layer | |
72 | |
73 def get_hash(filepath): | |
74 """Compute hash of the file""" | |
75 hashed = hashlib.sha256() | |
76 with open(filepath, 'rb') as filehandle: | |
77 for chunk in iter(lambda: filehandle.read(65536), b''): | |
78 hashed.update(chunk) | |
79 return hashed.hexdigest() | |
80 | |
81 def randcolor(): | |
82 """Return a tuple of random color values""" | |
83 color = [] | |
84 for i in range(3): | |
85 color.append(random.randrange(0,255)) | |
86 return tuple(color) | |
87 | |
88 def block_size(image_size, level): | |
89 """Compute the block width and height for this layer.""" | |
90 (width,height) = image_size | |
91 while level > 0: | |
92 width = width/2 | |
93 height = height/4 | |
94 level-=1 | |
95 if level < 1: | |
96 break | |
97 width = width/4 | |
98 height = height/2 | |
99 level-=1 | |
100 return (width,height) | |
101 | |
102 def format_genome(): | |
103 """Eventually I'd like to attempt to process the genome file into a standard | |
104 format, stripping out details of representation that can change the output, | |
105 such as: | |
106 - upper/lowercase | |
107 - line endings | |
108 - chromosome naming | |
109 - chromosome order | |
110 - noncanonical chromosomes""" | |
111 | |
112 def check_genome(): | |
113 """Eventually I'd like this to check assumptions I might make about the | |
114 genome file. A first check would be that it contains all the chromosomes, in | |
115 the format ''>chr1' or ''>1'. If these assumptions (which format_genome() | |
116 depends on) aren't met, and the format isn't recognized, then default to a | |
117 straight digest of the unmodified file.""" | |
118 | |
119 if __name__ == "__main__": | |
120 main() |