Back to index

python-biopython  1.60
Public Member Functions | Public Attributes | Private Member Functions
Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer Class Reference
Inheritance diagram for Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer:
Inheritance graph
[legend]
Collaboration diagram for Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def set_track_heights
def draw
def draw_track
def draw_feature_set
def draw_feature
def get_feature_sigil
def draw_cross_link
def draw_graph_set
def draw_line_graph
def draw_bar_graph
def draw_heat_graph
def draw_scale
def draw_tick
def draw_test_tracks
def draw_greytrack
def canvas_angle

Public Attributes

 track_size
 circle_core
 sweep
 track_radii
 drawing
 drawn_tracks
 current_track_level

Private Member Functions

def _draw_arc
def _draw_arc_poly
def _draw_arc_arrow

Detailed Description

CircularDrawer(AbstractDrawer)

    Inherits from:

    o AbstractDrawer

    Provides:

    Methods:

    o __init__(self, ...) Called on instantiation

    o set_page_size(self, pagesize, orientation)    Set the page size to the
                                                passed size and orientation

    o set_margins(self, x, y, xl, xr, yt, yb)   Set the drawable area of the
                                                page

    o set_bounds(self, start, end)  Set the bounds for the elements to be
                                    drawn

    o is_in_bounds(self, value)     Returns a boolean for whether the position
                                    is actually to be drawn

    o __len__(self)     Returns the length of sequence that will be drawn


    o draw(self)    Place the drawing elements on the diagram

    o init_fragments(self)  Calculate information
                            about sequence fragment locations on the drawing

    o set_track_heights(self)   Calculate information about the offset of
                                each track from the fragment base
                                
    o draw_test_tracks(self)    Add lines demarcating each track to the
                                drawing

    o draw_track(self, track)   Return the contents of the passed track as
                                drawing elements

    o draw_scale(self, track)   Return a scale for the passed track as
                                drawing elements

    o draw_greytrack(self, track)   Return a grey background and superposed
                                    label for the passed track as drawing
                                    elements

    o draw_feature_set(self, set)   Return the features in the passed set as
                                    drawing elements

    o draw_feature(self, feature)   Return a single feature as drawing
                                    elements

    o get_feature_sigil(self, feature, x0, x1, fragment)    Return a single
                                    feature as its sigil in drawing elements

    o draw_graph_set(self, set)     Return the data in a set of graphs as
                                    drawing elements

    o draw_line_graph(self, graph)  Return the data in a graph as a line
                                    graph in drawing elements

    o draw_heat_graph(self, graph)  Return the data in a graph as a heat
                                    graph in drawing elements

    o draw_bar_graph(self, graph)   Return the data in a graph as a bar
                                    graph in drawing elements

    o canvas_angle(self, base)      Return the angle, and cos and sin of
                                    that angle, subtended by the passed
                                    base position at the diagram center

    o draw_arc(self, inner_radius, outer_radius, startangle, endangle,
                color)    Return a drawable element describing an arc

    Attributes:

    o tracklines    Boolean for whether to draw lines dilineating tracks

    o pagesize      Tuple describing the size of the page in pixels

    o x0            Float X co-ord for leftmost point of drawable area

    o xlim          Float X co-ord for rightmost point of drawable area

    o y0            Float Y co-ord for lowest point of drawable area

    o ylim          Float Y co-ord for topmost point of drawable area

    o pagewidth     Float pixel width of drawable area

    o pageheight    Float pixel height of drawable area

    o xcenter       Float X co-ord of center of drawable area

    o ycenter       Float Y co-ord of center of drawable area

    o start         Int, base to start drawing from

    o end           Int, base to stop drawing at

    o length        Size of sequence to be drawn

    o track_size    Float (0->1) the proportion of the track height to
                    draw in

    o drawing       Drawing canvas

    o drawn_tracks  List of ints denoting which tracks are to be drawn

    o current_track_level   Int denoting which track is currently being
                            drawn

    o track_offsets     Dictionary of number of pixels that each track top,
                        center and bottom is offset from the base of a
                        fragment, keyed by track

    o sweep     Float (0->1) the proportion of the circle circumference to
                use for the diagram

    o cross_track_links List of tuples each with four entries (track A,
                        feature A, track B, feature B) to be linked.

Definition at line 42 of file _CircularDrawer.py.


Constructor & Destructor Documentation

def Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer.__init__ (   self,
  parent = None,
  pagesize = 'A3',
  orientation = 'landscape',
  x = 0.05,
  y = 0.05,
  xl = None,
  xr = None,
  yt = None,
  yb = None,
  start = None,
  end = None,
  tracklines = 0,
  track_size = 0.75,
  circular = 1,
  circle_core = 0.0,
  cross_track_links = None 
)
__init__(self, parent, pagesize='A3', orientation='landscape',
     x=0.05, y=0.05, xl=None, xr=None, yt=None, yb=None,
     start=None, end=None, tracklines=0, track_size=0.75,
     circular=1)

    o parent    Diagram object containing the data that the drawer
        draws

    o pagesize  String describing the ISO size of the image, or a tuple
        of pixels

    o orientation   String describing the required orientation of the
            final drawing ('landscape' or 'portrait')

    o x         Float (0->1) describing the relative size of the X
        margins to the page

    o y         Float (0->1) describing the relative size of the Y
        margins to the page

    o xl        Float (0->1) describing the relative size of the left X
        margin to the page (overrides x)

    o xl        Float (0->1) describing the relative size of the left X
        margin to the page (overrides x)

    o xr        Float (0->1) describing the relative size of the right X
        margin to the page (overrides x)

    o yt        Float (0->1) describing the relative size of the top Y
        margin to the page (overrides y)

    o yb        Float (0->1) describing the relative size of the lower Y
        margin to the page (overrides y)

    o start     Int, the position to begin drawing the diagram at

    o end       Int, the position to stop drawing the diagram at

    o tracklines    Boolean flag to show (or not) lines delineating tracks
            on the diagram            
            
    o track_size    The proportion of the available track height that
            should be taken up in drawing

    o circular      Boolean flaw to show whether the passed sequence is
            circular or not

    o circle_core   The proportion of the available radius to leave
            empty at the center of a circular diagram (0 to 1).

    o cross_track_links List of tuples each with four entries (track A,
                feature A, track B, feature B) to be linked.

Definition at line 170 of file _CircularDrawer.py.

00170 
00171                  circular=1, circle_core=0.0, cross_track_links=None):
00172         """ __init__(self, parent, pagesize='A3', orientation='landscape',
00173                      x=0.05, y=0.05, xl=None, xr=None, yt=None, yb=None,
00174                      start=None, end=None, tracklines=0, track_size=0.75,
00175                      circular=1)
00176 
00177             o parent    Diagram object containing the data that the drawer
00178                         draws
00179 
00180             o pagesize  String describing the ISO size of the image, or a tuple
00181                         of pixels
00182 
00183             o orientation   String describing the required orientation of the
00184                             final drawing ('landscape' or 'portrait')
00185 
00186             o x         Float (0->1) describing the relative size of the X
00187                         margins to the page
00188 
00189             o y         Float (0->1) describing the relative size of the Y
00190                         margins to the page
00191 
00192             o xl        Float (0->1) describing the relative size of the left X
00193                         margin to the page (overrides x)
00194 
00195             o xl        Float (0->1) describing the relative size of the left X
00196                         margin to the page (overrides x)
00197 
00198             o xr        Float (0->1) describing the relative size of the right X
00199                         margin to the page (overrides x)
00200 
00201             o yt        Float (0->1) describing the relative size of the top Y
00202                         margin to the page (overrides y)
00203 
00204             o yb        Float (0->1) describing the relative size of the lower Y
00205                         margin to the page (overrides y)
00206 
00207             o start     Int, the position to begin drawing the diagram at
00208 
00209             o end       Int, the position to stop drawing the diagram at
00210 
00211             o tracklines    Boolean flag to show (or not) lines delineating tracks
00212                             on the diagram            
00213                             
00214             o track_size    The proportion of the available track height that
00215                             should be taken up in drawing
00216 
00217             o circular      Boolean flaw to show whether the passed sequence is
00218                             circular or not
00219 
00220             o circle_core   The proportion of the available radius to leave
00221                             empty at the center of a circular diagram (0 to 1).
00222 
00223             o cross_track_links List of tuples each with four entries (track A,
00224                                 feature A, track B, feature B) to be linked.
00225         """
00226         # Use the superclass' instantiation method
00227         AbstractDrawer.__init__(self, parent, pagesize, orientation,
00228                                   x, y, xl, xr, yt, yb, start, end,
00229                                   tracklines, cross_track_links)
00230 
00231         # Useful measurements on the page
00232         self.track_size = track_size
00233         self.circle_core = circle_core
00234         if circular == False:   # Determine the proportion of the circumference
00235             self.sweep = 0.9    # around which information will be drawn
00236         else:
00237             self.sweep = 1
00238 

