Back to index

python-biopython  1.60
_Feature.py
Go to the documentation of this file.
00001 # Copyright 2003-2008 by Leighton Pritchard.  All rights reserved.
00002 # This code is part of the Biopython distribution and governed by its
00003 # license.  Please see the LICENSE file that should have been included
00004 # as part of this package.
00005 #
00006 # Contact:       Leighton Pritchard, Scottish Crop Research Institute,
00007 #                Invergowrie, Dundee, Scotland, DD2 5DA, UK
00008 #                L.Pritchard@scri.ac.uk
00009 ################################################################################
00010 
00011 """ Feature module
00012 
00013     Provides:
00014 
00015     o Feature - class to wrap Bio.SeqFeature objects with drawing information
00016 
00017     For drawing capabilities, this module uses reportlab to define colors:
00018 
00019     http://www.reportlab.com
00020 
00021     For dealing with biological information, the package uses BioPython:
00022 
00023     http://www.biopython.org
00024 """
00025 
00026 # ReportLab imports
00027 from reportlab.lib import colors
00028 
00029 # GenomeDiagram imports
00030 from _Colors import ColorTranslator
00031 
00032 import string
00033 
00034 class Feature(object):
00035     """ Class to wrap Bio.SeqFeature objects for GenomeDiagram
00036 
00037         Provides:
00038 
00039         Methods:
00040 
00041         o __init__(self, parent=None, feature_id=None, feature=None,
00042                  color=colors.lightgreen) Called when the feature is
00043                  instantiated
00044 
00045         o set_feature(self, feature) Wrap the passed feature
00046 
00047         o get_feature(self) Return the unwrapped Bio.SeqFeature object
00048 
00049         o set_color(self, color) Set the color in which the feature will
00050                 be drawn (accepts multiple formats: reportlab color.Color()
00051                 tuple and color.name, or integer representing Artemis color
00052 
00053         o get_color(self) Returns color.Color tuple of the feature's color
00054 
00055         o __getattr__(self, name) Catches attribute requests and passes them to
00056                 the wrapped Bio.SeqFeature object
00057 
00058         Attributes:
00059 
00060         o parent    FeatureSet, container for the object
00061 
00062         o id        Unique id
00063 
00064         o color    color.Color, color to draw the feature
00065 
00066         o hide      Boolean for whether the feature will be drawn or not
00067 
00068         o sigil     String denoting the type of sigil to use for the feature.
00069                     Currently either "BOX" or "ARROW" are supported.
00070 
00071         o arrowhead_length  Float denoting length of the arrow head to be drawn,
00072                             relative to the bounding box height.  The arrow shaft
00073                             takes up the remainder of the bounding box's length.
00074 
00075         o arrowshaft_height  Float denoting length of the representative arrow
00076                              shaft to be drawn, relative to the bounding box height.
00077                              The arrow head takes the full height of the bound box.
00078          
00079         o name_qualifiers   List of Strings, describes the qualifiers that may
00080                     contain feature names in the wrapped Bio.SeqFeature object
00081 
00082         o label     Boolean, 1 if the label should be shown
00083 
00084         o label_font    String describing the font to use for the feature label
00085 
00086         o label_size    Int describing the feature label font size
00087 
00088         o label_color  color.Color describing the feature label color
00089 
00090         o label_angle   Float describing the angle through which to rotate the
00091                     feature label in degrees (default = 45, linear only)
00092 
00093         o label_position    String, 'start', 'end' or 'middle' denoting where
00094                     to place the feature label (linear only)
00095 
00096         o locations     List of tuples of (start, end) ints describing where the
00097                     feature and any subfeatures start and end
00098 
00099         o type      String denoting the feature type
00100 
00101         o name      String denoting the feature name
00102 
00103         o strand    Int describing the strand on which the feature is found
00104 
00105     """
00106     def __init__(self, parent=None, feature_id=None, feature=None,
00107                  color=colors.lightgreen, label=0, border=None, colour=None):
00108         """ __init__(self, parent=None, feature_id=None, feature=None,
00109                  color=colors.lightgreen, label=0)
00110 
00111             o parent    FeatureSet containing the feature
00112 
00113             o feature_id    Unique id for the feature
00114 
00115             o feature   Bio.SeqFeature object to be wrapped
00116 
00117             o color    color.Color Color to draw the feature (overridden
00118                        by backwards compatible argument with UK spelling,
00119                        colour).  Either argument is overridden if 'color'
00120                        is found in feature qualifiers
00121 
00122             o border   color.Color Color to draw the feature border, use
00123                        None for the same as the fill color, False for no border.
00124 
00125             o label     Boolean, 1 if the label should be shown
00126         """
00127         #Let the UK spelling (colour) override the USA spelling (color)
00128         if colour is not None:
00129             color = colour
00130 
00131         self._colortranslator = ColorTranslator()
00132         
00133         # Initialise attributes
00134         self.parent = parent
00135         self.id = feature_id        
00136         self.color = color            # default color to draw the feature
00137         self.border = border
00138         self._feature = None            # Bio.SeqFeature object to wrap
00139         self.hide = 0                   # show by default
00140         self.sigil = 'BOX'
00141         self.arrowhead_length = 0.5 # 50% of the box height
00142         self.arrowshaft_height = 0.4 # 40% of the box height
00143         self.name_qualifiers = ['gene', 'label', 'name', 'locus_tag', 'product']
00144         self.label = label
00145         self.label_font = 'Helvetica'
00146         self.label_size = 6
00147         self.label_color = colors.black
00148         self.label_angle = 45
00149         self.label_position = 'start'
00150         
00151         if feature is not None:
00152             self.set_feature(feature)
00153 
00154     def set_feature(self, feature):
00155         """ set_feature(self, feature)
00156 
00157             o feature   Bio.SeqFeature object to be wrapped
00158 
00159             Defines the Bio.SeqFeature object to be wrapped
00160         """
00161         self._feature = feature
00162         self.__process_feature()
00163 
00164 
00165     def __process_feature(self):
00166         """ __process_feature(self)
00167 
00168             Examine the feature to be wrapped, and set some of the Feature's
00169             properties accordingly
00170         """
00171         self.locations = []
00172         bounds = []
00173         if self._feature.sub_features == []:
00174             start = self._feature.location.nofuzzy_start
00175             end = self._feature.location.nofuzzy_end
00176             #if start > end and self.strand == -1:
00177             #    start, end = end, start
00178             self.locations.append((start, end))
00179             bounds += [start, end]
00180         else:
00181             for subfeature in self._feature.sub_features:
00182                 start = subfeature.location.nofuzzy_start
00183                 end = subfeature.location.nofuzzy_end
00184                 #if start > end and self.strand == -1:
00185                 #    start, end = end, start
00186                 self.locations.append((start, end))                
00187                 bounds += [start, end]
00188         self.type = str(self._feature.type)                     # Feature type
00189         #TODO - Strand can vary with subfeatures (e.g. mixed strand tRNA)
00190         if self._feature.strand is None:
00191             #This is the SeqFeature default (None), but the drawing code
00192             #only expects 0, +1 or -1.
00193             self.strand = 0
00194         else:
00195             self.strand = int(self._feature.strand)                 # Feature strand
00196         if 'color' in self._feature.qualifiers:                # Artemis color (if present)
00197             self.color = self._colortranslator.artemis_color( \
00198                                          self._feature.qualifiers['color'][0])
00199         self.name = self.type
00200         for qualifier in self.name_qualifiers:            
00201             if qualifier in self._feature.qualifiers:
00202                 self.name = self._feature.qualifiers[qualifier][0]
00203                 break
00204         #Note will be 0 to N for origin wrapping feature on genome of length N 
00205         self.start, self.end = min(bounds), max(bounds)
00206 
00207 
00208     def get_feature(self):
00209         """ get_feature(self) -> Bio.SeqFeature
00210 
00211             Returns the unwrapped Bio.SeqFeature object
00212         """
00213         return self._feature
00214 
00215     def set_colour(self, colour):
00216         """Backwards compatible variant of set_color(self, color) using UK spelling."""
00217         color = self._colortranslator.translate(colour)
00218         self.color = color
00219 
00220     def set_color(self, color):
00221         """ set_color(self, color)
00222 
00223             o color    The color to draw the feature - either a colors.Color
00224                        object, an RGB tuple of floats, or an integer
00225                        corresponding to colors in colors.txt
00226                            
00227             Set the color in which the feature will be drawn
00228         """
00229         #TODO - Make this into the set method for a color property?
00230         color = self._colortranslator.translate(color)
00231         self.color = color
00232 
00233     def __getattr__(self, name):
00234         """ __getattr__(self, name) -> various
00235 
00236             If the Feature class doesn't have the attribute called for,
00237             check in self._feature for it
00238         """
00239         return getattr(self._feature, name) # try to get the attribute from the feature
00240 
00241 
00242     
00243 ################################################################################
00244 # RUN AS SCRIPT
00245 ################################################################################
00246 
00247 if __name__ == '__main__':
00248 
00249     # Test code
00250     gdf = Feature()