This file is indexed.

/usr/share/pyshared/cogent/draw/rlg2mpl.py is in python-cogent 1.5.1-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
"""ReportLab Graphics -> Matplotlib helpers"""

#linear, dotplot and dendrogram were originally written to target ReportLab Graphics rather
#than Matplotlib.  This module can be slowly boiled away as they become more matplotlib native.

from __future__ import division
from matplotlib.path import Path
from matplotlib.lines import Line2D
from matplotlib.text import Text
import matplotlib.patches as mpatches
import matplotlib.artist
import matplotlib.transforms
import matplotlib.colors
import numpy

from cogent.util.warning import discontinued

__author__ = "Peter Maxwell"
__copyright__ = "Copyright 2007-2011, The Cogent Project"
__credits__ = ["Peter Maxwell"]
__license__ = "GPL"
__version__ = "1.5.1"
__maintainer__ = "Peter Maxwell"
__email__ = "pm67nz@gmail.com"
__status__ = "Production"

def line_options(strokeColor='black', fillColor='black', strokeWidth=1):
    """Map from RLD line option names"""
    return dict(edgecolor=strokeColor, facecolor=fillColor, linewidth=strokeWidth)

def Line(x1, y1, x2, y2, **kw):
    """Acts like the RLG shape class of the same name"""
    path = Path([(x1, y1), (x2, y2)], [Path.MOVETO, Path.LINETO])
    return mpatches.PathPatch(path, **line_options(**kw))

def Rect(x, y, width, height, **kw):
    """Acts like the RLG shape class of the same name"""
    return mpatches.Rectangle((x,y),width,height,**line_options(**kw))

def Polygon(vertices, **kw):
    """Acts like the RLG shape class of the same name"""
    return mpatches.Polygon(vertices, **line_options(**kw))
    
def String(x, y, text, textAnchor='start', fontName=None, fontSize=10, 
        fillColor='black', rotation=None):
    """Acts like the RLG shape class of the same name"""
    fontname = fontName
    fontsize = fontSize
    color = fillColor
    ha = {'start':'left', 'middle':'center', 'end':'right'}[textAnchor]
    va = 'baseline'
    mpl_kw = dict((n,v) for (n,v) in locals().items() if n.islower())
    return Text(**mpl_kw)

class Group(matplotlib.artist.Artist):
    """Acts like the RLG shape class of the same name
    
    Groups elements together.  May apply a transform to its contents."""

    def __init__(self, *elements):
        """Initial lists of elements may be provided to allow
        compact definitions in literal Python code.  May or
        may not be useful."""
        matplotlib.artist.Artist.__init__(self)
        self.contents = []
        self.group_transform = matplotlib.transforms.Affine2D()
        self.outer_transform = matplotlib.transforms.TransformWrapper(
            self.get_transform())
        self.combined_transform = self.group_transform + self.outer_transform
        for elt in elements:
            self.add(elt)

    def set_figure(self, fig):
        matplotlib.artist.Artist.set_figure(self, fig)
        for c in self.contents:
            c.set_figure(fig)
    
    def set_clip_path(self, patch):
        matplotlib.artist.Artist.set_clip_path(self, patch)
        for c in self.contents:
            c.set_clip_path(patch)
          
    def set_transform(self, transform):
        matplotlib.artist.Artist.set_transform(self, transform)
        self.outer_transform.set(self.get_transform())
        
    def add(self, node, name=None):
        """Appends non-None child node to the 'contents' attribute. In addition,
        if a name is provided, it is subsequently accessible by name
        """
        # propagates properties down
        node.set_transform(node.get_transform() + self.combined_transform)
        self.contents.append(node)
    
    def rotate(self, theta):
        """Convenience to help you set transforms"""
        self.group_transform.rotate_deg(theta)

    def translate(self, dx, dy):
        """Convenience to help you set transforms"""
        self.group_transform.translate(dx, dy)

    def scale(self, sx, sy):
        """Convenience to help you set transforms"""
        self.group_transform.scale(sx, sy)

    def draw(self, renderer, *args, **kw):
        for c in self.contents:
            c.draw(renderer, *args, **kw)         


