Skip to content
Snippets Groups Projects
delly.py 4.56 KiB
Newer Older
Thomas Faraut's avatar
Thomas Faraut committed
#!/usr/bin/env python3

import sys
import os
Thomas Faraut's avatar
Thomas Faraut committed
import argparse
from pathlib import Path
from tempfile import mkdtemp
from shutil import rmtree, copyfile
from subprocess import run

import pysam


def eprint(*args, **kwargs):
    ''' A simple to sys.stderr printer wrapper '''
    print(*args, file=sys.stderr, **kwargs)

Thomas Faraut's avatar
Thomas Faraut committed

def existing_file_abs_path(f):
Thomas Faraut's avatar
Thomas Faraut committed
    try:
Thomas Faraut's avatar
Thomas Faraut committed
        Path(f).resolve()
Thomas Faraut's avatar
Thomas Faraut committed
    except FileNotFoundError:
        print("File %s is not an existing and valid file" % f)
Thomas Faraut's avatar
Thomas Faraut committed
        exit(1)
Thomas Faraut's avatar
Thomas Faraut committed
    else:
        my_abs_path = os.path.abspath(f)
    return my_abs_path

Thomas Faraut's avatar
Thomas Faraut committed

def file_abs_path(f):
    return os.path.abspath(f)


Thomas Faraut's avatar
Thomas Faraut committed
def get_bamfiles(bamlist):
    with open(bamlist, "r") as fin:
Thomas Faraut's avatar
Thomas Faraut committed
        bamfiles = [existing_file_abs_path(f.strip()) for f in fin]
Thomas Faraut's avatar
Thomas Faraut committed
    return bamfiles

Thomas Faraut's avatar
Thomas Faraut committed
def get_all_chromosomes(bamfile):
    with pysam.AlignmentFile(bamfile, "rb") as samfile:
        chromosomes = [contig['SN'] for contig in samfile.header['SQ']]
    return chromosomes

Thomas Faraut's avatar
Thomas Faraut committed
def get_unwanted_chroms(chroms_all, chromosome):
    if chromosome not in chroms_all:
        eprint("Selected chromosome is not a valid chromosome")
    chroms_all.remove(chromosome)
    return chroms_all

Thomas Faraut's avatar
Thomas Faraut committed
def append_chroms_to_exclude(exclusion_file, unwanted_chromosomes, odir="."):
Thomas Faraut's avatar
Thomas Faraut committed
    new_exclusion = os.path.join(odir, "excluded.tsv")
Thomas Faraut's avatar
Thomas Faraut committed
    copyfile(exclusion_file, new_exclusion)
    with open(new_exclusion,  "a") as fout:
        for chrom in unwanted_chromosomes:
            fout.write(chrom+"\n")
    return new_exclusion

Thomas Faraut's avatar
Thomas Faraut committed
def runDelly(args):
    bamlist = args.bamlist
    genome = args.genome
    chrom = args.chrom
    svtype = args.svtype
Thomas Faraut's avatar
Thomas Faraut committed
    excluded = existing_file_abs_path(args.excluded)
    output = file_abs_path(args.output)
    template = file_abs_path(args.template)
Thomas Faraut's avatar
Thomas Faraut committed

    bamfiles = get_bamfiles(bamlist)

    chromosomes_all = get_all_chromosomes(bamfiles[0])

    # removing the selected chrom from chromosomes_all
    unwanted_chromosomes = get_unwanted_chroms(chromosomes_all, chrom)

    tempdir = mkdtemp(dir=".")
    oldir = os.getcwd()
    os.chdir(tempdir)

    # add unwanted chromosomes to the excluded file
    exclusion_file = append_chroms_to_exclude(excluded, unwanted_chromosomes)

    delly_raw = "delly_raw.bcf"

Thomas Faraut's avatar
Thomas Faraut committed
    # construct delly string
Thomas Faraut's avatar
Thomas Faraut committed
    # TODO warning the genologin delly is not multiprocess
    delly_exe = "/home/faraut/save/Softwares/delly_v7.9_src/delly/src/delly"
    # delly_call_str = "delly call "
    delly_call_str = delly_exe + " call "
Thomas Faraut's avatar
Thomas Faraut committed
    delly_call_str += "-g %s " % genome
    delly_call_str += "-x %s " % exclusion_file
    delly_call_str += "-t %s " % svtype
    delly_call_str += "-o %s " % delly_raw
Thomas Faraut's avatar
Thomas Faraut committed
    delly_call_str += " ".join(bamfiles)
Thomas Faraut's avatar
Thomas Faraut committed
    completed = run(delly_call_str, shell=True)

    if completed:
        if os.path.exists(delly_raw):
            # construct delly string
            delly_filter_str = "delly filter "
            delly_filter_str += "-f germline "
            delly_filter_str += "-m 100 "
            delly_filter_str += "-t %s " % svtype
            delly_filter_str += "-o %s " % output
            delly_filter_str += "%s " % delly_raw
            completed = run(delly_filter_str, shell=True)

        else:
Thomas Faraut's avatar
Thomas Faraut committed
            command = "bcftools convert -O b -o {output}.bcf {template};\n".format(output=os.path.splitext(output)[0],
Thomas Faraut's avatar
Thomas Faraut committed
                                                                                   template=template)
            completed = run(command, shell=True)
Thomas Faraut's avatar
Thomas Faraut committed

    os.chdir(oldir)
Thomas Faraut's avatar
Thomas Faraut committed
    rmtree(tempdir)
Thomas Faraut's avatar
Thomas Faraut committed
    return completed.returncode
Thomas Faraut's avatar
Thomas Faraut committed
def parse_arguments():
    parser = argparse.ArgumentParser(
        prog="delly.py",
        description="Delly wrapper for a specific chromosome  "
Thomas Faraut's avatar
Thomas Faraut committed
                    "  ")
    parser.add_argument("-b", "--bamlist", required=True,
                        help="A file with a list of BAM files")
    parser.add_argument("-c", "--chrom", required=True,
                        help="a chromosome")
    parser.add_argument("-g", "--genome", required=True,
                        help="the genome")
    parser.add_argument("-x", "--excluded", required=True,
                        help="File describing regions to exclude")
    parser.add_argument("-t", "--svtype", required=True,
                        help="the svtype")
    parser.add_argument("-o", "--output", required=True,
                        help="outputfile")
    parser.add_argument("-e", "--template", required=True,
                        help="empty template file (used if no variant was found)")
Thomas Faraut's avatar
Thomas Faraut committed

    args = parser.parse_args()

    return args


def main():
    args = parse_arguments()
Thomas Faraut's avatar
Thomas Faraut committed


if __name__ == "__main__":
    sys.exit(main())