Imported Upstream version 0.3.1
[pysam.git] / pysam / __init__.py
1 from csamtools import *
2 from ctabix import *
3 import csamtools
4 import ctabix
5 import Pileup
6 import sys
7 import os
8
9 class SamtoolsError( Exception ):
10     '''exception raised in case of an error incurred in the samtools library.'''
11
12     def __init__(self, value):
13         self.value = value
14     def __str__(self):
15         return repr(self.value)
16
17 class SamtoolsDispatcher(object):
18     '''samtools dispatcher. 
19
20     Emulates the samtools command line as module calls.
21     
22     Captures stdout and stderr. 
23
24     Raises a :class:`pysam.SamtoolsError` exception in case
25     samtools exits with an error code other than 0.
26
27     Some command line options are associated with parsers.
28     For example, the samtools command "pileup -c" creates
29     a tab-separated table on standard output. In order to 
30     associate parsers with options, an optional list of 
31     parsers can be supplied. The list will be processed
32     in order checking for the presence of each option.
33
34     If no parser is given or no appropriate parser is found, 
35     the stdout output of samtools commands will be returned.
36     '''
37     dispatch=None
38     parsers=None
39
40     def __init__(self,dispatch, parsers): 
41         self.dispatch = dispatch
42         self.parsers = parsers
43         self.stderr = []
44
45     def __call__(self,*args, **kwargs):
46         '''execute the samtools command
47         '''
48         retval, stderr, stdout = csamtools._samtools_dispatch( self.dispatch, args )
49         if retval: raise SamtoolsError( "\n".join( stderr ) )
50         self.stderr = stderr
51         # samtools commands do not propagate the return code correctly.
52         # I have thus added this patch to throw if there is output on stderr.
53         # Note that there is sometimes output on stderr that is not an error,
54         # for example: [sam_header_read2] 2 sequences loaded.
55         # Ignore messages like these
56         stderr = [ x for x in stderr \
57                        if not x.startswith( "[sam_header_read2]" ) or \
58                        x.startswith("[bam_index_load]") or \
59                        x.startswith("[bam_sort_core]") or \
60                        x.startswith("[samopen] SAM header is present")
61                    ]
62         if stderr: raise SamtoolsError( "\n".join( stderr ) )
63
64         # call parser for stdout:
65         if not kwargs.get("raw") and stdout and self.parsers:
66             for options, parser in self.parsers:
67                 for option in options: 
68                     if option not in args: break
69                 else:
70                     return parser(stdout)
71
72         return stdout
73
74     def getMessages( self ):
75         return self.stderr
76
77     def usage(self):
78         '''return the samtools usage information for this command'''
79         retval, stderr, stdout = csamtools._samtools_dispatch( self.dispatch )
80         return "".join(stderr)
81
82 #
83 # samtools command line options to export in python
84 #
85 # import is a python reserved word.
86 SAMTOOLS_DISPATCH = { 
87     "view" : ( "view", None ),
88     "sort" : ( "sort", None),
89     "samimport": ( "import", None),
90     "pileup" : ( "pileup", ( (("-c",), Pileup.iterate ), ), ),
91     "faidx" : ("faidx", None),
92     "tview" : ("tview", None),
93     "index" : ("index", None),
94     "fixmate" : ("fixmate", None),
95     "glfview" : ("glfview", None),
96     "flagstat" : ("flagstat", None),
97     "calmd" : ("calmd", None),
98     "merge" : ("merge", None),  
99     "rmdup" : ("rmdup", None) }
100
101 # instantiate samtools commands as python functions
102 for key, options in SAMTOOLS_DISPATCH.iteritems():
103     cmd, parser = options
104     globals()[key] = SamtoolsDispatcher(cmd, parser)
105
106 # hack to export all the symbols from csamtools
107 __all__ = csamtools.__all__ + \
108     ctabix.__all__ + \
109     [ "SamtoolsError", "SamtoolsDispatcher" ] + list(SAMTOOLS_DISPATCH) +\
110     ["Pileup",] 
111
112 from version import __version__, __samtools_version__