Here is the caller graph for this function:


Member Function Documentation

def Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer._draw_arc (   self,
  inner_radius,
  outer_radius,
  startangle,
  endangle,
  color,
  border = None,
  colour = None,
  kwargs 
) [private]
draw_arc(self, inner_radius, outer_radius, startangle, endangle, color)
-> Group

    o inner_radius  Float distance of inside of arc from drawing center

    o outer_radius  Float distance of outside of arc from drawing center

    o startangle    Float angle subtended by start of arc at drawing center
            (in radians)

    o endangle      Float angle subtended by end of arc at drawing center
            (in radians)

    o color        colors.Color object for arc (overridden by backwards
           compatible argument with UK spelling, colour).

    Returns a closed path object describing an arced box corresponding to
    the passed values.  For very small angles, a simple four sided
    polygon is used.

Definition at line 1058 of file _CircularDrawer.py.

01058 
01059                  color, border=None, colour=None, **kwargs):
01060         """ draw_arc(self, inner_radius, outer_radius, startangle, endangle, color)
01061                 -> Group
01062 
01063             o inner_radius  Float distance of inside of arc from drawing center
01064 
01065             o outer_radius  Float distance of outside of arc from drawing center
01066 
01067             o startangle    Float angle subtended by start of arc at drawing center
01068                             (in radians)
01069 
01070             o endangle      Float angle subtended by end of arc at drawing center
01071                             (in radians)
01072 
01073             o color        colors.Color object for arc (overridden by backwards
01074                            compatible argument with UK spelling, colour).
01075 
01076             Returns a closed path object describing an arced box corresponding to
01077             the passed values.  For very small angles, a simple four sided
01078             polygon is used.
01079         """
01080         #Let the UK spelling (colour) override the USA spelling (color)
01081         if colour is not None:
01082             color = colour
01083 
01084         if color == colors.white and border is None:   # Force black border on 
01085             strokecolor = colors.black                 # white boxes with
01086         elif border is None:                           # undefined border, else
01087             strokecolor = color                        # use fill color
01088         elif border:
01089             if not isinstance(border, colors.Color):
01090                 raise ValueError("Invalid border color %s" % repr(border))
01091             strokecolor = border
01092         else:
01093             #e.g. False
01094             strokecolor = None
01095 
01096         if abs(float(endangle - startangle))>.01:
01097             # Wide arc, must use full curves
01098             p = ArcPath(strokeColor=strokecolor,
01099                         fillColor=color,
01100                         strokewidth=0)
01101             #Note reportlab counts angles anti-clockwise from the horizontal
01102             #(as in mathematics, e.g. complex numbers and polar coordinates)
01103             #but we use clockwise from the vertical.  Also reportlab uses
01104             #degrees, but we use radians.
01105             p.addArc(self.xcenter, self.ycenter, inner_radius,
01106                      90 - (endangle * 180 / pi), 90 - (startangle * 180 / pi),
01107                      moveTo=True)
01108             p.addArc(self.xcenter, self.ycenter, outer_radius,
01109                      90 - (endangle * 180 / pi), 90 - (startangle * 180 / pi),
01110                      reverse=True)
01111             p.closePath()
01112             return p
01113         else:
01114             #Cheat and just use a four sided polygon.
01115             # Calculate trig values for angle and coordinates
01116             startcos, startsin = cos(startangle), sin(startangle)
01117             endcos, endsin = cos(endangle), sin(endangle)
01118             x0,y0 = self.xcenter, self.ycenter      # origin of the circle
01119             x1,y1 = (x0+inner_radius*startsin, y0+inner_radius*startcos)
01120             x2,y2 = (x0+inner_radius*endsin, y0+inner_radius*endcos)
01121             x3,y3 = (x0+outer_radius*endsin, y0+outer_radius*endcos)
01122             x4,y4 = (x0+outer_radius*startsin, y0+outer_radius*startcos)
01123             return draw_polygon([(x1,y1),(x2,y2),(x3,y3),(x4,y4)], color, border)

Here is the call graph for this function:

Here is the caller graph for this function:

def Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer._draw_arc_arrow (   self,
  inner_radius,
  outer_radius,
  startangle,
  endangle,
  color,
  border = None,
  shaft_height_ratio = 0.4,
  head_length_ratio = 0.5,
  orientation = 'right',
  colour = None,
  kwargs 
) [private]
Draw an arrow along an arc.

Definition at line 1217 of file _CircularDrawer.py.

