File: __init__.py

package info (click to toggle)
python-biopython 1.42-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 17,584 kB
  • ctags: 12,272
  • sloc: python: 80,461; xml: 13,834; ansic: 7,902; cpp: 1,855; sql: 1,144; makefile: 203
file content (212 lines) | stat: -rw-r--r-- 7,289 bytes parent folder | download
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
"""General mechanisms to access applications in biopython.
"""
import os
import StringIO
import popen2

from Bio import File

def generic_run(commandline):
    """Run an application with the given commandline.

    This expects a pre-built commandline that derives from 
    AbstractCommandline, and returns a ApplicationResult object
    to get results from a program, along with handles of the
    standard output and standard error.
    """
    # print str(commandline)
    child = popen2.Popen3(str(commandline), 1)
    # get information and close the files, so if we call this function
    # repeatedly we won't end up with too many open files

    # here are the file descriptors
    r = child.fromchild
    w = child.tochild
    e = child.childerr
    
    r_out = r.read()
    e_out = e.read()
    w.close()
    r.close()
    e.close()
    
    # capture error code
    error_code = os.WEXITSTATUS(child.wait())

    return ApplicationResult(commandline, error_code), \
           File.UndoHandle(StringIO.StringIO(r_out)), \
           File.UndoHandle(StringIO.StringIO(e_out))

class ApplicationResult:
    """Make results of a program available through a standard interface.
    
    This tries to pick up output information available from the program
    and make it available programmatically.
    """
    def __init__(self, application_cl, return_code):
        """Intialize with the commandline from the program.
        """
        self._cl = application_cl

        # provide the return code of the application
        self.return_code = return_code

        # get the application dependent results we can provide
        # right now the only results we handle are output files
        self._results = {}

        for parameter in self._cl.parameters:
            if "file" in parameter.param_types and \
               "output" in parameter.param_types:
                if parameter.is_set:
                    self._results[parameter.names[-1]] = parameter.value

    def get_result(self, output_name):
        """Retrieve result information for the given output.
        """
        return self._results[output_name]

    def available_results(self):
        """Retrieve a list of all available results.
        """
        result_names = self._results.keys()
        result_names.sort()
        return result_names

class AbstractCommandline:
    """Generic interface for running applications from biopython.

    This class shouldn't be called directly; it should be subclassed to
    provide an implementation for a specific application.
    """
    def __init__(self):
        self.program_name = ""
        self.parameters = []
    
    def __str__(self):
        """Make the commandline with the currently set options.
        """
        commandline = "%s " % self.program_name
        for parameter in self.parameters:
            if parameter.is_required and not(parameter.is_set):
                raise ValueError("Parameter %s is not set." % parameter.names)
            if parameter.is_set:
                commandline += str(parameter)

        return commandline

    def set_parameter(self, name, value = None):
        """Set a commandline option for a program.
        """
        set_option = 0
        for parameter in self.parameters:
            if name in parameter.names:
                if value is not None:
                    self._check_value(value, name, parameter.checker_function)
                    parameter.value = value
                parameter.is_set = 1
                set_option = 1

        if set_option == 0:
            raise ValueError("Option name %s was not found." % name)

    def _check_value(self, value, name, check_function):
        """Check whether the given value is valid.

        This uses the passed function 'check_function', which can either
        return a [0, 1] (bad, good) value or raise an error. Either way
        this function will raise an error if the value is not valid, or
        finish silently otherwise.
        """
        if check_function is not None:
            is_good = check_function(value)
            if is_good in [0, 1]: # if we are dealing with a good/bad check
                if not(is_good):
                    raise ValueError(
                            "Invalid parameter value %r for parameter %s" %
                            (value, name))
                    
class _AbstractParameter:
    """A class to hold information about a parameter for a commandline.

    Do not use this directly, instead use one of the subclasses.

    Attributes:

    o names -- a list of string names by which the parameter can be
    referenced (ie. ["-a", "--append", "append"]). The first name in
    the list is considered to be the one that goes on the commandline,
    for those parameters that print the option. The last name in the list
    is assumed to be a "human readable" name describing the option in one
    word.

    o param_type -- a list of string describing the type of parameter, 
    which can help let programs know how to use it. Example descriptions
    include 'input', 'output', 'file'

    o checker_function -- a reference to a function that will determine
    if a given value is valid for this parameter. This function can either
    raise an error when given a bad value, or return a [0, 1] decision on
    whether the value is correct.

    o description -- a description of the option.

    o is_required -- a flag to indicate if the parameter must be set for
    the program to be run.

    o is_set -- if the parameter has been set

    o value -- the value of a parameter
    """
    def __init__(self, names = [], types = [], checker_function = None, 
                 is_required = 0, description = ""):
        self.names = names
        self.param_types = types
        self.checker_function = checker_function
        self.description = description
        self.is_required = is_required

        self.is_set = 0
        self.value = None

class _Option(_AbstractParameter):
    """Represent an option that can be set for a program.

    This holds UNIXish options like --append=yes and -a yes
    """
    def __str__(self):
        """Return the value of this option for the commandline.
        """
        # first deal with long options
        if self.names[0].find("--") >= 0:
            output = "%s" % self.names[0]
            if self.value is not None:
                output += "=%s " % self.value
            else:
                output += " "
        # now short options
        elif self.names[0].find("-") >= 0:
            output = "%s " % self.names[0]
            if self.value is not None:
                output += "%s " % self.value
        else:
            raise ValueError("Unrecognized option type: %s" % self.names[0])

        return output

class _Argument(_AbstractParameter):
    """Represent an argument on a commandline.
    """
    def __str__(self):
        if self.value is not None:
            return "%s " % self.value
        else:
            return " "

# --- general functions to check for valid parameters
def _file_exists(self, filename):
    """Make sure that a passed filename exists.
    """
    if not(os.path.exists(filename)):
        raise ValueError("File %s does not exist." % filename)