1 """Represent information for graphical display.
2
3 Classes in this module are designed to hold information in a way that
4 makes it easy to draw graphical figures.
5 """
6
7 from reportlab.lib import colors
8
9
10 from Bio.Graphics.BasicChromosome import ChromosomeSegment
11 from Bio.Graphics.BasicChromosome import TelomereSegment
12
13
14
15
16 RAINBOW_COLORS = {(1, 1) : colors.violet,
17 (2, 2) : colors.indigo,
18 (3, 3) : colors.blue,
19 (4, 4) : colors.green,
20 (5, 5) : colors.yellow,
21 (6, 6) : colors.orange,
22 (7, 20) : colors.red}
23
25 """Represent a chromosome with count information.
26
27 This is used to display information about counts along a chromosome.
28 The segments are expected to have different count information, which
29 will be displayed using a color scheme.
30
31 I envision using this class when you think that certain regions of
32 the chromosome will be especially abundant in the counts, and you
33 want to pick those out.
34 """
36 """Initialize a representation of chromosome counts.
37
38 Arguments:
39
40 o segment_names - An ordered list of all segment names along
41 the chromosome. The count and other information will be added to
42 these.
43
44 o color_scheme - A coloring scheme to use in the counts. This should
45 be a dictionary mapping count ranges to colors (specified in
46 reportlab.lib.colors).
47 """
48 self._names = segment_names
49 self._count_info = {}
50 self._label_info = {}
51 self._scale_info = {}
52 for name in self._names:
53 self._count_info[name] = 0
54 self._label_info[name] = None
55 self._scale_info[name] = 1
56
57 self._color_scheme = color_scheme
58
59 - def add_count(self, segment_name, count = 1):
60 """Add counts to the given segment name.
61
62 Arguments:
63
64 o segment_name - The name of the segment we should add counts to.
65 If the name is not present, a KeyError will be raised.
66
67 o count - The counts to add the current segment. This defaults to
68 a single count.
69 """
70 try:
71 self._count_info[segment_name] += count
72 except KeyError:
73 raise KeyError("Segment name %s not found." % segment_name)
74
76 """Divide the counts for a segment by some kind of scale value.
77
78 This is useful if segments aren't represented by raw counts, but
79 are instead counts divided by some number.
80 """
81 try:
82 self._count_info[segment_name] = \
83 float(self._count_info[segment_name]) / float(scale_value)
84 except KeyError:
85 raise KeyError("Segment name %s not found." % segment_name)
86
88 """Add a label to a specfic segment.
89
90 Raises a KeyError is the specified segment name is not found.
91 """
92 if segment_name in self._label_info:
93 self._label_info[segment_name] = label
94 else:
95 raise KeyError("Segment name %s not found." % segment_name)
96
98 """Set the scale for a specific chromosome segment.
99
100 By default all segments have the same scale -- this allows scaling
101 by the size of the segment.
102
103 Raises a KeyError is the specified segment name is not found.
104 """
105 if segment_name in self._label_info:
106 self._scale_info[segment_name] = scale
107 else:
108 raise KeyError("Segment name %s not found." % segment_name)
109
111 """Retrieve the color and label info about the segments.
112
113 Returns a list consiting of two tuples specifying the counts and
114 label name for each segment. The list is ordered according to the
115 original listing of names. Labels are set as None if no label
116 was specified.
117 """
118 order_info = []
119
120 for seg_name in self._names:
121 order_info.append((self._count_info[seg_name],
122 self._label_info[seg_name]))
123
124 return order_info
125
127 """Add the collected segment information to a chromosome for drawing.
128
129 Arguments:
130
131 o chromosome - A Chromosome graphics object that we can add
132 chromosome segments to.
133
134 This creates ChromosomeSegment (and TelomereSegment) objects to
135 fill in the chromosome. The information is derived from the
136 label and count information, with counts transformed to the
137 specified color map.
138
139 Returns the chromosome with all of the segments added.
140 """
141 for seg_num in range(len(self._names)):
142 is_end_segment = 0
143
144 if seg_num == 0:
145 cur_segment = TelomereSegment()
146 is_end_segment = 1
147 elif seg_num == len(self._names) - 1:
148 cur_segment = TelomereSegment(1)
149 is_end_segment = 1
150
151 else:
152 cur_segment = ChromosomeSegment()
153
154 seg_name = self._names[seg_num]
155 if self._count_info[seg_name] > 0:
156 color = self._color_from_count(self._count_info[seg_name])
157 cur_segment.fill_color = color
158
159 if self._label_info[seg_name] is not None:
160 cur_segment.label = self._label_info[seg_name]
161
162
163 if is_end_segment:
164 cur_segment.scale = 3
165 else:
166 cur_segment.scale = self._scale_info[seg_name]
167
168 chromosome.add(cur_segment)
169
170 return chromosome
171
173 """Translate the given count into a color using the color scheme.
174 """
175 for count_start, count_end in self._color_scheme.keys():
176 if count >= count_start and count <= count_end:
177 return self._color_scheme[(count_start, count_end)]
178
179
180 raise ValueError("Count value %s was not found in the color scheme."
181 % count)
182