01217 
01218                   colour=None, **kwargs):
01219         """Draw an arrow along an arc."""
01220         #Let the UK spelling (colour) override the USA spelling (color)
01221         if colour is not None:
01222             color = colour
01223 
01224         if color == colors.white and border is None:   # Force black border on 
01225             strokecolor = colors.black                 # white boxes with
01226         elif border is None:                           # undefined border, else
01227             strokecolor = color                        # use fill color
01228         elif border:
01229             if not isinstance(border, colors.Color):
01230                 raise ValueError("Invalid border color %s" % repr(border))
01231             strokecolor = border
01232         else:
01233             #e.g. False
01234             strokecolor = None
01235 
01236         #if orientation == 'right':
01237         #    startangle, endangle = min(startangle, endangle), max(startangle, endangle)
01238         #elif orientation == 'left':
01239         #    startangle, endangle = max(startangle, endangle), min(startangle, endangle)
01240         #else:
01241         startangle, endangle = min(startangle, endangle), max(startangle, endangle)
01242         if orientation != "left" and orientation != "right":
01243             raise ValueError("Invalid orientation %s, should be 'left' or 'right'" \
01244                              % repr(orientation))
01245 
01246         angle = float(endangle - startangle)    # angle subtended by arc
01247         middle_radius = 0.5*(inner_radius+outer_radius)
01248         boxheight = outer_radius - inner_radius
01249         shaft_height = boxheight*shaft_height_ratio
01250         shaft_inner_radius = middle_radius - 0.5*shaft_height
01251         shaft_outer_radius = middle_radius + 0.5*shaft_height
01252         headangle_delta = max(0.0,min(abs(boxheight)*head_length_ratio/middle_radius, abs(angle)))
01253         if angle < 0:
01254             headangle_delta *= -1 #reverse it
01255         if orientation=="right":
01256             headangle = endangle-headangle_delta
01257         else:
01258             headangle = startangle+headangle_delta
01259         if startangle <= endangle:
01260             headangle = max(min(headangle, endangle), startangle)
01261         else:
01262             headangle = max(min(headangle, startangle), endangle)
01263         assert startangle <= headangle <= endangle \
01264             or endangle <= headangle <= startangle, \
01265             (startangle, headangle, endangle, angle)
01266         
01267 
01268         # Calculate trig values for angle and coordinates
01269         startcos, startsin = cos(startangle), sin(startangle)
01270         headcos, headsin = cos(headangle), sin(headangle)
01271         endcos, endsin = cos(endangle), sin(endangle)
01272         x0,y0 = self.xcenter, self.ycenter      # origin of the circle
01273         if 0.5 >= abs(angle) and abs(headangle_delta) >= abs(angle):
01274             #If the angle is small, and the arrow is all head,
01275             #cheat and just use a triangle.
01276             if orientation=="right":
01277                 x1,y1 = (x0+inner_radius*startsin, y0+inner_radius*startcos)
01278                 x2,y2 = (x0+outer_radius*startsin, y0+outer_radius*startcos)
01279                 x3,y3 = (x0+middle_radius*endsin, y0+middle_radius*endcos)
01280             else:
01281                 x1,y1 = (x0+inner_radius*endsin, y0+inner_radius*endcos)
01282                 x2,y2 = (x0+outer_radius*endsin, y0+outer_radius*endcos)
01283                 x3,y3 = (x0+middle_radius*startsin, y0+middle_radius*startcos)
01284             #return draw_polygon([(x1,y1),(x2,y2),(x3,y3)], color, border,
01285             #                    stroke_line_join=1)
01286             return Polygon([x1,y1,x2,y2,x3,y3],
01287                            strokeColor=border or color,
01288                            fillColor=color,
01289                            strokeLineJoin=1, #1=round, not mitre!
01290                            strokewidth=0)
01291         elif orientation=="right":
01292             p = ArcPath(strokeColor=strokecolor,
01293                         fillColor=color,
01294                         #default is mitre/miter which can stick out too much:
01295                         strokeLineJoin=1, #1=round
01296                         strokewidth=0,
01297                         **kwargs)
01298             #Note reportlab counts angles anti-clockwise from the horizontal
01299             #(as in mathematics, e.g. complex numbers and polar coordinates)
01300             #but we use clockwise from the vertical.  Also reportlab uses
01301             #degrees, but we use radians.
01302             p.addArc(self.xcenter, self.ycenter, shaft_inner_radius,
01303                      90 - (headangle * 180 / pi), 90 - (startangle * 180 / pi),
01304                      moveTo=True)
01305             p.addArc(self.xcenter, self.ycenter, shaft_outer_radius,
01306                      90 - (headangle * 180 / pi), 90 - (startangle * 180 / pi),
01307                      reverse=True)
01308             p.lineTo(x0+outer_radius*headsin, y0+outer_radius*headcos)
01309             if abs(angle) < 0.5:
01310                 p.lineTo(x0+middle_radius*endsin, y0+middle_radius*endcos)
01311                 p.lineTo(x0+inner_radius*headsin, y0+inner_radius*headcos)
01312             else:
01313                 dx = min(0.1, abs(angle)/50.0) #auto-scale number of steps
01314                 x = dx
01315                 while x < 1:
01316                     r = outer_radius - x*(outer_radius-middle_radius)
01317                     a = headangle + x*(endangle-headangle)
01318                     p.lineTo(x0+r*sin(a), y0+r*cos(a))
01319                     x += dx
01320                 p.lineTo(x0+middle_radius*endsin, y0+middle_radius*endcos)
01321                 x = dx
01322                 while x < 1:
01323                     r = middle_radius - x*(middle_radius-inner_radius)
01324                     a = headangle + (1-x)*(endangle-headangle)
01325                     p.lineTo(x0+r*sin(a), y0+r*cos(a))
01326                     x += dx
01327                 p.lineTo(x0+inner_radius*headsin, y0+inner_radius*headcos)
01328             p.closePath()
01329             return p
01330         else:
01331             p = ArcPath(strokeColor=strokecolor,
01332                         fillColor=color,
01333                         #default is mitre/miter which can stick out too much:
01334                         strokeLineJoin=1, #1=round
01335                         strokewidth=0,
01336                         **kwargs)
01337             #Note reportlab counts angles anti-clockwise from the horizontal
01338             #(as in mathematics, e.g. complex numbers and polar coordinates)
01339             #but we use clockwise from the vertical.  Also reportlab uses
01340             #degrees, but we use radians.
01341             p.addArc(self.xcenter, self.ycenter, shaft_inner_radius,
01342                      90 - (endangle * 180 / pi), 90 - (headangle * 180 / pi),
01343                      moveTo=True, reverse=True)
01344             p.addArc(self.xcenter, self.ycenter, shaft_outer_radius,
01345                      90 - (endangle * 180 / pi), 90 - (headangle * 180 / pi),
01346                      reverse=False)
01347             p.lineTo(x0+outer_radius*headsin, y0+outer_radius*headcos)
01348             #Note - two staight lines is only a good approximation for small
01349             #head angle, in general will need to curved lines here:
01350             if abs(angle) < 0.5:
01351                 p.lineTo(x0+middle_radius*startsin, y0+middle_radius*startcos)
01352                 p.lineTo(x0+inner_radius*headsin, y0+inner_radius*headcos)
01353             else:
01354                 dx = min(0.1, abs(angle)/50.0) #auto-scale number of steps
01355                 x = dx
01356                 while x < 1:
01357                     r = outer_radius - x*(outer_radius-middle_radius)
01358                     a = headangle + x*(startangle-headangle)
01359                     p.lineTo(x0+r*sin(a), y0+r*cos(a))
01360                     x += dx
01361                 p.lineTo(x0+middle_radius*startsin, y0+middle_radius*startcos)
01362                 x = dx
01363                 while x < 1:
01364                     r = middle_radius - x*(middle_radius-inner_radius)
01365                     a = headangle + (1-x)*(startangle-headangle)
01366                     p.lineTo(x0+r*sin(a), y0+r*cos(a))
01367                     x += dx
01368                 p.lineTo(x0+inner_radius*headsin, y0+inner_radius*headcos)
01369             p.closePath()
01370             return p
01371 

Here is the caller graph for this function:

def Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer._draw_arc_poly (   self,
  inner_radius,
  outer_radius,
  inner_startangle,
  inner_endangle,
  outer_startangle,
  outer_endangle,
  color,
  border = None,
  flip = False,
  kwargs 
) [private]

Definition at line 1128 of file _CircularDrawer.py.

01128 
01129                        **kwargs):
01130 
01131         if color == colors.white and border is None:   # Force black border on 
01132             strokecolor = colors.black                 # white boxes with
01133         elif border is None:                           # undefined border, else
01134             strokecolor = color                        # use fill color
01135         elif border:
01136             if not isinstance(border, colors.Color):
01137                 raise ValueError("Invalid border color %s" % repr(border))
01138             strokecolor = border
01139         else:
01140             #e.g. False
01141             strokecolor = None
01142         
01143         x0, y0 = self.xcenter, self.ycenter      # origin of the circle
01144         if abs(inner_endangle - outer_startangle)>0.01 \
01145         or abs(outer_endangle - inner_startangle)>0.01 \
01146         or abs(inner_startangle - outer_startangle)>0.01 \
01147         or abs(outer_startangle - outer_startangle)>0.01:
01148             # Wide arc, must use full curves
01149             p = ArcPath(strokeColor=strokecolor,
01150                         fillColor=color,
01151                         #default is mitre/miter which can stick out too much:
01152                         strokeLineJoin=1, #1=round
01153                         strokewidth=0)
01154             #Note reportlab counts angles anti-clockwise from the horizontal
01155             #(as in mathematics, e.g. complex numbers and polar coordinates)
01156             #but we use clockwise from the vertical.  Also reportlab uses
01157             #degrees, but we use radians.
01158             i_start = 90 - (inner_startangle * 180 / pi)
01159             i_end = 90 - (inner_endangle * 180 / pi)
01160             o_start = 90 - (outer_startangle * 180 / pi)
01161             o_end = 90 - (outer_endangle * 180 / pi)
01162             p.addArc(x0, y0, inner_radius, i_end, i_start,
01163                      moveTo=True, reverse=True)
01164             if flip:
01165                 #Flipped, join end to start,
01166                 dx = 0.1
01167                 x = dx
01168                 while x < 1:
01169                     r = inner_radius + x*(outer_radius-inner_radius)
01170                     a = (i_end + x*(o_start-i_end))*pi/180 #to radians for sin/cos
01171                     p.lineTo(x0+r*cos(a), y0+r*sin(a))
01172                     x += dx
01173                 p.addArc(x0, y0, outer_radius, o_end, o_start, reverse=True)
01174                 x = dx
01175                 while x < 1:
01176                     r = outer_radius - x*(outer_radius-inner_radius)
01177                     a = (o_end + x*(i_start-o_end))*pi/180 #to radians for sin/cos
01178                     p.lineTo(x0+r*cos(a), y0+r*sin(a))
01179                     x += dx
01180             else:
01181                 #Not flipped, join start to start, end to end
01182                 dx = 0.1
01183                 x = dx
01184                 while x < 1:
01185                     r = inner_radius + x*(outer_radius-inner_radius)
01186                     a = (i_end + x*(o_end-i_end))*pi/180 #to radians for sin/cos
01187                     p.lineTo(x0+r*cos(a), y0+r*sin(a))
01188                     x += dx
01189                 p.addArc(x0, y0, outer_radius, o_end, o_start,
01190                          reverse=False)
01191                 x = dx
01192                 while x < 1:
01193                     r = outer_radius - x*(outer_radius-inner_radius)
01194                     a = (o_start + x*(i_start-o_start))*pi/180 #to radians for sin/cos
01195                     p.lineTo(x0+r*cos(a), y0+r*sin(a))
01196                     x += dx
01197             p.closePath()
01198             return p
01199         else:
01200             #Cheat and just use a four sided polygon.
01201             # Calculate trig values for angle and coordinates
01202             inner_startcos, inner_startsin = cos(inner_startangle), sin(inner_startangle)
01203             inner_endcos, inner_endsin = cos(inner_endangle), sin(inner_endangle)
01204             outer_startcos, outer_startsin = cos(outer_startangle), sin(outer_startangle)
01205             outer_endcos, outer_endsin = cos(outer_endangle), sin(outer_endangle)
01206             x1,y1 = (x0+inner_radius*inner_startsin, y0+inner_radius*inner_startcos)
01207             x2,y2 = (x0+inner_radius*inner_endsin, y0+inner_radius*inner_endcos)
01208             x3,y3 = (x0+outer_radius*outer_endsin, y0+outer_radius*outer_endcos)
01209             x4,y4 = (x0+outer_radius*outer_startsin, y0+outer_radius*outer_startcos)
01210             return draw_polygon([(x1,y1),(x2,y2),(x3,y3),(x4,y4)], color, border,
01211                                 #default is mitre/miter which can stick out too much:
01212                                 strokeLineJoin=1, #1=round
01213                                 )

