Package Bio :: Package Graphics :: Package GenomeDiagram :: Module _FeatureSet
[hide private]
[frames] | no frames]

Source Code for Module Bio.Graphics.GenomeDiagram._FeatureSet

  1  # Copyright 2003-2008 by Leighton Pritchard.  All rights reserved. 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license.  Please see the LICENSE file that should have been included 
  4  # as part of this package. 
  5  # 
  6  # Contact:       Leighton Pritchard, Scottish Crop Research Institute, 
  7  #                Invergowrie, Dundee, Scotland, DD2 5DA, UK 
  8  #                L.Pritchard@scri.ac.uk 
  9  ################################################################################ 
 10  # 
 11  # Thanks to Peter Cock for the impetus to write the get_features() code to 
 12  # subselect Features. 
 13  # 
 14  ################################################################################ 
 15   
 16  """ FeatureSet module 
 17   
 18      Provides: 
 19   
 20      o FeatureSet - container for Feature objects 
 21   
 22      For drawing capabilities, this module uses reportlab to draw and write 
 23      the diagram: 
 24   
 25      http://www.reportlab.com 
 26   
 27      For dealing with biological information, the package expects BioPython 
 28      objects: 
 29   
 30      http://www.biopython.org 
 31  """ 
 32   
 33  #------------------------------------------------------------------------------ 
 34  # IMPORTS 
 35   
 36  # ReportLab 
 37  from __future__ import print_function 
 38   
 39  from reportlab.pdfbase import _fontdata 
 40  from reportlab.lib import colors 
 41   
 42  # GenomeDiagram 
 43  from ._Feature import Feature 
 44   
 45  # Builtins 
 46  import re 
 47   
 48  #------------------------------------------------------------------------------ 
 49  # CLASSES 
 50   
 51  #------------------------------------------------------------ 
 52  # FeatureSet 
 53   
 54   