def figureLayout(width=None, height=None, margin=0.25, aspect=None, 
        default_aspect=0.75, useful_width=None, leftovers=False, **margins):
    """Width and height of a figure, plus a bounding box that nearly fills it, derived
    from defaults or provided margins.  All input figures are in inches."""
    left = margins.pop('left', 0) + margin
    right = margins.pop('right', 0) + margin
    top = margins.pop('top', 0) + margin
    bottom = margins.pop('bottom', 0) + margin
    default_width = 6  # use rcParams here?
    if useful_width:
        default_width = min(useful_width, default_width)
    width = width or default_width
    if aspect is not None:
        assert not height
        height = aspect * width
    else:
        height = height or default_aspect * width
    total_height = height + top + bottom
    total_width = width + left + right 
    posn = [left/total_width, bottom/total_height, width/total_width, height/total_height]
    if leftovers:
        return (total_width, total_height), posn, margins
    else:   
        assert not margins, margins.keys()
        return (total_width, total_height), posn

class Drawable(object):
    # Superclass for objects which can generate a matplotlib figure, in order 
    # to supply consistent and convenient showFigure() and drawToFile() 
    # methods.
    # Subclasses must provide .makeFigure() which will make use of 
    # _makeFigure() matplotlib.pyplot import done at runtime to give the 
    # user every chance to change the matplotlib backend first
    def _makeFigure(self, width, height, **kw):
        import matplotlib.pyplot as plt
        fig = plt.figure(figsize=(width,height), facecolor='white')
        return fig
                
    def drawFigure(self, title=None, **kw):
        """Draw the figure.  
        Extra arguments are forwarded to self.makeFigure()"""
        import matplotlib.pyplot as plt
        fig = self.makeFigure(**kw)
        if title is not None:
            fig.suptitle(title)
        plt.draw_if_interactive()
        
    def showFigure(self, title=None, **kw):
        """Make the figure and immediately pyplot.show() it.  
        Extra arguments are forwarded to self.makeFigure()"""
        self.drawFigure(title, **kw)
        import matplotlib.pyplot as plt
        plt.show()
        
    def drawToFile(self, fname, **kw):
        """Save in a file named 'fname'
        Extra arguments are forwarded to self.makeFigure() unless 
        they are valid for savefig()"""
        makefig_kw = {}
        savefig_kw = {}
        for (k,v) in kw.items():
            if k in ['dpi', 'facecolor', 'edgecolor', 'orientation',
                    'papertype', 'format', 'transparent']:
                savefig_kw[k] = v
            else:
                makefig_kw[k] = v    
        fig = self.makeFigure(**makefig_kw)
        fig.savefig(fname, **savefig_kw)
        
    def drawToPDF(self, filename, total_width=None, height=None, **kw):
        # Matches, as far as possible, old ReportLab version
        
        if total_width is not None:
            kw['width'] = total_width / 72
        kw2 = {}
        for (k,v) in kw.items():
            if k in ['wraps', 'border', 'withTrackLabelColumn']:
                discontinued('argument', "%s" % k, '1.6')
            else:
                kw2[k] = v
        kw2['format'] = 'pdf'
        if height:
            kw2['height'] = height / 72
        return self.drawToFile(filename, **kw2)


# For sequence feature styles:
# Matplotlib has fancy_box and fancy_arrow.  The code below is 
# similar, except that the two ends of the box have independent 
# styles: open, square, rounded, pointy, or blunt
        