Here is the call graph for this function:

Here is the caller graph for this function:

canvas_angle(self, base) -> (float, float, float)

Definition at line 1050 of file _CircularDrawer.py.

01050 
01051     def canvas_angle(self, base):
01052         """ canvas_angle(self, base) -> (float, float, float)
01053         """
01054         angle = self.sweep*2*pi*(base-self.start)/self.length
01055         return (angle, cos(angle), sin(angle))
01056 

Here is the call graph for this function:

Here is the caller graph for this function:

draw(self)

    Draw a circular diagram of the stored data

Definition at line 274 of file _CircularDrawer.py.

00274 
00275     def draw(self):
00276         """ draw(self)
00277 
00278             Draw a circular diagram of the stored data
00279         """
00280         # Instantiate the drawing canvas
00281         self.drawing = Drawing(self.pagesize[0], self.pagesize[1])
00282 
00283         feature_elements = []           # holds feature elements
00284         feature_labels = []             # holds feature labels
00285         greytrack_bgs = []              # holds track background
00286         greytrack_labels = []           # holds track foreground labels
00287         scale_axes = []                 # holds scale axes
00288         scale_labels = []               # holds scale axis labels
00289 
00290         # Get tracks to be drawn and set track sizes
00291         self.drawn_tracks = self._parent.get_drawn_levels()        
00292         self.set_track_heights()
00293 
00294         # Go through each track in the parent (if it is to be drawn) one by
00295         # one and collate the data as drawing elements
00296         for track_level in self._parent.get_drawn_levels():
00297             self.current_track_level = track_level
00298             track = self._parent[track_level]
00299             gbgs, glabels = self.draw_greytrack(track)    # Greytracks
00300             greytrack_bgs.append(gbgs)
00301             greytrack_labels.append(glabels)
00302             features, flabels = self.draw_track(track)   # Features and graphs
00303             feature_elements.append(features)
00304             feature_labels.append(flabels)
00305             if track.scale:
00306                 axes, slabels = self.draw_scale(track)       # Scale axes
00307                 scale_axes.append(axes)
00308                 scale_labels.append(slabels)
00309 
00310         feature_cross_links = []
00311         for cross_link_obj in self.cross_track_links:
00312             cross_link_elements = self.draw_cross_link(cross_link_obj)
00313             if cross_link_elements:
00314                 feature_cross_links.append(cross_link_elements)
00315 
00316         # Groups listed in order of addition to page (from back to front)
00317         # Draw track backgrounds
00318         # Draw feature cross track links
00319         # Draw features and graphs
00320         # Draw scale axes
00321         # Draw scale labels
00322         # Draw feature labels
00323         # Draw track labels
00324         element_groups = [greytrack_bgs, feature_cross_links,
00325                           feature_elements,
00326                           scale_axes, scale_labels,
00327                           feature_labels, greytrack_labels
00328                           ]
00329         for element_group in element_groups:
00330             for element_list in element_group:
00331                 [self.drawing.add(element) for element in element_list]
00332             
00333         if self.tracklines:             # Draw test tracks over top of diagram
00334             self.draw_test_tracks()
00335 

draw_bar_graph(self, graph) -> [element, element,...]

    o graph     Graph object

    Returns a list of drawable elements for a bar graph of the passed
    Graph object

Definition at line 647 of file _CircularDrawer.py.

00647 
00648     def draw_bar_graph(self, graph):
00649         """ draw_bar_graph(self, graph) -> [element, element,...]
00650 
00651             o graph     Graph object
00652 
00653             Returns a list of drawable elements for a bar graph of the passed
00654             Graph object
00655         """
00656         #print '\tdraw_bar_graph'
00657         # At each point contained in the graph data, we draw a vertical bar
00658         # from the track center to the height of the datapoint value (positive
00659         # values go up in one color, negative go down in the alternative
00660         # color).
00661         bar_elements = []
00662         
00663         # Set the number of pixels per unit for the data
00664         data_quartiles = graph.quartiles()
00665         minval, maxval = data_quartiles[0],data_quartiles[4]
00666         btm, ctr, top = self.track_radii[self.current_track_level]
00667         trackheight = 0.5*(top-btm)
00668         datarange = maxval - minval
00669         if datarange == 0:
00670             datarange = trackheight
00671         data = graph[self.start:self.end]
00672         # midval is the value at which the x-axis is plotted, and is the
00673         # central ring in the track
00674         if graph.center is None:
00675             midval = (maxval + minval)/2.    
00676         else:
00677             midval = graph.center
00678 
00679         # Convert data into 'binned' blocks, covering half the distance to the
00680         # next data point on either side, accounting for the ends of fragments
00681         # and tracks
00682         start, end = self._current_track_start_end()
00683         data = intermediate_points(start, end, graph[start:end])
00684 
00685         if not data:
00686             return []
00687 
00688         # Whichever is the greatest difference: max-midval or min-midval, is
00689         # taken to specify the number of pixel units resolved along the
00690         # y-axis
00691         resolution = max((midval-minval), (maxval-midval))
00692         if resolution == 0:
00693             resolution = trackheight
00694 
00695         # Create elements for the bar graph based on newdata
00696         for pos0, pos1, val in data:
00697             pos0angle, pos0cos, pos0sin = self.canvas_angle(pos0)
00698             pos1angle, pos1cos, pos1sin = self.canvas_angle(pos1)
00699 
00700             barval = trackheight*(val-midval)/resolution
00701             if barval >=0:
00702                 barcolor = graph.poscolor
00703             else:
00704                 barcolor = graph.negcolor
00705 
00706             # Draw bar
00707             bar_elements.append(self._draw_arc(ctr, ctr+barval, pos0angle,
00708                                               pos1angle, barcolor))
00709         return bar_elements
00710 
00711     
00712 

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 500 of file _CircularDrawer.py.