55 -class FeatureSet(object):
56 """ FeatureSet 57 58 Provides: 59 60 Methods: 61 62 o __init__(self, set_id=None, name=None) Called on instantiation 63 64 o add_feature(self, feature, color=colors.lightgreen) Add a Feature 65 object to the set 66 67 o del_feature(self, feature_id) Remove a feature from the set, by id 68 69 o set_all_features(self, attr, value) Set the passed attribute to the 70 passed value in all features in the set 71 72 o get_features(self) Returns a list of Features from the set 73 74 o get_ids(self) Returns a list of unique ids for features in the set 75 76 o range(self) Returns the range of bases covered by features in 77 the set 78 79 o to_string(self, verbose=0) Returns a string describing the set 80 81 o __len__(self) Returns the length of sequence covered by the set 82 83 o __getitem__(self, key) Returns a feature from the set, keyed by id 84 85 o __str__(self) Returns a string describing the set 86 87 Attributes: 88 89 o id Unique id for the set 90 91 o name String describing the set 92 """
93 - def __init__(self, set_id=None, name=None, parent=None):
94 """ __init__(self, set_id=None, name=None) 95 96 o set_id Unique id for the set 97 98 o name String identifying the feature set 99 """ 100 self.parent = parent 101 self.id = id # Unique id for the set 102 self.next_id = 0 # counter for unique feature ids 103 self.features = {} # Holds features, keyed by ID 104 self.name = name # String describing the set
105
106 - def add_feature(self, feature, **kwargs):
107 """ add_feature(self, feature, **args) 108 109 o feature Bio.SeqFeature object 110 111 o **kwargs Keyword arguments for Feature. Named attributes 112 of the Feature 113 114 Add a Bio.SeqFeature object to the diagram (will be stored 115 internally in a Feature wrapper 116 """ 117 id = self.next_id # get id number 118 f = Feature(self, id, feature) 119 self.features[id] = f # add feature 120 for key in kwargs: 121 if key == "colour" or key == "color": 122 #Deal with "colour" as a special case by also mapping to color. 123 #If Feature.py used a python property we wouldn't need to call 124 #set_color explicitly. However, this is important to make sure 125 #every color gets mapped to a colors object - for example color 126 #numbers, or strings (may not matter for PDF, but does for PNG). 127 self.features[id].set_color(kwargs[key]) 128 continue 129 setattr(self.features[id], key, kwargs[key]) 130 self.next_id += 1 # increment next id 131 return f
132
133 - def del_feature(self, feature_id):
134 """ del_feature(self, feature_id) 135 136 o feature_id Unique id of the feature to delete 137 138 Remove a feature from the set, indicated by its id 139 """ 140 del self.features[feature_id]
141
142 - def set_all_features(self, attr, value):
143 """ set_all_features(self, attr, value) 144 145 o attr An attribute of the Feature class 146 147 o value The value to set that attribute 148 149 Set the passed attribute of all features in the set to the 150 passed value 151 """ 152 changed = 0 153 for feature in self.features.values(): 154 # If the feature has the attribute, and the value should change 155 if hasattr(feature, attr): 156 if getattr(feature, attr) != value: 157 setattr(feature, attr, value) # set it to the passed value
158 159 #For backwards compatibility, we support both colour and color. 160 #As a quick hack, make "colour" set both "colour" and "color". 161 #if attr=="colour": 162 # self.set_all_feature("color",value) 163
164 - def get_features(self, attribute=None, value=None, comparator=None):
165 """ get_features(self, attribute=None, value=None, comparator=None) -> 166 [Feature, Feature, ...] 167 168 o attribute String, attribute of a Feature object 169 170 o value The value desired of the attribute 171 172 o comparator String, how to compare the Feature attribute to the 173 passed value 174 175 If no attribute or value is given, return a list of all features in the 176 feature set. If both an attribute and value are given, then depending 177 on the comparator, then a list of all features in the FeatureSet 178 matching (or not) the passed value will be returned. Allowed comparators 179 are: 'startswith', 'not', 'like'. 180 181 The user is expected to make a responsible decision about which feature 182 attributes to use with which passed values and comparator settings. 183 """ 184 # If no attribute or value specified, return all features 185 if attribute is None or value is None: 186 return list(self.features.values()) 187 # If no comparator is specified, return all features where the attribute 188 # value matches that passed 189 if comparator is None: 190 return [feature for feature in self.features.values() if 191 getattr(feature, attribute) == value] 192 # If the comparator is 'not', return all features where the attribute 193 # value does not match that passed 194 elif comparator == 'not': 195 return [feature for feature in self.features.values() if 196 getattr(feature, attribute) != value] 197 # If the comparator is 'startswith', return all features where the attribute 198 # value does not match that passed 199 elif comparator == 'startswith': 200 return [feature for feature in self.features.values() if 201 getattr(feature, attribute).startswith(value)] 202 # If the comparator is 'like', use a regular expression search to identify 203 # features 204 elif comparator == 'like': 205 return [feature for feature in self.features.values() if 206 re.search(value, getattr(feature, attribute))] 207 # As a final option, just return an empty list 208 return []
209
210 - def get_ids(self):
211 """ get_ids(self) -> [int, int, ...] 212 213 Return a list of all ids for the feature set 214 """ 215 return list(self.features.keys())
216
217 - def range(self):
218 """ range(self) 219 220 Returns the lowest and highest base (or mark) numbers as a tuple 221 """ 222 lows, highs = [], [] 223 for feature in self.features.values(): 224 for start, end in feature.locations: 225 lows.append(start) 226 highs.append(end) 227 if len(lows) != 0 and len(highs) != 0: # Default in case there is 228 return (min(lows), max(highs)) # nothing in the set 229 return 0, 0
230
231 - def to_string(self, verbose=0):
232 """ to_string(self, verbose=0) -> "" 233 234 o verbose Boolean indicating whether a short or complete 235 account of the set is required 236 237 Returns a formatted string with information about the set 238 """ 239 if not verbose: # Short account only required 240 return "%s" % self 241 else: # Long account desired 242 outstr = ["\n<%s: %s>" % (self.__class__, self.name)] 243 outstr.append("%d features" % len(self.features)) 244 for key in self.features: 245 outstr.append("feature: %s" % self.features[key]) 246 return "\n".join(outstr)
247
248 - def __len__(self):
249 """ __len__(self) -> int 250 251 Return the number of features in the set 252 """ 253 return len(self.features)
254
255 - def __getitem__(self, key):
256 """ __getitem__(self, key) -> Feature 257 258 Return a feature, keyed by id 259 """ 260 return self.features[key]
261
262 - def __str__(self):
263 """ __str__(self) -> "" 264 265 Returns a formatted string with information about the feature set 266 """ 267 outstr = ["\n<%s: %s %d features>" % (self.__class__, self.name, 268 len(self.features))] 269 return "\n".join(outstr)
270 271 ################################################################################ 272 # RUN AS SCRIPT 273 ################################################################################ 274 275 if __name__ == '__main__': 276 from Bio import SeqIO 277 278 genbank_entry = SeqIO.read('/data/Genomes/Bacteria/Nanoarchaeum_equitans/NC_005213.gbk', 'gb') 279 280 # Test code 281 gdfs = FeatureSet(0, 'Nanoarchaeum equitans CDS') 282 for feature in genbank_entry.features: 283 if feature.type == 'CDS': 284 gdfs.add_feature(feature) 285 286 #print len(gdfs) 287 #print gdfs.get_ids() 288 #gdfs.del_feature(560) 289 #print gdfs.get_ids() 290 #print gdfs.get_features() 291 #for feature in gdfs.get_features(): 292 # print feature.id, feature.start, feature.end 293 #print gdfs[500] 294