Skip to content

Commit

Permalink
refactoring for htslib
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreasHeger committed Jun 7, 2014
1 parent cbc1845 commit 0c0ee00
Show file tree
Hide file tree
Showing 12 changed files with 6,354 additions and 5,034 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*#

# test directory
pysam/
tests/pysam/
tests/tmp*
tests/*.bam
tests/*.bai
Expand Down
56 changes: 29 additions & 27 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,35 +34,37 @@ include pysam.py
# pysam tests
include tests/00README.txt
include tests/Makefile
include tests/ex1.fa
include tests/ex1.sam.gz
include tests/ex3.sam
include tests/ex4.sam
include tests/ex5.sam
include tests/ex6.sam
include tests/ex7.sam
include tests/ex8.sam
include tests/ex9_fail.bam
include tests/ex9_nofail.bam
include tests/ex10.sam
include tests/example.py
include tests/pysam_test.py
include tests/segfault_tests.py
include tests/example_*.sam
include tests/example_btag.bam
include tests/tag_bug.bam
include tests/example.vcf40
include tests/example_empty_header.bam
include tests/test_unaligned.bam
include tests/issue100.bam
include tests/pysam_data
include tests/tabix_data
#ex1.fa
#include tests/ex1.sam.gz
#include tests/ex3.sam
#include tests/ex4.sam
#include tests/ex5.sam
#include tests/ex6.sam
#include tests/ex7.sam
#include tests/ex8.sam
#include tests/ex9_fail.bam
#include tests/ex9_nofail.bam
#include tests/ex10.sam
#include tests/example.py
#include tests/pysam_test.py
#include tests/segfault_tests.py
#include tests/example_*.sam
#include tests/example_btag.bam
#include tests/tag_bug.bam
#include tests/example.vcf40
#include tests/example_empty_header.bam
#include tests/test_unaligned.bam
#include tests/issue100.bam

# tabix tests
include tests/tabix_test.py
include tests/example.gtf.gz
include tests/example.gtf.gz.tbi
include tests/example.bed.gz
include tests/example.bed.gz.tbi
include tests/vcf-examples/*.vcf
#include tests/tabix_test.py
#include tests/example.gtf.gz
#include tests/example.gtf.gz.tbi
#include tests/example.bed.gz
#include tests/example.bed.gz.tbi
#include tests/vcf-examples/*.vcf

# documentation
include doc/*
142 changes: 78 additions & 64 deletions pysam/__init__.py
Original file line number Diff line number Diff line change
@@ -1,118 +1,130 @@
from pysam.csamtools import *
from pysam.chtslib import *
from pysam.ctabix import *
import pysam.csamtools as csamtools
import pysam.ctabix as ctabix
from pysam.cvcf import *
import pysam.cvcf as cvcf
import pysam.Pileup as Pileup
import sys
import os

class SamtoolsError( Exception ):
'''exception raised in case of an error incurred in the samtools library.'''

class SamtoolsError(Exception):
'''exception raised in case of an error incurred in the samtools
library.'''

def __init__(self, value):
self.value = value

def __str__(self):
return repr(self.value)


class SamtoolsDispatcher(object):
'''samtools dispatcher.
'''samtools dispatcher.
Emulates the samtools command line as module calls.
Captures stdout and stderr.
Captures stdout and stderr.
Raises a :class:`pysam.SamtoolsError` exception in case
samtools exits with an error code other than 0.
Some command line options are associated with parsers.
For example, the samtools command "pileup -c" creates
a tab-separated table on standard output. In order to
associate parsers with options, an optional list of
parsers can be supplied. The list will be processed
in order checking for the presence of each option.
Some command line options are associated with parsers. For
example, the samtools command "pileup -c" creates a tab-separated
table on standard output. In order to associate parsers with
options, an optional list of parsers can be supplied. The list
will be processed in order checking for the presence of each
option.
If no parser is given or no appropriate parser is found, the
stdout output of samtools commands will be returned.
If no parser is given or no appropriate parser is found,
the stdout output of samtools commands will be returned.
'''
dispatch=None
parsers=None

def __init__(self,dispatch, parsers):
dispatch = None
parsers = None

def __init__(self, dispatch, parsers):
self.dispatch = dispatch
self.parsers = parsers
self.stderr = []

def __call__(self, *args, **kwargs):
'''execute a samtools command
'''
retval, stderr, stdout = csamtools._samtools_dispatch( self.dispatch, args )
if retval: raise SamtoolsError( 'csamtools returned with error %i: %s' % (retval, "\n".join( stderr ) ))
retval, stderr, stdout = csamtools._samtools_dispatch(
self.dispatch, args)
if retval:
raise SamtoolsError(
'csamtools returned with error %i: %s' %
(retval, "\n".join(stderr)))
self.stderr = stderr
# samtools commands do not propagate the return code correctly.
# I have thus added this patch to throw if there is output on stderr.
# Note that there is sometimes output on stderr that is not an error,
# for example: [sam_header_read2] 2 sequences loaded.
# Ignore messages like these
stderr = [ x for x in stderr \
if not (x.startswith( "[sam_header_read2]" ) or \
x.startswith("[bam_index_load]") or \
x.startswith("[bam_sort_core]") or \
x.startswith("[samopen] SAM header is present") )
]
if stderr: raise SamtoolsError( "\n".join( stderr ) )
stderr = [x for x in stderr
if not (x.startswith("[sam_header_read2]") or
x.startswith("[bam_index_load]") or
x.startswith("[bam_sort_core]") or
x.startswith("[samopen] SAM header is present"))
]
if stderr:
raise SamtoolsError("\n".join(stderr))

# call parser for stdout:
if not kwargs.get("raw") and stdout and self.parsers:
for options, parser in self.parsers:
for option in options:
if option not in args: break
for option in options:
if option not in args:
break
else:
return parser(stdout)

return stdout

def getMessages( self ):
def getMessages(self):
return self.stderr

def usage(self):
'''return the samtools usage information for this command'''
retval, stderr, stdout = csamtools._samtools_dispatch( self.dispatch )
retval, stderr, stdout = csamtools._samtools_dispatch(
self.dispatch)
return "".join(stderr)

#
# samtools command line options to export in python
#
# import is a python reserved word.
SAMTOOLS_DISPATCH = {
SAMTOOLS_DISPATCH = {
# samtools 'documented' commands
"view" : ( "view", None ),
"sort" : ( "sort", None),
"mpileup" : ( "mpileup", None),
"depth" : ("depth", None),
"faidx" : ("faidx", None),
"tview" : ("tview", None),
"index" : ("index", None),
"idxstats" : ("idxstats", None),
"fixmate" : ("fixmate", None),
"flagstat" : ("flagstat", None),
"calmd" : ("calmd", None),
"merge" : ("merge", None),
"rmdup" : ("rmdup", None),
"reheader" : ("reheader", None),
"cat" : ("cat", None),
"targetcut" : ("targetcut", None),
"phase" : ("phase", None),
"view": ("view", None),
"sort": ("sort", None),
"mpileup": ("mpileup", None),
"depth": ("depth", None),
"faidx": ("faidx", None),
"tview": ("tview", None),
"index": ("index", None),
"idxstats": ("idxstats", None),
"fixmate": ("fixmate", None),
"flagstat": ("flagstat", None),
"calmd": ("calmd", None),
"merge": ("merge", None),
"rmdup": ("rmdup", None),
"reheader": ("reheader", None),
"cat": ("cat", None),
"targetcut": ("targetcut", None),
"phase": ("phase", None),
# others
"samimport": ( "import", None),
"bam2fq" : ("bam2fq", None),
"pad2unpad" : ("pad2unpad", None),
"depad" : ("pad2unpad", None),
"bedcov" : ("bedcov", None),
"bamshuf" : ("bamshuf", None),
"samimport": ("import", None),
"bam2fq": ("bam2fq", None),
"pad2unpad": ("pad2unpad", None),
"depad": ("pad2unpad", None),
"bedcov": ("bedcov", None),
"bamshuf": ("bamshuf", None),
# obsolete
# "pileup" : ( "pileup", ( (("-c",), Pileup.iterate ), ), ),
# "pileup": "pileup", ( (("-c",), Pileup.iterate),),),

}

Expand All @@ -123,23 +135,25 @@ def usage(self):

# hack to export all the symbols from csamtools
__all__ = \
csamtools.__all__ + \
chtslib.__all__ + \
ctabix.__all__ + \
cvcf.__all__ +\
[ "SamtoolsError", "SamtoolsDispatcher" ] + list(SAMTOOLS_DISPATCH) +\
["Pileup" ]
["SamtoolsError", "SamtoolsDispatcher"] +\
list(SAMTOOLS_DISPATCH) +\
["Pileup"]

from pysam.version import __version__, __samtools_version__

###########################################################
# Utility functions for compilation

def get_include():
'''return a list of include directories.'''
dirname = os.path.abspath(os.path.join(os.path.dirname(__file__)))
return [ dirname,
os.path.join(dirname, 'include', 'samtools'),
os.path.join(dirname, 'include', 'tabix') ]
return [dirname,
os.path.join(dirname, 'include', 'samtools'),
os.path.join(dirname, 'include', 'tabix')]


def get_defines():
'''return a list of defined compilation parameters.'''
return [('_FILE_OFFSET_BITS','64'), ('_USE_KNETFILE','')]
return [('_FILE_OFFSET_BITS', '64'),
('_USE_KNETFILE', '')]
Loading

0 comments on commit 0c0ee00

Please sign in to comment.