1 from csamtools import *
11 class SamtoolsError( Exception ):
12 '''exception raised in case of an error incurred in the samtools library.'''
14 def __init__(self, value):
17 return repr(self.value)
19 class SamtoolsDispatcher(object):
20 '''samtools dispatcher.
22 Emulates the samtools command line as module calls.
24 Captures stdout and stderr.
26 Raises a :class:`pysam.SamtoolsError` exception in case
27 samtools exits with an error code other than 0.
29 Some command line options are associated with parsers.
30 For example, the samtools command "pileup -c" creates
31 a tab-separated table on standard output. In order to
32 associate parsers with options, an optional list of
33 parsers can be supplied. The list will be processed
34 in order checking for the presence of each option.
36 If no parser is given or no appropriate parser is found,
37 the stdout output of samtools commands will be returned.
42 def __init__(self,dispatch, parsers):
43 self.dispatch = dispatch
44 self.parsers = parsers
47 def __call__(self, *args, **kwargs):
48 '''execute a samtools command
50 retval, stderr, stdout = csamtools._samtools_dispatch( self.dispatch, args )
51 if retval: raise SamtoolsError( "\n".join( stderr ) )
53 # samtools commands do not propagate the return code correctly.
54 # I have thus added this patch to throw if there is output on stderr.
55 # Note that there is sometimes output on stderr that is not an error,
56 # for example: [sam_header_read2] 2 sequences loaded.
57 # Ignore messages like these
58 stderr = [ x for x in stderr \
59 if not (x.startswith( "[sam_header_read2]" ) or \
60 x.startswith("[bam_index_load]") or \
61 x.startswith("[bam_sort_core]") or \
62 x.startswith("[samopen] SAM header is present") )
64 if stderr: raise SamtoolsError( "\n".join( stderr ) )
66 # call parser for stdout:
67 if not kwargs.get("raw") and stdout and self.parsers:
68 for options, parser in self.parsers:
69 for option in options:
70 if option not in args: break
76 def getMessages( self ):
80 '''return the samtools usage information for this command'''
81 retval, stderr, stdout = csamtools._samtools_dispatch( self.dispatch )
82 return "".join(stderr)
85 # samtools command line options to export in python
87 # import is a python reserved word.
89 # samtools 'documented' commands
90 "view" : ( "view", None ),
91 "sort" : ( "sort", None),
92 "mpileup" : ( "mpileup", None),
93 "depth" : ("depth", None),
94 "faidx" : ("faidx", None),
95 "tview" : ("tview", None),
96 "index" : ("index", None),
97 "idxstats" : ("idxstats", None),
98 "fixmate" : ("fixmate", None),
99 "flagstat" : ("flagstat", None),
100 "calmd" : ("calmd", None),
101 "merge" : ("merge", None),
102 "rmdup" : ("rmdup", None),
103 "reheader" : ("reheader", None),
104 "cat" : ("cat", None),
105 "targetcut" : ("targetcut", None),
106 "phase" : ("phase", None),
108 "samimport": ( "import", None),
109 "bam2fq" : ("bam2fq", None),
111 # "pileup" : ( "pileup", ( (("-c",), Pileup.iterate ), ), ),
115 # instantiate samtools commands as python functions
116 for key, options in SAMTOOLS_DISPATCH.iteritems():
117 cmd, parser = options
118 globals()[key] = SamtoolsDispatcher(cmd, parser)
120 # hack to export all the symbols from csamtools
122 csamtools.__all__ + \
125 [ "SamtoolsError", "SamtoolsDispatcher" ] + list(SAMTOOLS_DISPATCH) +\
128 from version import __version__, __samtools_version__