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