class PathBuilder(object):
    """Path, made up of straight lines and bezier curves."""
    # Only used by the _End classes below

    def __init__(self):
        self.points = []
        self.operators = []

    def asPath(self):
        return Path(self.points, self.operators)

    def moveTo(self, x, y):
        self.points.append((x, y))
        self.operators.append(Path.MOVETO)

    def lineTo(self, x, y):
        self.points.append((x, y))
        self.operators.append(Path.LINETO)

    def curveTo(self, x1, y1, x2, y2, x3, y3):
        self.points.extend([(x1, y1), (x2, y2), (x3, y3)])
        self.operators.extend([Path.CURVE4]*3)

    def closePath(self):
        self.points.append((0.0, 0.0)) # ignored
        self.operators.append(Path.CLOSEPOLY)

class _End(object):
    
    def __init__(self, x_near, x_far, y_first, y_second, **kw):
        self.x_near = x_near
        self.x_far = x_far
        self.y_first = y_first
        self.y_second = y_second
        for (n, v) in kw.items():
            setattr(self, n, v)
    
    def moveToStart(self, path):
        path.moveTo(*self.startPoint())
    
    def drawToStart(self, path):
        path.lineTo(*self.startPoint())
    
    def finish(self, path):
        path.closePath()
    
    def startPoint(self):
        return (self.x_near, self.y_first)
        
    def __add__(self, oppo):
        p = PathBuilder()
        self.moveToStart(p)
        self.drawEnd(p)
        oppo.drawToStart(p)
        oppo.drawEnd(p)
        self.finish(p)
        return p.asPath()        
    
class Open(_End):
    def finish(self, path):
        self.drawToStart(path)
    
    def drawEnd(self, path):
        path.moveTo(self.x_near, self.y_second)
    
class Square(_End):
    def drawEnd(self, path):
        path.lineTo(self.x_near, self.y_second)
    
class Rounded(_End):
    def startPoint(self):
        return (self.x_near + self.dx, self.y_first)
    
    def drawEnd(self, path):
        path.curveTo(self.x_near, self.y_first, self.x_near, self.y_first,
                self.x_near, self.y_first + self.dy)
        path.lineTo(self.x_near, self.y_second - self.dy)
        path.curveTo(self.x_near, self.y_second, self.x_near, self.y_second,
                self.x_near + self.dx, self.y_second)    

class Pointy(_End):
    def _effective_dx(self):
        return max(abs(self.dx), abs(self.dy))*self.dx/abs(self.dx)
    
    def startPoint(self):
        return (self.x_near + self._effective_dx(), self.y_first)
    
    def drawEnd(self, path):
        head_start = self.x_near + self._effective_dx()
        middle = (self.y_first + self.y_second) / 2
        if self.blunt:
            for (x, y) in [
                    (head_start, self.y_first + self.dy),
                    (self.x_near, self.y_first),
                    (self.x_near, self.y_second),
                    (head_start, self.y_second - self.dy),
                    (head_start, self.y_second)]:
                path.lineTo(x, y)
        else:
            for (x, y) in [
                    (head_start, self.y_first + self.dy),
                    (self.x_near, middle),
                    (head_start, self.y_second - self.dy),
                    (head_start, self.y_second)]:
                path.lineTo(x, y)

def _sign(x):
    return x and x/abs(x)

def End(x1, x2, y1, y2, closed=True, rounded=False, pointy=False, blunt=False, 
        min_width=0.5, proportion_of_track=0.6):
    inwards = _sign(x2 - x1)
    span = max(abs(x2 - x1), min_width)
    thickness = abs(y1-y2)
    if pointy:
        head_size = min(thickness/20, span)
        head_size = max(head_size, min_width/2)
        height = thickness / proportion_of_track
        spare = (height - thickness) / 2
        end = Pointy(x1, x2, y1, y2,
                dx=inwards*head_size/2, dy=_sign(y1-y2)*spare,
                blunt=blunt)
    elif rounded:
        ry = thickness/4
        rx = min(span, ry)
        end = Rounded(x1, x2, y1, y2, dx=rx*inwards, dy=ry*_sign(y2-y1))
    elif not closed:
        end = Open(x1, x2, y1, y2)
    else:
        end = Square(x1, x2, y1, y2)
    return end