00500 
00501     def draw_cross_link(self, cross_link):
00502         startA = cross_link.startA
00503         startB = cross_link.startB
00504         endA = cross_link.endA
00505         endB = cross_link.endB
00506            
00507         if not self.is_in_bounds(startA) \
00508         and not self.is_in_bounds(endA):
00509             return None
00510         if not self.is_in_bounds(startB) \
00511         and not self.is_in_bounds(endB):
00512             return None
00513 
00514         if startA < self.start: startA = self.start
00515         if startB < self.start: startB = self.start
00516         if self.end < endA: endA = self.end
00517         if self.end < endB: endB = self.end
00518 
00519         trackobjA = cross_link._trackA(self._parent.tracks.values())
00520         trackobjB = cross_link._trackB(self._parent.tracks.values())
00521         assert trackobjA is not None
00522         assert trackobjB is not None
00523         if trackobjA == trackobjB: raise NotImplementedError()
00524 
00525         if trackobjA.start is not None:
00526             if endA < trackobjA.start:
00527                 return
00528             startA = max(startA, trackobjA.start)
00529         if trackobjA.end is not None:
00530             if trackobjA.end < startA:
00531                 return
00532             endA = min(endA, trackobjA.end)
00533         if trackobjB.start is not None:
00534             if endB < trackobjB.start:
00535                 return
00536             startB = max(startB, trackobjB.start)
00537         if trackobjB.end is not None:
00538             if trackobjB.end < startB:
00539                 return
00540             endB = min(endB, trackobjB.end)
00541 
00542         for track_level in self._parent.get_drawn_levels():
00543             track = self._parent[track_level]
00544             if track == trackobjA:
00545                 trackA = track_level
00546             if track == trackobjB:
00547                 trackB = track_level
00548         if trackA == trackB: raise NotImplementedError()
00549 
00550         startangleA, startcosA, startsinA = self.canvas_angle(startA)
00551         startangleB, startcosB, startsinB = self.canvas_angle(startB)
00552         endangleA, endcosA, endsinA = self.canvas_angle(endA)
00553         endangleB, endcosB, endsinB = self.canvas_angle(endB)
00554 
00555         btmA, ctrA, topA = self.track_radii[trackA]
00556         btmB, ctrB, topB = self.track_radii[trackB]
00557 
00558         if ctrA < ctrB:
00559             return [self._draw_arc_poly(topA, btmB,
00560                            startangleA, endangleA,
00561                            startangleB, endangleB,
00562                            cross_link.color, cross_link.border, cross_link.flip)]
00563         else:
00564             return [self._draw_arc_poly(btmA, topB,
00565                            startangleA, endangleA,
00566                            startangleB, endangleB,
00567                            cross_link.color, cross_link.border, cross_link.flip)]
00568 

Here is the call graph for this function:

draw_feature(self, feature, parent_feature=None) -> ([element, element,...], [element, element,...])

    o feature           Feature containing location info

    Returns tuple of (list of elements describing single feature, list
    of labels for those elements)

Definition at line 380 of file _CircularDrawer.py.

00380 
00381     def draw_feature(self, feature):
00382         """ draw_feature(self, feature, parent_feature=None) -> ([element, element,...], [element, element,...])
00383 
00384             o feature           Feature containing location info
00385 
00386             Returns tuple of (list of elements describing single feature, list
00387             of labels for those elements)
00388         """        
00389         feature_elements = []   # Holds drawable elements for a single feature
00390         label_elements = []     # Holds labels for a single feature
00391 
00392         if feature.hide:    # Don't show feature: return early
00393             return feature_elements, label_elements
00394 
00395         start, end = self._current_track_start_end()
00396         # A single feature may be split into subfeatures, so loop over them
00397         for locstart, locend in feature.locations:
00398             if locend < start:
00399                 continue
00400             locstart = max(locstart, start)
00401             if end < locstart:
00402                 continue
00403             locend = min(locend, end)
00404             # Get sigil for the feature/ each subfeature
00405             feature_sigil, label = self.get_feature_sigil(feature, locstart, locend)
00406             feature_elements.append(feature_sigil)
00407             if label is not None:   # If there's a label
00408                 label_elements.append(label)
00409 
00410         return feature_elements, label_elements
00411 

Here is the call graph for this function:

Here is the caller graph for this function:

draw_feature_set(self, set) -> ([element, element,...], [element, element,...])

    o set       FeatureSet object

    Returns a tuple (list of elements describing features, list of
    labels for elements)

Definition at line 358 of file _CircularDrawer.py.

00358 
00359     def draw_feature_set(self, set):
00360         """ draw_feature_set(self, set) -> ([element, element,...], [element, element,...])
00361 
00362             o set       FeatureSet object
00363 
00364             Returns a tuple (list of elements describing features, list of
00365             labels for elements)
00366         """
00367         #print 'draw feature set'
00368         feature_elements = []   # Holds diagram elements belonging to the features
00369         label_elements = []     # Holds diagram elements belonging to feature labels 
00370 
00371         # Collect all the elements for the feature set
00372         for feature in set.get_features():
00373             if self.is_in_bounds(feature.start) or self.is_in_bounds(feature.end):
00374                 features, labels = self.draw_feature(feature)
00375                 feature_elements += features
00376                 label_elements += labels
00377 
00378         return feature_elements, label_elements
00379         

Here is the call graph for this function:

Here is the caller graph for this function:

draw_graph_set(self, set) -> ([element, element,...], [element, element,...])

    o set       GraphSet object

    Returns tuple (list of graph elements, list of graph labels)

Definition at line 569 of file _CircularDrawer.py.

00569 
00570     def draw_graph_set(self, set):
00571         """ draw_graph_set(self, set) -> ([element, element,...], [element, element,...])
00572         
00573             o set       GraphSet object
00574 
00575             Returns tuple (list of graph elements, list of graph labels)
00576         """
00577         #print 'draw graph set'
00578         elements = []   # Holds graph elements
00579 
00580         # Distribution dictionary for how to draw the graph
00581         style_methods = {'line': self.draw_line_graph,
00582                          'heat': self.draw_heat_graph,
00583                          'bar': self.draw_bar_graph
00584                          }
00585 
00586         for graph in set.get_graphs():
00587             #print graph.name
00588             elements += style_methods[graph.style](graph)
00589 
00590         return elements, []
00591 

Here is the call graph for this function:

Here is the caller graph for this function:

draw_greytrack(self)

    o track     Track object

    Put in a grey background to the current track, if the track
    specifies that we should

Definition at line 987 of file _CircularDrawer.py.

00987 
00988     def draw_greytrack(self, track):
00989         """ draw_greytrack(self)
00990 
00991             o track     Track object
00992 
00993             Put in a grey background to the current track, if the track
00994             specifies that we should
00995         """
00996         greytrack_bgs = []      # Holds track backgrounds
00997         greytrack_labels = []   # Holds track foreground labels
00998 
00999         if not track.greytrack: # No greytrack required, return early
01000             return [], []
01001 
01002         # Get track location
01003         btm, ctr, top = self.track_radii[self.current_track_level]
01004 
01005         start, end = self._current_track_start_end()
01006         startangle, startcos, startsin = self.canvas_angle(start)
01007         endangle, endcos, endsin = self.canvas_angle(end)
01008 
01009         # Make background
01010         if track.start is not None or track.end is not None:
01011             #Draw an arc, leaving out the wedge
01012             p = ArcPath(strokeColor=track.scale_color, fillColor=None)
01013             greytrack_bgs.append(self._draw_arc(btm, top, startangle, endangle,
01014                                  colors.Color(0.96, 0.96, 0.96)))
01015         elif self.sweep < 1:
01016             #Make a partial circle, a large arc box
01017             #This method assumes the correct center for us.
01018             greytrack_bgs.append(self._draw_arc(btm, top, 0, 2*pi*self.sweep,
01019                                  colors.Color(0.96, 0.96, 0.96)))
01020         else:
01021             #Make a full circle (using a VERY thick linewidth)
01022             greytrack_bgs.append(Circle(self.xcenter, self.ycenter, ctr, 
01023                                  strokeColor = colors.Color(0.96, 0.96, 0.96),
01024                                  fillColor=None, strokeWidth=top-btm))
01025 
01026         if track.greytrack_labels:  # Labels are required for this track
01027             labelstep = self.length//track.greytrack_labels  # label interval
01028             for pos in range(self.start, self.end, labelstep):
01029                 label = String(0, 0, track.name,            # Add a new label at
01030                            fontName=track.greytrack_font,   # each interval
01031                            fontSize=track.greytrack_fontsize,
01032                            fillColor=track.greytrack_fontcolor)
01033                 theta, costheta, sintheta = self.canvas_angle(pos)
01034                 if theta < startangle or endangle < theta:
01035                     continue
01036                 x,y = self.xcenter+btm*sintheta, self.ycenter+btm*costheta  # start text halfway up marker
01037                 labelgroup = Group(label)
01038                 labelangle = self.sweep*2*pi*(pos-self.start)/self.length - pi/2
01039                 if theta > pi:  
01040                     label.textAnchor = 'end'    # Anchor end of text to inner radius
01041                     labelangle += pi            # and reorient it
01042                 cosA, sinA = cos(labelangle), sin(labelangle)
01043                 labelgroup.transform = (cosA, -sinA, sinA,
01044                                         cosA, x, y)
01045                 if not self.length-x <= labelstep:  # Don't overrun the circle
01046                     greytrack_labels.append(labelgroup)
01047 
01048         return greytrack_bgs, greytrack_labels
01049 

