From 8f4d223ec6c1e1e2715708d0532399ede4ed2727 Mon Sep 17 00:00:00 2001 From: Lance Parsons Date: Wed, 22 May 2024 02:29:46 -0400 Subject: [PATCH] fix: remove NA string replacement, fixed upstream (#2940) Wrapper previously failed if the optional output `qc_metrics` was not supplied due to NA replacement code that was not in a conditional. The code is no longer required since NA strings are now output correctly in https://github.com/deeptools/deepTools/pull/1002 ### QC * [x] I confirm that: For all wrappers added by this PR, * there is a test case which covers any introduced changes, * `input:` and `output:` file paths in the resulting rule can be changed arbitrarily, * either the wrapper can only use a single core, or the example rule contains a `threads: x` statement with `x` being a reasonable default, * rule names in the test case are in [snake_case](https://en.wikipedia.org/wiki/Snake_case) and somehow tell what the rule is about or match the tools purpose or name (e.g., `map_reads` for a step that maps reads), * all `environment.yaml` specifications follow [the respective best practices](https://stackoverflow.com/a/64594513/2352071), * the `environment.yaml` pinning has been updated by running `snakedeploy pin-conda-envs environment.yaml` on a linux machine, * wherever possible, command line arguments are inferred and set automatically (e.g. based on file extensions in `input:` or `output:`), * all fields of the example rules in the `Snakefile`s and their entries are explained via comments (`input:`/`output:`/`params:` etc.), * `stderr` and/or `stdout` are logged correctly (`log:`), depending on the wrapped tool, * temporary files are either written to a unique hidden folder in the working directory, or (better) stored where the Python function `tempfile.gettempdir()` points to (see [here](https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir); this also means that using any Python `tempfile` default behavior works), * the `meta.yaml` contains a link to the documentation of the respective tool or command, * `Snakefile`s pass the linting (`snakemake --lint`), * `Snakefile`s are formatted with [snakefmt](https://github.com/snakemake/snakefmt), * Python wrapper scripts are formatted with [black](https://black.readthedocs.io). * Conda environments use a minimal amount of channels, in recommended ordering. E.g. for bioconda, use (conda-forge, bioconda, nodefaults, as conda-forge should have highest priority and defaults channels are usually not needed because most packages are in conda-forge nowadays). --------- Co-authored-by: Filipe G. Vieira <1151762+fgvieira@users.noreply.github.com> --- bio/deeptools/plotfingerprint/test/Snakefile | 11 +++++------ bio/deeptools/plotfingerprint/wrapper.py | 19 +++++-------------- bio/deeptools/plotheatmap/test/Snakefile | 2 +- bio/deeptools/plotheatmap/wrapper.py | 3 ++- bio/deeptools/plotprofile/test/Snakefile | 5 +---- bio/deeptools/plotprofile/wrapper.py | 3 ++- 6 files changed, 16 insertions(+), 27 deletions(-) diff --git a/bio/deeptools/plotfingerprint/test/Snakefile b/bio/deeptools/plotfingerprint/test/Snakefile index d3cca05ce1..888da5cec4 100644 --- a/bio/deeptools/plotfingerprint/test/Snakefile +++ b/bio/deeptools/plotfingerprint/test/Snakefile @@ -2,7 +2,7 @@ rule plot_fingerprint: input: bam_files=expand("samples/{sample}.bam", sample=["a", "b"]), bam_idx=expand("samples/{sample}.bam.bai", sample=["a", "b"]), - jsd_sample="samples/b.bam" # optional, requires qc_metrics output + jsd_sample="samples/b.bam", # optional, requires qc_metrics output output: # Please note that --plotFile and --outRawCounts are exclusively defined via output files. # Usable output variables, their extensions and which option they implicitly call are listed here: @@ -10,13 +10,12 @@ rule plot_fingerprint: fingerprint="plot_fingerprint/plot_fingerprint.png", # required # optional output counts="plot_fingerprint/raw_counts.tab", - qc_metrics="plot_fingerprint/qc_metrics.txt" + qc_metrics="plot_fingerprint/qc_metrics.txt", log: - "logs/deeptools/plot_fingerprint.log" + "logs/deeptools/plot_fingerprint.log", params: # optional parameters - "--numberOfSamples 200 " - threads: - 8 + extra="--numberOfSamples 200", + threads: 8 wrapper: "master/bio/deeptools/plotfingerprint" diff --git a/bio/deeptools/plotfingerprint/wrapper.py b/bio/deeptools/plotfingerprint/wrapper.py index b1059f5390..5cb6668699 100644 --- a/bio/deeptools/plotfingerprint/wrapper.py +++ b/bio/deeptools/plotfingerprint/wrapper.py @@ -1,12 +1,14 @@ __author__ = "Antonie Vietor" -__copyright__ = "Copyright 2020, Antonie Vietor" +__copyright__ = "Copyright 2024, Antonie Vietor, Lance Parsons" __email__ = "antonie.v@gmx.de" __license__ = "MIT" -from snakemake.shell import shell import re +from snakemake.shell import shell + log = snakemake.log_fmt_shell(stdout=True, stderr=True) +extra = snakemake.params.get("extra", "") jsd_sample = snakemake.input.get("jsd_sample") out_counts = snakemake.output.get("counts") @@ -30,16 +32,5 @@ "{optional_output} " "--numberOfProcessors {snakemake.threads} " "{jsd} " - "{snakemake.params}) {log}" + "{extra}) {log}" ) -# ToDo: remove the 'NA' string replacement when fixed in deepTools, see: -# https://github.com/deeptools/deepTools/pull/999 -regex_passes = 2 - -with open(out_metrics, "rt") as f: - metrics = f.read() - for i in range(regex_passes): - metrics = re.sub("\tNA(\t|\n)", "\tnan\\1", metrics) - -with open(out_metrics, "wt") as f: - f.write(metrics) diff --git a/bio/deeptools/plotheatmap/test/Snakefile b/bio/deeptools/plotheatmap/test/Snakefile index facc208a6d..812ef6b214 100644 --- a/bio/deeptools/plotheatmap/test/Snakefile +++ b/bio/deeptools/plotheatmap/test/Snakefile @@ -14,6 +14,6 @@ rule plot_heatmap: "logs/deeptools/heatmap.log" params: # optional parameters - "--plotType=fill " + extra="--plotType=fill " wrapper: "master/bio/deeptools/plotheatmap" diff --git a/bio/deeptools/plotheatmap/wrapper.py b/bio/deeptools/plotheatmap/wrapper.py index a963064387..eae24a605e 100644 --- a/bio/deeptools/plotheatmap/wrapper.py +++ b/bio/deeptools/plotheatmap/wrapper.py @@ -6,6 +6,7 @@ from snakemake.shell import shell log = snakemake.log_fmt_shell(stdout=True, stderr=True) +extra = snakemake.params.get("extra", "") out_region = snakemake.output.get("regions") out_matrix = snakemake.output.get("heatmap_matrix") @@ -27,5 +28,5 @@ "-m {snakemake.input[0]} " "-o {snakemake.output.heatmap_img} " "{optional_output} " - "{snakemake.params}) {log}" + "{extra}) {log}" ) diff --git a/bio/deeptools/plotprofile/test/Snakefile b/bio/deeptools/plotprofile/test/Snakefile index 8156ea47e6..b1e77bf60a 100644 --- a/bio/deeptools/plotprofile/test/Snakefile +++ b/bio/deeptools/plotprofile/test/Snakefile @@ -15,9 +15,6 @@ rule plot_profile: "logs/deeptools/plot_profile.log" params: # optional parameters - "--plotType=fill " - "--perGroup " - "--colors red yellow blue " - "--dpi 150 " + extra="--plotType=fill --perGroup --colors red yellow blue --dpi 150" wrapper: "master/bio/deeptools/plotprofile" diff --git a/bio/deeptools/plotprofile/wrapper.py b/bio/deeptools/plotprofile/wrapper.py index 9fcc8b875d..7d6c98a3dc 100644 --- a/bio/deeptools/plotprofile/wrapper.py +++ b/bio/deeptools/plotprofile/wrapper.py @@ -6,6 +6,7 @@ from snakemake.shell import shell log = snakemake.log_fmt_shell(stdout=True, stderr=True) +extra = snakemake.params.get("extra", "") out_region = snakemake.output.get("regions") out_data = snakemake.output.get("data") @@ -25,5 +26,5 @@ "-m {snakemake.input[0]} " "-o {snakemake.output.plot_img} " "{optional_output} " - "{snakemake.params}) {log}" + "{extra}) {log}" )