diff --git a/bio/cnvkit/batch/environment.linux-64.pin.txt b/bio/cnvkit/batch/environment.linux-64.pin.txt index f1f55ee51b1..b9aeca8bf48 100644 --- a/bio/cnvkit/batch/environment.linux-64.pin.txt +++ b/bio/cnvkit/batch/environment.linux-64.pin.txt @@ -138,6 +138,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py310h5eaa309_1.con https://conda.anaconda.org/conda-forge/linux-64/pango-1.54.0-h4c5309f_1.conda#7df02e445367703cd87a574046e3a6f0 https://conda.anaconda.org/conda-forge/noarch/rlpycairo-0.2.0-pyhd8ed1ab_0.conda#71d8c309e4e5c13d8f4113b5a394e633 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.14.1-py310hfcf56fc_1.conda#d9b1b75a227dbc42f3fe0e8bc852b805 +https://conda.anaconda.org/bioconda/noarch/snakemake-wrapper-utils-0.8.0-pyhdfd78af_0.conda#1650e521333852f45468d97b1b2fdcce https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.9.2-py310h68603db_2.conda#4a8c5dd75815384ddbc3aee99ccd7b50 https://conda.anaconda.org/conda-forge/linux-64/pomegranate-0.14.8-py310hc4a4660_0.tar.bz2#5318c4d1baef8fd825b2c61b88d5f117 https://conda.anaconda.org/bioconda/noarch/pyfaidx-0.8.1.3-pyhdfd78af_0.tar.bz2#b7235b21bc5dd12cd480a23201cc8886 diff --git a/bio/cnvkit/batch/environment.yaml b/bio/cnvkit/batch/environment.yaml index d69e286a550..ac814df5ffa 100644 --- a/bio/cnvkit/batch/environment.yaml +++ b/bio/cnvkit/batch/environment.yaml @@ -4,3 +4,4 @@ channels: - nodefaults dependencies: - cnvkit =0.9.12 + - snakemake-wrapper-utils =0.8.0 diff --git a/bio/cnvkit/batch/wrapper.py b/bio/cnvkit/batch/wrapper.py index 555a1427003..c8d262f8b78 100644 --- a/bio/cnvkit/batch/wrapper.py +++ b/bio/cnvkit/batch/wrapper.py @@ -3,16 +3,14 @@ __email__ = "patrik.smeds@scilifelab.uu.se" __license__ = "MIT" -import logging from os import listdir -from os.path import basename -from os.path import dirname from os.path import join from tempfile import TemporaryDirectory -import shutil from snakemake.shell import shell +from snakemake_wrapper_utils.snakemake import move_files -log = snakemake.log_fmt_shell(stdout=False, stderr=True) + +log = snakemake.log_fmt_shell(stdout=True, stderr=True, append=True) input_bam_files = f"{snakemake.input.bam}" @@ -50,9 +48,7 @@ with TemporaryDirectory() as tmpdirname: if create_reference: output = f"--output-reference {join(tmpdirname, 'reference.cnn')}" - output_list = [snakemake.output.reference] else: - output_list = [value for key, value in snakemake.output.items()] output = f"-d {tmpdirname} " shell( "(cnvkit.py batch {input_bam_files} " @@ -65,15 +61,35 @@ "{extra}) {log}" ) - for output_file in output_list: - filename = basename(output_file) - parent = dirname(output_file) - - try: - shutil.copy2(join(tmpdirname, filename), output_file) - except FileNotFoundError as e: - temp_files = listdir(tmpdirname) - logging.error( - f"Couldn't locate file {basename} possible files are {[basename(f) for f in temp_files]}" - ) - raise e + # actual generated files + temp_files = listdir(tmpdirname) + + # mapping of file suffixes to snakemake.output attributes + file_map = { + "antitargetcoverage.cnn": "antitarget_coverage", + "bintest.cns": "bins", + ".cnr": "regions", + "call.cns": "segments_called", + "targetcoverage.cnn": "target_coverage", + ".cns": "segments", + "reference.cnn": "reference", + } + + mapping = {} + + # find matches btw generated files and snakemake output + for suffix, attr in file_map.items(): + if not snakemake.output.get(attr): + continue + for file in temp_files: + if file.endswith(suffix): + # Skip ambiguous matches + if attr == "segments" and any( + x in file for x in ["call.cns", "bintest.cns"] + ): + continue + mapping[attr] = join(tmpdirname, file) + break # stop after first match + + for file in move_files(snakemake, mapping): + shell("{file} {log}")