Here is the call graph for this function:

draw_heat_graph(self, graph) -> [element, element,...]

    o graph     Graph object

    Returns a list of drawable elements for the heat graph

Definition at line 713 of file _CircularDrawer.py.

00713 
00714     def draw_heat_graph(self, graph):
00715         """ draw_heat_graph(self, graph) -> [element, element,...]
00716 
00717             o graph     Graph object
00718 
00719             Returns a list of drawable elements for the heat graph
00720         """
00721         #print '\tdraw_heat_graph'
00722         # At each point contained in the graph data, we draw a box that is the
00723         # full height of the track, extending from the midpoint between the
00724         # previous and current data points to the midpoint between the current
00725         # and next data points
00726         heat_elements = []      # holds drawable elements
00727 
00728         # Get graph data
00729         data_quartiles = graph.quartiles()
00730         minval, maxval = data_quartiles[0],data_quartiles[4]
00731         midval = (maxval + minval)/2.    # mid is the value at the X-axis
00732         btm, ctr, top = self.track_radii[self.current_track_level]
00733         trackheight = (top-btm)
00734 
00735         start, end = self._current_track_start_end()
00736         data = intermediate_points(start, end, graph[start:end])
00737 
00738         # Create elements on the graph, indicating a large positive value by
00739         # the graph's poscolor, and a large negative value by the graph's
00740         # negcolor attributes
00741         for pos0, pos1, val in data:
00742             pos0angle, pos0cos, pos0sin = self.canvas_angle(pos0)
00743             pos1angle, pos1cos, pos1sin = self.canvas_angle(pos1)
00744 
00745             # Calculate the heat color, based on the differential between
00746             # the value and the median value
00747             heat = colors.linearlyInterpolatedColor(graph.poscolor,
00748                                                     graph.negcolor,
00749                                                     maxval, minval, val)
00750             
00751             # Draw heat box
00752             heat_elements.append(self._draw_arc(btm, top, pos0angle, pos1angle,
00753                                                 heat, border=heat))
00754         return heat_elements
00755 

Here is the call graph for this function:

Here is the caller graph for this function:

draw_line_graph(self, graph, center) -> [element, element,...]

    o graph     GraphData object

    Returns a line graph as a list of drawable elements

Definition at line 592 of file _CircularDrawer.py.

00592 
00593     def draw_line_graph(self, graph):
00594         """ draw_line_graph(self, graph, center) -> [element, element,...]
00595 
00596             o graph     GraphData object
00597 
00598             Returns a line graph as a list of drawable elements
00599         """
00600         #print '\tdraw_line_graph'
00601         line_elements = []  # holds drawable elements
00602 
00603         # Get graph data
00604         data_quartiles = graph.quartiles()
00605         minval, maxval = data_quartiles[0],data_quartiles[4]
00606         btm, ctr, top = self.track_radii[self.current_track_level]
00607         trackheight = 0.5*(top-btm)
00608         datarange = maxval - minval
00609         if datarange == 0:
00610             datarange = trackheight
00611 
00612         start, end = self._current_track_start_end()
00613         data = graph[start:end]
00614         
00615         if not data:
00616             return []
00617 
00618         # midval is the value at which the x-axis is plotted, and is the
00619         # central ring in the track
00620         if graph.center is None:
00621             midval = (maxval + minval)/2.    
00622         else:
00623             midval = graph.center
00624         # Whichever is the greatest difference: max-midval or min-midval, is
00625         # taken to specify the number of pixel units resolved along the
00626         # y-axis
00627         resolution = max((midval-minval), (maxval-midval))
00628 
00629         # Start from first data point
00630         pos, val = data[0]
00631         lastangle, lastcos, lastsin = self.canvas_angle(pos)
00632         # We calculate the track height
00633         posheight = trackheight*(val-midval)/resolution + ctr
00634         lastx = self.xcenter+posheight*lastsin  # start xy coords
00635         lasty = self.ycenter+posheight*lastcos
00636         for pos, val in data:
00637             posangle, poscos, possin = self.canvas_angle(pos)
00638             posheight = trackheight*(val-midval)/resolution + ctr
00639             x = self.xcenter+posheight*possin   # next xy coords
00640             y = self.ycenter+posheight*poscos
00641             line_elements.append(Line(lastx, lasty, x, y,
00642                                       strokeColor = graph.poscolor,
00643                                       strokeWidth = graph.linewidth))
00644             lastx, lasty, = x, y
00645         return line_elements
00646         

Here is the call graph for this function:

Here is the caller graph for this function:

draw_scale(self, track) -> ([element, element,...], [element, element,...])

    o track     Track object

    Returns a tuple of (list of elements in the scale, list of labels
    in the scale)

Definition at line 756 of file _CircularDrawer.py.

