Warning

This document is for an old release of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.

Source code for galaxy.datatypes.converters.sam_to_bam

#!/usr/bin/env python
# Dan Blankenberg

"""
A wrapper script for converting SAM to BAM, with sorting.
%prog input_filename.sam output_filename.bam
"""
import optparse
import os
import shutil
import subprocess
import sys
import tempfile

import packaging.version

CHUNK_SIZE = 2 ** 20  # 1mb


[docs]def cleanup_before_exit(tmp_dir): if tmp_dir and os.path.exists(tmp_dir): shutil.rmtree(tmp_dir)
[docs]def cmd_exists(cmd): # http://stackoverflow.com/questions/5226958/which-equivalent-function-in-python for path in os.environ["PATH"].split(":"): if os.path.exists(os.path.join(path, cmd)): return True return False
def _get_samtools_version(): version = '0.0.0' if not cmd_exists('samtools'): raise Exception('This tool needs samtools, but it is not on PATH.') # Get the version of samtools via --version-only, if available p = subprocess.Popen(['samtools', '--version-only'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = p.communicate() # --version-only is available # Format is <version x.y.z>+htslib-<a.b.c> if p.returncode == 0: version = output.split('+')[0] return version output = subprocess.Popen(['samtools'], stderr=subprocess.PIPE, stdout=subprocess.PIPE).communicate()[1] lines = output.split('\n') for line in lines: if line.lower().startswith('version'): # Assuming line looks something like: version: 0.1.12a (r862) version = line.split()[1] break return version def __main__(): # Parse Command Line parser = optparse.OptionParser() (options, args) = parser.parse_args() assert len(args) == 2, 'You must specify the input and output filenames' input_filename, output_filename = args tmp_dir = tempfile.mkdtemp(prefix='tmp-sam_to_bam_converter-') # convert to SAM unsorted_bam_filename = os.path.join(tmp_dir, 'unsorted.bam') unsorted_stderr_filename = os.path.join(tmp_dir, 'unsorted.stderr') proc = subprocess.Popen(['samtools', 'view', '-bS', input_filename], stdout=open(unsorted_bam_filename, 'wb'), stderr=open(unsorted_stderr_filename, 'wb'), cwd=tmp_dir) return_code = proc.wait() if return_code: stderr_target = sys.stderr else: stderr_target = sys.stdout with open(unsorted_stderr_filename) as stderr: while True: chunk = stderr.read(CHUNK_SIZE) if chunk: stderr_target.write(chunk) else: break # sort sam, so indexing will not fail sorted_stderr_filename = os.path.join(tmp_dir, 'sorted.stderr') sorting_prefix = os.path.join(tmp_dir, 'sorted_bam') # samtools changed sort command arguments (starting from version 1.3) samtools_version = packaging.version.parse(_get_samtools_version()) if samtools_version < packaging.version.parse('1.0'): sort_args = ['-o', unsorted_bam_filename, sorting_prefix] else: sort_args = ['-T', sorting_prefix, unsorted_bam_filename] proc = subprocess.Popen(['samtools', 'sort'] + sort_args, stdout=open(output_filename, 'wb'), stderr=open(sorted_stderr_filename, 'wb'), cwd=tmp_dir) return_code = proc.wait() if return_code: stderr_target = sys.stderr else: stderr_target = sys.stdout with open(sorted_stderr_filename) as stderr: while True: chunk = stderr.read(CHUNK_SIZE) if chunk: stderr_target.write(chunk) else: break cleanup_before_exit(tmp_dir) if __name__ == "__main__": __main__()