1
2
3
4
5
6
7
8
9
10
11 """ Feature module
12
13 Provides:
14
15 o Feature - class to wrap Bio.SeqFeature objects with drawing information
16
17 For drawing capabilities, this module uses reportlab to define colors:
18
19 http://www.reportlab.com
20
21 For dealing with biological information, the package uses BioPython:
22
23 http://www.biopython.org
24 """
25
26
27 from reportlab.lib import colors
28
29
30 from _Colors import ColorTranslator
31
32 import string
33
35 """ Class to wrap Bio.SeqFeature objects for GenomeDiagram
36
37 Provides:
38
39 Methods:
40
41 o __init__(self, parent=None, feature_id=None, feature=None,
42 color=colors.lightgreen) Called when the feature is
43 instantiated
44
45 o set_feature(self, feature) Wrap the passed feature
46
47 o get_feature(self) Return the unwrapped Bio.SeqFeature object
48
49 o set_color(self, color) Set the color in which the feature will
50 be drawn (accepts multiple formats: reportlab color.Color()
51 tuple and color.name, or integer representing Artemis color
52
53 o get_color(self) Returns color.Color tuple of the feature's color
54
55 o __getattr__(self, name) Catches attribute requests and passes them to
56 the wrapped Bio.SeqFeature object
57
58 Attributes:
59
60 o parent FeatureSet, container for the object
61
62 o id Unique id
63
64 o color color.Color, color to draw the feature
65
66 o hide Boolean for whether the feature will be drawn or not
67
68 o sigil String denoting the type of sigil to use for the feature.
69 Currently either "BOX" or "ARROW" are supported.
70
71 o arrowhead_length Float denoting length of the arrow head to be drawn,
72 relative to the bounding box height. The arrow shaft
73 takes up the remainder of the bounding box's length.
74
75 o arrowshaft_height Float denoting length of the representative arrow
76 shaft to be drawn, relative to the bounding box height.
77 The arrow head takes the full height of the bound box.
78
79 o name_qualifiers List of Strings, describes the qualifiers that may
80 contain feature names in the wrapped Bio.SeqFeature object
81
82 o label Boolean, 1 if the label should be shown
83
84 o label_font String describing the font to use for the feature label
85
86 o label_size Int describing the feature label font size
87
88 o label_color color.Color describing the feature label color
89
90 o label_angle Float describing the angle through which to rotate the
91 feature label in degrees (default = 45, linear only)
92
93 o label_position String, 'start', 'end' or 'middle' denoting where
94 to place the feature label (linear only)
95
96 o locations List of tuples of (start, end) ints describing where the
97 feature and any subfeatures start and end
98
99 o type String denoting the feature type
100
101 o name String denoting the feature name
102
103 o strand Int describing the strand on which the feature is found
104
105 """
106 - def __init__(self, parent=None, feature_id=None, feature=None,
107 color=colors.lightgreen, label=0, colour=None):
108 """ __init__(self, parent=None, feature_id=None, feature=None,
109 color=colors.lightgreen, label=0)
110
111 o parent FeatureSet containing the feature
112
113 o feature_id Unique id for the feature
114
115 o feature Bio.SeqFeature object to be wrapped
116
117 o color color.Color Color to draw the feature (overridden
118 by backwards compatible argument with UK spelling,
119 colour). Either argument is overridden if 'color'
120 is found in feature qualifiers
121
122 o label Boolean, 1 if the label should be shown
123 """
124
125 if colour is not None:
126 color = colour
127
128 self._colortranslator = ColorTranslator()
129
130
131 self.parent = parent
132 self.id = feature_id
133 self.color = color
134 self._feature = None
135 self.hide = 0
136 self.sigil = 'BOX'
137 self.arrowhead_length = 0.5
138 self.arrowshaft_height = 0.4
139 self.name_qualifiers = ['gene', 'label', 'name', 'locus_tag', 'product']
140 self.label = label
141 self.label_font = 'Helvetica'
142 self.label_size = 6
143 self.label_color = colors.black
144 self.label_angle = 45
145 self.label_position = 'start'
146
147 if feature is not None:
148 self.set_feature(feature)
149
151 """ set_feature(self, feature)
152
153 o feature Bio.SeqFeature object to be wrapped
154
155 Defines the Bio.SeqFeature object to be wrapped
156 """
157 self._feature = feature
158 self.__process_feature()
159
160
162 """ __process_feature(self)
163
164 Examine the feature to be wrapped, and set some of the Feature's
165 properties accordingly
166 """
167 self.locations = []
168 bounds = []
169 if self._feature.sub_features == []:
170 if '^' in str(self._feature.location._start):
171 self.hide = 1
172
173 start, end = str(self._feature.location._start).split('^')
174 else:
175 start = str(self._feature.location._start)
176 end = str(self._feature.location._end)
177 while start[0] not in string.digits:
178
179 start = start[1:]
180 while end[0] not in string.digits:
181
182 end = end[1:]
183 while end[-1] not in string.digits:
184
185 end = end[:-1]
186 start, end = int(start), int(end)
187
188
189 self.locations.append((start, end))
190 bounds += [start, end]
191 else:
192 for subfeature in self._feature.sub_features:
193 if '^' in str(subfeature.location._start):
194 self.hide = 1
195 start, end = str(subfeature.location._start).split('^')
196 else:
197 start = str(subfeature.location._start)
198 end = str(subfeature.location._end)
199 while start[0] not in string.digits:
200
201 start = start[1:]
202 while end[0] not in string.digits:
203
204 end = end[1:]
205 try:
206 start, end = int(start), int(end)
207 except:
208
209 sys.exit(1)
210
211
212 self.locations.append((start, end))
213 bounds += [start, end]
214 self.type = str(self._feature.type)
215 if self._feature.strand is None :
216
217
218 self.strand = 0
219 else :
220 self.strand = int(self._feature.strand)
221 if 'color' in self._feature.qualifiers:
222
223
224
225 artemis_color = self._feature.qualifiers['color'][0]
226 if artemis_color.count('.'):
227 artemis_color = artemis_color.split('.')[0]
228 else:
229 artemis_color = artemis_color
230 self.color = self._colortranslator.artemis_color(artemis_color)
231 self.name = self.type
232 for qualifier in self.name_qualifiers:
233 if qualifier in self._feature.qualifiers:
234 self.name = self._feature.qualifiers[qualifier][0]
235 break
236 self.start, self.end = min(bounds), max(bounds)
237
238
240 """ get_feature(self) -> Bio.SeqFeature
241
242 Returns the unwrapped Bio.SeqFeature object
243 """
244 return self._feature
245
247 """Backwards compatible variant of set_color(self, color) using UK spelling."""
248 color = self._colortranslator.translate(colour)
249 self.color = color
250
252 """ set_color(self, color)
253
254 o color The color to draw the feature - either a colors.Color
255 object, an RGB tuple of floats, or an integer
256 corresponding to colors in colors.txt
257
258 Set the color in which the feature will be drawn
259 """
260
261 color = self._colortranslator.translate(color)
262 self.color = color
263
265 """ __getattr__(self, name) -> various
266
267 If the Feature class doesn't have the attribute called for,
268 check in self._feature for it
269 """
270 return getattr(self._feature, name)
271
272
273
274
275
276
277
278 if __name__ == '__main__':
279
280
281 gdf = Feature()
282