00756 
00757     def draw_scale(self, track):
00758         """ draw_scale(self, track) -> ([element, element,...], [element, element,...])
00759 
00760             o track     Track object
00761 
00762             Returns a tuple of (list of elements in the scale, list of labels
00763             in the scale)
00764         """
00765         scale_elements = []     # holds axes and ticks
00766         scale_labels = []       # holds labels
00767 
00768         if not track.scale:     # no scale required, exit early
00769             return [], []
00770 
00771         # Get track locations
00772         btm, ctr, top = self.track_radii[self.current_track_level]
00773         trackheight = (top-ctr)
00774         
00775         # X-axis
00776         start, end = self._current_track_start_end()
00777         if track.start is not None or track.end is not None:
00778             #Draw an arc, leaving out the wedge
00779             p = ArcPath(strokeColor=track.scale_color, fillColor=None)
00780             startangle, startcos, startsin = self.canvas_angle(start)
00781             endangle, endcos, endsin = self.canvas_angle(end)
00782             p.addArc(self.xcenter, self.ycenter, ctr,
00783                      90 - (endangle * 180 / pi),
00784                      90 - (startangle * 180 / pi))
00785             scale_elements.append(p)
00786             del p
00787             # Y-axis start marker
00788             x0, y0 = self.xcenter+btm*startsin, self.ycenter+btm*startcos
00789             x1, y1 = self.xcenter+top*startsin, self.ycenter+top*startcos
00790             scale_elements.append(Line(x0, y0, x1, y1, strokeColor=track.scale_color))
00791             # Y-axis end marker
00792             x0, y0 = self.xcenter+btm*endsin, self.ycenter+btm*endcos
00793             x1, y1 = self.xcenter+top*endsin, self.ycenter+top*endcos
00794             scale_elements.append(Line(x0, y0, x1, y1, strokeColor=track.scale_color))
00795         elif self.sweep < 1:
00796             #Draw an arc, leaving out the wedge
00797             p = ArcPath(strokeColor=track.scale_color, fillColor=None)
00798             #Note reportlab counts angles anti-clockwise from the horizontal
00799             #(as in mathematics, e.g. complex numbers and polar coordinates)
00800             #in degrees.
00801             p.addArc(self.xcenter, self.ycenter, ctr,
00802                      startangledegrees=90-360*self.sweep,
00803                      endangledegrees=90)
00804             scale_elements.append(p)
00805             del p
00806             # Y-axis start marker
00807             x0, y0 = self.xcenter, self.ycenter+btm
00808             x1, y1 = self.xcenter, self.ycenter+top
00809             scale_elements.append(Line(x0, y0, x1, y1, strokeColor=track.scale_color))
00810             # Y-axis end marker
00811             alpha = 2*pi*self.sweep
00812             x0, y0 = self.xcenter+btm*sin(alpha), self.ycenter+btm*cos(alpha)
00813             x1, y1 = self.xcenter+top*sin(alpha), self.ycenter+top*cos(alpha)
00814             scale_elements.append(Line(x0, y0, x1, y1, strokeColor=track.scale_color))
00815         else:
00816             #Draw a full circle
00817             scale_elements.append(Circle(self.xcenter, self.ycenter, ctr,
00818                                          strokeColor=track.scale_color,
00819                                          fillColor=None))
00820 
00821         start, end = self._current_track_start_end()
00822         if track.scale_ticks:   # Ticks are required on the scale
00823             # Draw large ticks 
00824             #I want the ticks to be consistently positioned relative to
00825             #the start of the sequence (position 0), not relative to the
00826             #current viewpoint (self.start and self.end)
00827 
00828             ticklen = track.scale_largeticks * trackheight
00829             tickiterval = int(track.scale_largetick_interval)
00830             #Note that we could just start the list of ticks using
00831             #range(0,self.end,tickinterval) and the filter out the
00832             #ones before self.start - but this seems wasteful.
00833             #Using tickiterval * (self.start/tickiterval) is a shortcut.
00834             for tickpos in range(tickiterval * (self.start//tickiterval),
00835                                  int(self.end), tickiterval):
00836                 if tickpos <= start or end <= tickpos:
00837                     continue
00838                 tick, label = self.draw_tick(tickpos, ctr, ticklen,
00839                                              track,
00840                                              track.scale_largetick_labels)
00841                 scale_elements.append(tick)
00842                 if label is not None:   # If there's a label, add it
00843                     scale_labels.append(label)
00844             # Draw small ticks
00845             ticklen = track.scale_smallticks * trackheight
00846             tickiterval = int(track.scale_smalltick_interval)
00847             for tickpos in range(tickiterval * (self.start//tickiterval),
00848                                  int(self.end), tickiterval):
00849                 if tickpos <= start or end <= tickpos:
00850                     continue
00851                 tick, label = self.draw_tick(tickpos, ctr, ticklen,
00852                                              track,
00853                                              track.scale_smalltick_labels)
00854                 scale_elements.append(tick)
00855                 if label is not None:   # If there's a label, add it
00856                     scale_labels.append(label)
00857         
00858         # Check to see if the track contains a graph - if it does, get the
00859         # minimum and maximum values, and put them on the scale Y-axis
00860         # at 60 degree intervals, ordering the labels by graph_id
00861         startangle, startcos, startsin = self.canvas_angle(start)
00862         endangle, endcos, endsin = self.canvas_angle(end)
00863         if track.axis_labels:
00864             for set in track.get_sets():
00865                 if set.__class__ is GraphSet:
00866                     # Y-axis
00867                     for n in xrange(7):
00868                         angle = n * 1.0471975511965976
00869                         if angle < startangle or endangle < angle:
00870                             continue
00871                         ticksin, tickcos = sin(angle), cos(angle)
00872                         x0, y0 = self.xcenter+btm*ticksin, self.ycenter+btm*tickcos
00873                         x1, y1 = self.xcenter+top*ticksin, self.ycenter+top*tickcos
00874                         scale_elements.append(Line(x0, y0, x1, y1,
00875                                                    strokeColor=track.scale_color))
00876 
00877                         graph_label_min = []
00878                         graph_label_max = []
00879                         graph_label_mid = []
00880                         for graph in set.get_graphs():                        
00881                             quartiles = graph.quartiles()
00882                             minval, maxval = quartiles[0], quartiles[4]
00883                             if graph.center is None:
00884                                 midval = (maxval + minval)/2.
00885                                 graph_label_min.append("%.3f" % minval)
00886                                 graph_label_max.append("%.3f" % maxval)
00887                                 graph_label_mid.append("%.3f" % midval)
00888                             else:
00889                                 diff = max((graph.center-minval),
00890                                            (maxval-graph.center))
00891                                 minval = graph.center-diff
00892                                 maxval = graph.center+diff
00893                                 midval = graph.center
00894                                 graph_label_mid.append("%.3f" % midval)
00895                                 graph_label_min.append("%.3f" % minval)
00896                                 graph_label_max.append("%.3f" % maxval)
00897                         xmid, ymid = (x0+x1)/2., (y0+y1)/2.
00898                         for limit, x, y, in [(graph_label_min, x0, y0),
00899                                              (graph_label_max, x1, y1),
00900                                              (graph_label_mid, xmid, ymid)]:
00901                             label = String(0, 0, ";".join(limit),
00902                                            fontName=track.scale_font,
00903                                            fontSize=track.scale_fontsize,
00904                                            fillColor=track.scale_color)
00905                             label.textAnchor = 'middle'
00906                             labelgroup = Group(label)
00907                             labelgroup.transform = (tickcos, -ticksin,
00908                                                     ticksin, tickcos,
00909                                                     x, y)
00910                             scale_labels.append(labelgroup)
00911 
00912         return scale_elements, scale_labels
00913 

Here is the call graph for this function:

draw_test_tracks(self)

    Draw blue ones indicating tracks to be drawn, with a green line
    down the center.

Definition at line 966 of file _CircularDrawer.py.

00966 
00967     def draw_test_tracks(self):
00968         """ draw_test_tracks(self)
00969 
00970             Draw blue ones indicating tracks to be drawn, with a green line
00971             down the center.
00972         """
00973         #print 'drawing test tracks'
00974         # Add lines only for drawn tracks
00975         for track in self.drawn_tracks:
00976             btm, ctr, top = self.track_radii[track]            
00977             self.drawing.add(Circle(self.xcenter, self.ycenter, top,
00978                                     strokeColor=colors.blue,
00979                                     fillColor=None))  # top line
00980             self.drawing.add(Circle(self.xcenter, self.ycenter, ctr,
00981                                     strokeColor=colors.green,
00982                                     fillColor=None))  # middle line
00983             self.drawing.add(Circle(self.xcenter, self.ycenter, btm,
00984                                     strokeColor=colors.blue,
00985                                     fillColor=None))  # bottom line
00986 

def Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer.draw_tick (   self,
  tickpos,
  ctr,
  ticklen,
  track,
  draw_label 
)
draw_tick(self, tickpos, ctr, ticklen) -> (element, element)

    o tickpos   Int, position of the tick on the sequence

    o ctr       Float, Y co-ord of the center of the track

    o ticklen   How long to draw the tick

    o track     Track, the track the tick is drawn on

    o draw_label    Boolean, write the tick label?

    Returns a drawing element that is the tick on the scale

Definition at line 914 of file _CircularDrawer.py.

00914 
00915     def draw_tick(self, tickpos, ctr, ticklen, track, draw_label):
00916         """ draw_tick(self, tickpos, ctr, ticklen) -> (element, element)
00917 
00918             o tickpos   Int, position of the tick on the sequence
00919 
00920             o ctr       Float, Y co-ord of the center of the track
00921 
00922             o ticklen   How long to draw the tick
00923 
00924             o track     Track, the track the tick is drawn on
00925 
00926             o draw_label    Boolean, write the tick label?
00927 
00928             Returns a drawing element that is the tick on the scale
00929         """
00930         # Calculate tick co-ordinates
00931         tickangle, tickcos, ticksin = self.canvas_angle(tickpos)
00932         x0, y0 = self.xcenter+ctr*ticksin, self.ycenter+ctr*tickcos
00933         x1, y1 = self.xcenter+(ctr+ticklen)*ticksin, self.ycenter+(ctr+ticklen)*tickcos
00934         # Calculate height of text label so it can be offset on lower half
00935         # of diagram
00936         # LP: not used, as not all fonts have ascent_descent data in reportlab.pdfbase._fontdata
00937         #label_offset = _fontdata.ascent_descent[track.scale_font][0]*\
00938         #               track.scale_fontsize/1000.
00939         tick = Line(x0, y0, x1, y1, strokeColor=track.scale_color)
00940         if draw_label:                          # Put tick position on as label
00941             if track.scale_format == 'SInt':
00942                 if tickpos >= 1000000:
00943                     tickstring = str(tickpos//1000000) + " Mbp"
00944                 elif tickpos >= 1000:
00945                     tickstring = str(tickpos//1000) + " Kbp"
00946                 else:
00947                     tickstring = str(tickpos)
00948             else:
00949                 tickstring = str(tickpos)
00950             label = String(0, 0, tickstring,  # Make label string
00951                            fontName=track.scale_font,
00952                            fontSize=track.scale_fontsize,
00953                            fillColor=track.scale_color)
00954             if tickangle > pi:
00955                 label.textAnchor = 'end'
00956             # LP: This label_offset depends on ascent_descent data, which is not available for all 
00957             # fonts, so has been deprecated.
00958             #if 0.5*pi < tickangle < 1.5*pi:
00959             #    y1 -= label_offset
00960             labelgroup = Group(label)
00961             labelgroup.transform = (1,0,0,1, x1, y1)
00962         else:
00963             labelgroup = None
00964         return tick, labelgroup
00965 

Here is the call graph for this function:

Here is the caller graph for this function:

draw_track(self, track) -> ([element, element,...], [element, element,...])

    o track     Track object

    Return tuple of (list of track elements, list of track labels)           

Definition at line 336 of file _CircularDrawer.py.

00336 
00337     def draw_track(self, track):
00338         """ draw_track(self, track) -> ([element, element,...], [element, element,...])
00339 
00340             o track     Track object
00341 
00342             Return tuple of (list of track elements, list of track labels)           
00343         """
00344         track_elements = [] # Holds elements for features and graphs
00345         track_labels = []   # Holds labels for features and graphs
00346         
00347         # Distribution dictionary for dealing with different set types
00348         set_methods = {FeatureSet: self.draw_feature_set,
00349                        GraphSet: self.draw_graph_set
00350                        }
00351         
00352         for set in track.get_sets():        # Draw the feature or graph sets
00353             elements, labels = set_methods[set.__class__](set)
00354             track_elements += elements
00355             track_labels += labels
00356         return track_elements, track_labels
00357 

Here is the call graph for this function:

def Bio.Graphics.GenomeDiagram._CircularDrawer.CircularDrawer.get_feature_sigil (   self,
  feature,
  locstart,
  locend,
  kwargs 
)
get_feature_sigil(self, feature, x0, x1, fragment) -> (element, element)

    o feature       Feature object

    o locstart      The start position of the feature

    o locend        The end position of the feature

    Returns a drawable indicator of the feature, and any required label
    for it

Definition at line 412 of file _CircularDrawer.py.

00412 
00413     def get_feature_sigil(self, feature, locstart, locend, **kwargs):
00414         """ get_feature_sigil(self, feature, x0, x1, fragment) -> (element, element)
00415 
00416             o feature       Feature object
00417 
00418             o locstart      The start position of the feature
00419 
00420             o locend        The end position of the feature
00421 
00422             Returns a drawable indicator of the feature, and any required label
00423             for it
00424         """
00425         # Establish the co-ordinates for the sigil
00426         btm, ctr, top = self.track_radii[self.current_track_level]
00427         
00428         startangle, startcos, startsin = self.canvas_angle(locstart)
00429         endangle, endcos, endsin = self.canvas_angle(locend)
00430         midangle, midcos, midsin = self.canvas_angle(float(locend+locstart)/2)
00431 
00432         # Distribution dictionary for various ways of drawing the feature
00433         # Each method takes the inner and outer radii, the start and end angle
00434         # subtended at the diagram center, and the color as arguments
00435         draw_methods = {'BOX': self._draw_arc,
00436                         'ARROW': self._draw_arc_arrow,
00437                         }
00438 
00439         # Get sigil for the feature, location dependent on the feature strand        
00440         method = draw_methods[feature.sigil]
00441         kwargs['head_length_ratio'] = feature.arrowhead_length
00442         kwargs['shaft_height_ratio'] = feature.arrowshaft_height
00443         
00444         #Support for clickable links... needs ReportLab 2.4 or later
00445         #which added support for links in SVG output.
00446         if hasattr(feature, "url") :
00447             kwargs["hrefURL"] = feature.url
00448             kwargs["hrefTitle"] = feature.name
00449 
00450         border = feature.border
00451 
00452         if feature.strand == 1:
00453             sigil = method(ctr, top, startangle, endangle, feature.color,
00454                            border, orientation='right', **kwargs)
00455         elif feature.strand == -1:
00456             sigil = method(btm, ctr, startangle, endangle, feature.color,
00457                            border, orientation='left', **kwargs)
00458         else:
00459             sigil = method(btm, top, startangle, endangle, feature.color,
00460                            border, **kwargs)
00461 
00462         if feature.label:   # Feature needs a label
00463             label = String(0, 0, feature.name.strip(),
00464                            fontName=feature.label_font,
00465                            fontSize=feature.label_size,
00466                            fillColor=feature.label_color)
00467             labelgroup = Group(label)
00468             label_angle = startangle + 0.5 * pi     # Make text radial
00469             sinval, cosval = startsin, startcos
00470             if feature.strand != -1:
00471                 # Feature is on top, or covers both strands
00472                 if startangle < pi: # Turn text round and anchor end to inner radius
00473                     sinval, cosval = endsin, endcos
00474                     label_angle = endangle - 0.5 * pi
00475                     labelgroup.contents[0].textAnchor = 'end'
00476                 pos = self.xcenter+top*sinval
00477                 coslabel = cos(label_angle)
00478                 sinlabel = sin(label_angle)    
00479                 labelgroup.transform = (coslabel,-sinlabel,sinlabel,coslabel,
00480                                         pos, self.ycenter+top*cosval)
00481             else:
00482                 # Feature on bottom strand
00483                 if startangle < pi: # Turn text round and anchor end to inner radius
00484                     sinval, cosval = endsin, endcos
00485                     label_angle = endangle - 0.5 * pi
00486                 else:
00487                     labelgroup.contents[0].textAnchor = 'end'
00488                 pos = self.xcenter+btm*sinval
00489                 coslabel = cos(label_angle)
00490                 sinlabel = sin(label_angle)
00491                 labelgroup.transform = (coslabel,-sinlabel,sinlabel,coslabel,
00492                                         pos, self.ycenter+btm*cosval)
00493 
00494         else:
00495             labelgroup = None
00496         #if locstart > locend:
00497         #    print locstart, locend, feature.strand, sigil, feature.name
00498         #print locstart, locend, feature.name
00499         return sigil, labelgroup

Here is the call graph for this function:

Here is the caller graph for this function:

set_track_heights(self)

    Since tracks may not be of identical heights, the bottom and top
    radius for each track is stored in a dictionary - self.track_radii,
    keyed by track number

Definition at line 239 of file _CircularDrawer.py.

00239 
00240     def set_track_heights(self):
00241         """ set_track_heights(self)
00242 
00243             Since tracks may not be of identical heights, the bottom and top
00244             radius for each track is stored in a dictionary - self.track_radii,
00245             keyed by track number
00246         """
00247         bot_track = min(min(self.drawn_tracks), 1)
00248         top_track = max(self.drawn_tracks)     # The 'highest' track to draw
00249 
00250         trackunit_sum = 0           # Holds total number of 'units' taken up by all tracks
00251         trackunits = {}             # Holds start and end units for each track keyed by track number
00252         heightholder = 0            # placeholder variable
00253         for track in range(bot_track, top_track+1):    # track numbers to 'draw'
00254             try:
00255                 trackheight = self._parent[track].height    # Get track height
00256             except:
00257                 trackheight = 1                             # ...or default to 1
00258             trackunit_sum += trackheight    # increment total track unit height
00259             trackunits[track] = (heightholder, heightholder+trackheight)
00260             heightholder += trackheight     # move to next height
00261 
00262         trackunit_height = 0.5*min(self.pagewidth, self.pageheight)/trackunit_sum
00263         track_core = trackunit_height * self.circle_core
00264         trackunit_height = trackunit_height * (1-self.circle_core)
00265 
00266         # Calculate top and bottom radii for each track
00267         self.track_radii = {}      # The inner, outer and center radii for each track
00268         track_crop = trackunit_height*(1-self.track_size)/2.    # 'step back' in pixels
00269         for track in trackunits:
00270             top = trackunits[track][1]*trackunit_height - track_crop + track_core
00271             btm = trackunits[track][0]*trackunit_height + track_crop + track_core
00272             ctr = btm+(top-btm)/2.
00273             self.track_radii[track] = (btm, ctr, top)


Member Data Documentation

Definition at line 232 of file _CircularDrawer.py.

Definition at line 296 of file _CircularDrawer.py.

Definition at line 280 of file _CircularDrawer.py.

Definition at line 290 of file _CircularDrawer.py.

Definition at line 234 of file _CircularDrawer.py.

Definition at line 266 of file _CircularDrawer.py.

Definition at line 231 of file _CircularDrawer.py.


The documentation for this class was generated from the following file: