This file is indexed.

/usr/share/pyshared/Bio/Graphics/Distribution.py is in python-biopython 1.58-1.

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
"""Display information distributed across a Chromosome-like object.

These classes are meant to show the distribution of some kind of information
as it changes across any kind of segment. It was designed with chromosome
distributions in mind, but could also work for chromosome regions, BAC clones
or anything similar.

Reportlab is used for producing the graphical output.
"""
# standard library
import math

# reportlab
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.lib import colors

from reportlab.graphics.shapes import Drawing, String
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.barcharts import BarChartProperties
from reportlab.graphics.widgetbase import TypedPropertyCollection
from reportlab.graphics import renderPDF, renderPS

from Bio.Graphics import _write

class DistributionPage(object):
    """Display a grouping of distributions on a page.

    This organizes Distributions, and will display them nicely
    on a single page.
    """
    def __init__(self, output_format = 'pdf'):
        self.distributions = []

        # customizable attributes
        self.number_of_columns = 1
        self.page_size = letter
        self.title_size = 20

        self.output_format = output_format

    def draw(self, output_file, title):
        """Draw out the distribution information.

        Arguments:

        o output_file - The name of the file to output the information to,
                        or a handle to write to.

        o title - A title to display on the graphic.
        """
        width, height = self.page_size
        cur_drawing = Drawing(width, height)

        self._draw_title(cur_drawing, title, width, height)

        # calculate the x and y position changes for each distribution
        cur_x_pos = inch * .5
        end_x_pos = width - inch * .5
        cur_y_pos = height - 1.5 * inch
        end_y_pos = .5 * inch
        x_pos_change = ((end_x_pos - cur_x_pos) /
                        float(self.number_of_columns))
        num_y_rows = math.ceil(float(len(self.distributions))
                               / float(self.number_of_columns))
        y_pos_change = (cur_y_pos - end_y_pos) / num_y_rows
        
        self._draw_distributions(cur_drawing, cur_x_pos, x_pos_change,
                                 cur_y_pos, y_pos_change, num_y_rows)
        self._draw_legend(cur_drawing, 2.5 * inch, width)

        return _write(cur_drawing, output_file, self.output_format)

    def _draw_title(self, cur_drawing, title, width, height):
        """Add the title of the figure to the drawing.
        """
        title_string = String(width / 2, height - inch, title)
        title_string.fontName = 'Helvetica-Bold'
        title_string.fontSize = self.title_size
        title_string.textAnchor = "middle"

        cur_drawing.add(title_string)

    def _draw_distributions(self, cur_drawing, start_x_pos, x_pos_change,
                            start_y_pos, y_pos_change, num_y_drawings):
        """Draw all of the distributions on the page.

        Arguments:

        o cur_drawing - The drawing we are working with.

        o start_x_pos - The x position on the page to start drawing at.

        o x_pos_change - The change in x position between each figure.

        o start_y_pos - The y position on the page to start drawing at.

        o y_pos_change - The change in y position between each figure.

        o num_y_drawings - The number of drawings we'll have in the y
        (up/down) direction.
        """
        for y_drawing in range(int(num_y_drawings)):
            # if we are on the last y position, we may not be able
            # to fill all of the x columns
            if ((y_drawing + 1) * self.number_of_columns >
                len(self.distributions)):
                num_x_drawings = len(self.distributions) - \
                                 y_drawing * self.number_of_columns
            else:
                num_x_drawings = self.number_of_columns
            for x_drawing in range(num_x_drawings):
                dist_num = y_drawing * self.number_of_columns + x_drawing
                cur_distribution = self.distributions[dist_num]

                # find the x and y boundaries of the distribution
                x_pos = start_x_pos + x_drawing * x_pos_change
                end_x_pos = x_pos + x_pos_change
                end_y_pos = start_y_pos - y_drawing * y_pos_change
                y_pos = end_y_pos - y_pos_change

                # draw the distribution
                cur_distribution.draw(cur_drawing, x_pos, y_pos, end_x_pos,
                                      end_y_pos)

    def _draw_legend(self, cur_drawing, start_y, width):
        """Add a legend to the figure.

        Subclasses can implement to provide a specialized legend.
        """
        pass

class BarChartDistribution(object):
    """Display the distribution of values as a bunch of bars.
    """
    def __init__(self, display_info = []):
        """Initialize a Bar Chart display of distribution info.

        Class attributes:

        o display_info - the information to be displayed in the distribution.
        This should be ordered as a list of lists, where each internal list
        is a data set to display in the bar chart.
        """
        self.display_info = display_info

        self.x_axis_title = ""
        self.y_axis_title = ""
        self.chart_title = ""
        self.chart_title_size = 10

        self.padding_percent = 0.15

    def draw(self, cur_drawing, start_x, start_y, end_x, end_y):
        """Draw a bar chart with the info in the specified range.
        """
        bar_chart = VerticalBarChart()
        if self.chart_title:
            self._draw_title(cur_drawing, self.chart_title,
                             start_x, start_y, end_x, end_y)
        # set the position of the bar chart
        x_start, x_end, y_start, y_end = \
           self._determine_position(start_x, start_y, end_x, end_y)
                                          
        bar_chart.x = x_start
        bar_chart.y = y_start
        bar_chart.width = abs(x_start - x_end)
        bar_chart.height = abs(y_start - y_end)

        # set the information in the bar chart
        bar_chart.data = self.display_info
        bar_chart.valueAxis.valueMin = min(self.display_info[0])
        bar_chart.valueAxis.valueMax = max(self.display_info[0])
        for data_set in self.display_info[1:]:
            if min(data_set) < bar_chart.valueAxis.valueMin:
                bar_chart.valueAxis.valueMin = min(data_set)
            if max(data_set) > bar_chart.valueAxis.valueMax:
                bar_chart.valueAxis.valueMax = max(data_set)

        # set other formatting options
        if len(self.display_info) == 1:
            bar_chart.groupSpacing = 0
            style = TypedPropertyCollection(BarChartProperties)
            style.strokeWidth = 0
            style.strokeColor = colors.green
            style[0].fillColor = colors.green

            bar_chart.bars = style
        

        # set the labels
        # XXX labels don't work yet
        # bar_chart.valueAxis.title = self.x_axis_title
        # bar_chart.categoryAxis.title = self.y_axis_title

        cur_drawing.add(bar_chart)

    def _draw_title(self, cur_drawing, title, start_x, start_y, end_x, end_y):
        """Add the title of the figure to the drawing.
        """
        x_center = start_x + (end_x - start_x) / 2
        y_pos = end_y + (self.padding_percent * (start_y - end_y)) / 2
        title_string = String(x_center, y_pos, title)
        title_string.fontName = 'Helvetica-Bold'
        title_string.fontSize = self.chart_title_size
        title_string.textAnchor = "middle"

        cur_drawing.add(title_string)

    def _determine_position(self, start_x, start_y, end_x, end_y):
        """Calculate the position of the chart with blank space.

        This uses some padding around the chart, and takes into account
        whether the chart has a title. It returns 4 values, which are,
        in order, the x_start, x_end, y_start and y_end of the chart
        itself.
        """
        x_padding = self.padding_percent * (end_x - start_x)
        y_padding = self.padding_percent * (start_y - end_y)

        new_x_start = start_x + x_padding
        new_x_end = end_x - x_padding

        if self.chart_title:
            new_y_start = start_y - y_padding - self.chart_title_size
        else:
            new_y_start = start_y - y_padding

        new_y_end = end_y + y_padding
        
        return new_x_start, new_x_end, new_y_start, new_y_end

class LineDistribution(object):
    """Display the distribution of values as connected lines.

    This distribution displays the change in values across the object as
    lines. This also allows multiple distributions to be displayed on a
    single graph.
    """
    def __init__(self):
        pass

    def draw(self, cur_drawing, start_x, start_y, end_x, end_y):
        pass