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   - FeatureSet - container for Feature objects 
 20   
 21  For drawing capabilities, this module uses reportlab to draw and write 
 22  the diagram: http://www.reportlab.com 
 23  """ 
 24   
 25  from __future__ import print_function 
 26   
 27  # GenomeDiagram 
 28  from ._Feature import Feature 
 29   
 30  # Builtins 
 31  import re 
 32   
 33   
34 -class FeatureSet(object):
35 """FeatureSet object.""" 36
37 - def __init__(self, set_id=None, name=None, parent=None):
38 """Create the object. 39 40 Arguments: 41 - set_id: Unique id for the set 42 - name: String identifying the feature set 43 """ 44 self.parent = parent 45 self.id = id # Unique id for the set 46 self.next_id = 0 # counter for unique feature ids 47 self.features = {} # Holds features, keyed by ID 48 self.name = name # String describing the set
49
50 - def add_feature(self, feature, **kwargs):
51 """Add a new feature. 52 53 Arguments: 54 - feature: Bio.SeqFeature object 55 - kwargs: Keyword arguments for Feature. Named attributes 56 of the Feature 57 58 Add a Bio.SeqFeature object to the diagram (will be stored 59 internally in a Feature wrapper). 60 """ 61 id = self.next_id # get id number 62 f = Feature(self, id, feature) 63 self.features[id] = f # add feature 64 for key in kwargs: 65 if key == "colour" or key == "color": 66 # Deal with "colour" as a special case by also mapping to color. 67 # If Feature.py used a python property we wouldn't need to call 68 # set_color explicitly. However, this is important to make sure 69 # every color gets mapped to a colors object - for example color 70 # numbers, or strings (may not matter for PDF, but does for PNG). 71 self.features[id].set_color(kwargs[key]) 72 continue 73 setattr(self.features[id], key, kwargs[key]) 74 self.next_id += 1 # increment next id 75 return f
76
77 - def del_feature(self, feature_id):
78 """Delete a feature. 79 80 Arguments: 81 - feature_id: Unique id of the feature to delete 82 83 Remove a feature from the set, indicated by its id. 84 """ 85 del self.features[feature_id]
86
87 - def set_all_features(self, attr, value):
88 """Set an attribute of all the features. 89 90 Arguments: 91 - attr: An attribute of the Feature class 92 - value: The value to set that attribute to 93 94 Set the passed attribute of all features in the set to the 95 passed value. 96 """ 97 changed = 0 98 for feature in self.features.values(): 99 # If the feature has the attribute, and the value should change 100 if hasattr(feature, attr): 101 if getattr(feature, attr) != value: 102 setattr(feature, attr, value) # set it to the passed value
103 104 # For backwards compatibility, we support both colour and color. 105 # As a quick hack, make "colour" set both "colour" and "color". 106 # if attr=="colour": 107 # self.set_all_feature("color",value) 108
109 - def get_features(self, attribute=None, value=None, comparator=None):
110 """Retrieve features. 111 112 Arguments: 113 - attribute: String, attribute of a Feature object 114 - value: The value desired of the attribute 115 - comparator: String, how to compare the Feature attribute to the 116 passed value 117 118 If no attribute or value is given, return a list of all features in the 119 feature set. If both an attribute and value are given, then depending 120 on the comparator, then a list of all features in the FeatureSet 121 matching (or not) the passed value will be returned. Allowed comparators 122 are: 'startswith', 'not', 'like'. 123 124 The user is expected to make a responsible decision about which feature 125 attributes to use with which passed values and comparator settings. 126 """ 127 # If no attribute or value specified, return all features 128 if attribute is None or value is None: 129 return list(self.features.values()) 130 # If no comparator is specified, return all features where the attribute 131 # value matches that passed 132 if comparator is None: 133 return [feature for feature in self.features.values() if 134 getattr(feature, attribute) == value] 135 # If the comparator is 'not', return all features where the attribute 136 # value does not match that passed 137 elif comparator == 'not': 138 return [feature for feature in self.features.values() if 139 getattr(feature, attribute) != value] 140 # If the comparator is 'startswith', return all features where the attribute 141 # value does not match that passed 142 elif comparator == 'startswith': 143 return [feature for feature in self.features.values() if 144 getattr(feature, attribute).startswith(value)] 145 # If the comparator is 'like', use a regular expression search to identify 146 # features 147 elif comparator == 'like': 148 return [feature for feature in self.features.values() if 149 re.search(value, getattr(feature, attribute))] 150 # As a final option, just return an empty list 151 return []
152
153 - def get_ids(self):
154 """Return a list of all ids for the feature set.""" 155 return list(self.features.keys())
156
157 - def range(self):
158 """Returns the lowest and highest base (or mark) numbers as a tuple.""" 159 lows, highs = [], [] 160 for feature in self.features.values(): 161 for start, end in feature.locations: 162 lows.append(start) 163 highs.append(end) 164 if len(lows) != 0 and len(highs) != 0: # Default in case there is 165 return (min(lows), max(highs)) # nothing in the set 166 return 0, 0
167
168 - def to_string(self, verbose=0):
169 """Returns a formatted string with information about the set 170 171 Arguments: 172 - verbose: Boolean indicating whether a short (default) or 173 complete account of the set is required 174 """ 175 if not verbose: # Short account only required 176 return "%s" % self 177 else: # Long account desired 178 outstr = ["\n<%s: %s>" % (self.__class__, self.name)] 179 outstr.append("%d features" % len(self.features)) 180 for key in self.features: 181 outstr.append("feature: %s" % self.features[key]) 182 return "\n".join(outstr)
183
184 - def __len__(self):
185 """Return the number of features in the set.""" 186 return len(self.features)
187
188 - def __getitem__(self, key):
189 """Return a feature, keyed by id.""" 190 return self.features[key]
191
192 - def __str__(self):
193 """Returns a formatted string with information about the feature set.""" 194 outstr = ["\n<%s: %s %d features>" % (self.__class__, self.name, 195 len(self.features))] 196 return "\n".join(outstr)
197 198 ################################################################################ 199 # RUN AS SCRIPT 200 ################################################################################ 201 202 if __name__ == '__main__': 203 from Bio import SeqIO 204 205 genbank_entry = SeqIO.read('/data/Genomes/Bacteria/Nanoarchaeum_equitans/NC_005213.gbk', 'gb') 206 207 # Test code 208 gdfs = FeatureSet(0, 'Nanoarchaeum equitans CDS') 209 for feature in genbank_entry.features: 210 if feature.type == 'CDS': 211 gdfs.add_feature(feature) 212 213 # print len(gdfs) 214 # print gdfs.get_ids() 215 # gdfs.del_feature(560) 216 # print gdfs.get_ids() 217 # print gdfs.get_features() 218 # for feature in gdfs.get_features(): 219 # print feature.id, feature.start, feature.end 220 # print gdfs[500] 221