From 10ec9ae72acc4792caa49035dc28cc4c15a83233 Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 13 Jan 2020 10:17:43 +0000 Subject: [PATCH 01/22] Edits to citation and help --- README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c838ee6..a666a15 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Detect somatic copy number variants (CNV) in tumour-normal samples using the * [Command options](#command-options) * [Filtering output for relevant CNVs](#filtering-output-for-relevant-cnvs) * [Time and memory footprint](#time-and-memory-footprint) -* [Citation](#citation) +* [Citation & Getting help](#citation--getting-help) @@ -326,8 +326,8 @@ quality requires: * 1 hour and ~15 GB of memory for the actual detection of CNVs starting from the pileup. Time and memory is mostly driven by the number of SNPs -Citation -======== +Citation & Getting help +======================= If using *cnv_facets* please cite @@ -337,3 +337,14 @@ If using *cnv_facets* please cite number and clonal heterogeneity analysis tool for high-throughput DNA sequencing, *Nucleic Acids Res*, 2016](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5027494/) + +Any and all comment and questions can be sent to one or more of the following +recipients: + +* Open an issue at [github.com/dariober/cnv_facets)](https://github.com/dariober/cnv_facets/issues) + +* For questions specific to the FACETS package and CNV calling open an issue at + [https://github.com/ddmskcc/facets](https://github.com/mskcc/facets/issues) + +* Post a question at https://www.biostars.org/ (you may want to notify me by + sending an email to `dario beraldi gmail com`) From 8a3169229bbb47fa1f2abd9f3f7002b94956ad4c Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 13 Jan 2020 10:26:37 +0000 Subject: [PATCH 02/22] Note about conda envs --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f691ce..8c57ab3 100644 --- a/README.md +++ b/README.md @@ -82,9 +82,13 @@ Install via bioconda (recommended) Installation via the [conda](https://conda.io/docs/) package manager is the recommended route. Options `-c bioconda -c conda-forge` can be omitted if -bioconda and conda-forge are already registered channels (see below): +bioconda and conda-forge are already registered channels (see below). +It is generally not recommended to install packages in the conda base environment. Better to +install in a dedicated envirnment. E.g.: ``` +conda create -n my_project +conda activate my_project conda install -c bioconda -c conda-forge cnv_facets ``` From f71153f8f1de26cd10a5e67067c1dadc0ce2e57f Mon Sep 17 00:00:00 2001 From: Dario Beraldi Date: Wed, 15 Jan 2020 14:10:30 +0000 Subject: [PATCH 03/22] Add link to clarification re CF_EM --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c57ab3..6a30ca7 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ CNLR_MEDIAN_CLUST | Float | Median log-ratio (logR) of the segment cluster. logR MAF_R | Float | Log-odds-ratio (logOR) summary for the segment. logOR is defined by the log-odds ratio of the variant allele count in the tumor versus in the normal MAF_R_CLUST | Float | Log-odds-ratio (logOR) summary for the segment cluster. logOR is defined by the log-odds ratio of the variant allele count in the tumor versus that in the normal SEGCLUST | Integer | Segment cluster to which the segment belongs -CF_EM | Float | Cellular fraction, fraction of DNA associated with the aberrant genotype. Set to 1 for normal diploid +CF_EM | Float | Cellular fraction, fraction of DNA associated with the aberrant genotype. Set to 1 for normal diploid. See also issue #17 TCN_EM | Integer | Total copy number. 2 for normal diploid LCN_EM | Integer | Lesser (minor) copy number. 1 for normal diploid CNV_ANN | String | Annotation features assigned to this CNV From b4a6f096357911ebaadf619aee1315c27f0fd758 Mon Sep 17 00:00:00 2001 From: Dario Beraldi Date: Wed, 15 Jan 2020 14:12:02 +0000 Subject: [PATCH 04/22] Link fixed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a30ca7..0dbd1c4 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ CNLR_MEDIAN_CLUST | Float | Median log-ratio (logR) of the segment cluster. logR MAF_R | Float | Log-odds-ratio (logOR) summary for the segment. logOR is defined by the log-odds ratio of the variant allele count in the tumor versus in the normal MAF_R_CLUST | Float | Log-odds-ratio (logOR) summary for the segment cluster. logOR is defined by the log-odds ratio of the variant allele count in the tumor versus that in the normal SEGCLUST | Integer | Segment cluster to which the segment belongs -CF_EM | Float | Cellular fraction, fraction of DNA associated with the aberrant genotype. Set to 1 for normal diploid. See also issue #17 +CF_EM | Float | Cellular fraction, fraction of DNA associated with the aberrant genotype. Set to 1 for normal diploid. See also issue [#17](https://github.com/dariober/cnv_facets/issues/17) TCN_EM | Integer | Total copy number. 2 for normal diploid LCN_EM | Integer | Lesser (minor) copy number. 1 for normal diploid CNV_ANN | String | Annotation features assigned to this CNV From 44fdd18a4beb4f57c6e6e746d31a6399efdbc85b Mon Sep 17 00:00:00 2001 From: dariober Date: Sun, 15 Mar 2020 12:27:15 +0000 Subject: [PATCH 05/22] Add option to skip coverage plots (issue #19) --- bin/cnv_facets.R | 20 +++++++++++++------- test/test_cnv_facets.py | 9 +++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/bin/cnv_facets.R b/bin/cnv_facets.R index 69c3bfe..c4141a0 100755 --- a/bin/cnv_facets.R +++ b/bin/cnv_facets.R @@ -31,7 +31,7 @@ suppressMessages(library(gridExtra)) # ----------------------------------------------------------------------------- -VERSION= sprintf('0.15.0; facets=%s', packageVersion('facets')) +VERSION= sprintf('0.16.0; facets=%s', packageVersion('facets')) docstring<- sprintf('DESCRIPTION \\n\\ Detect somatic copy number variants (CNVs) and estimate purity and ploidy in a\\n\\ @@ -131,6 +131,10 @@ parser$add_argument('--unmatched', '-u', help= 'Normal sample is unmatched. If set, heterozygote SNPs are\\n\\ called using tumor reads only and logOR calculations are different', action= 'store_true') +parser$add_argument('--no-cov-plot', '-np', help= +'Do not produce coverage plots (they can be memory intensive).\\n\\ +Other plots remain unaffected', action= 'store_true') + def_rnd<- 'The name of the input file' parser$add_argument('--rnd-seed', '-s', help= sprintf( 'Seed for random number generator. Default: %s', def_rnd), type= 'character', default= def_rnd) @@ -812,11 +816,13 @@ if(sys.nframe() == 0){ } rcmat_flt<- filter_rcmat(rcmat= rcmat[['pileup']], min_ndepth= xargs$depth[1], max_ndepth= xargs$depth[2], target_bed= targets) - - write(sprintf('[%s] Plotting histogram of coverage...', Sys.time()), stderr()) - plot_coverage(rcmat= rcmat[['pileup']], rcmat_flt= rcmat_flt, - fname= paste0(xargs$out, '.cov.pdf'), title= paste0('Depth of coverage\n', xargs$out)) - + + if(xargs$no_cov_plot == FALSE){ + write(sprintf('[%s] Plotting histogram of coverage...', Sys.time()), stderr()) + plot_coverage(rcmat= rcmat[['pileup']], rcmat_flt= rcmat_flt, + fname= paste0(xargs$out, '.cov.pdf'), title= paste0('Depth of coverage\n', xargs$out)) + } + rcmat[['pileup']]<- NULL x_ <- gc(verbose= FALSE) @@ -887,7 +893,7 @@ if(sys.nframe() == 0){ par(las= 1, mar= c(3, 3, 1, 1), mgp= c(1.5, 0.5, 0), tcl= -0.3) logRlogORspider(facets$proc_out$out, facets$proc_out$dipLogR) x_ <- dev.off() - + si<- capture.output(sessionInfo()) write(si, stderr()) } diff --git a/test/test_cnv_facets.py b/test/test_cnv_facets.py index d58e6d0..3172925 100755 --- a/test/test_cnv_facets.py +++ b/test/test_cnv_facets.py @@ -84,6 +84,15 @@ def testBamInput(self): self.assertTrue(os.path.exists('test_out/out.csv.gz')) self.assertEqual('', vcf_validator('test_out/out.vcf.gz')) + def testDoNotPlot(self): + p = sp.Popen("""../bin/cnv_facets.R --no-cov-plot -t data/TCRBOA6-T-WEX.sample.bam -n data/TCRBOA6-N-WEX.sample.bam -vcf data/common.sample.vcf.gz -o test_out/out""", shell=True, stdout= sp.PIPE, stderr= sp.PIPE) + stdout, stderr = p.communicate() + self.assertEqual(0, p.returncode) + self.assertTrue(os.path.exists('test_out/out.vcf.gz')) + self.assertTrue(os.path.exists('test_out/out.cnv.png')) + self.assertTrue(os.path.exists('test_out/out.spider.pdf')) + self.assertTrue(not os.path.exists('test_out/out.cov.pdf')) + def testBamInputNotProperlyPaired(self): # Prepare a bam files with 'properly paired' flag removed p = sp.Popen(r""" From 33bdbbff22b00b3e32ccaba6649963af07697d96 Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:16:35 +0100 Subject: [PATCH 06/22] First pass at github workflow --- .github/workflows/main.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..503ba96 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,15 @@ +name: CI +on: [push] +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Conda env setup + run: | + curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" + bash Miniforge3-$(uname)-$(uname -m).sh + + conda create -n cnv_facets + conda activate cnv_facets + conda install -c bioconda -c conda-forge cnv_facets From 0837585bd77e38e93151e09dffe3a6f816d03a2c Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:20:29 +0100 Subject: [PATCH 07/22] Run in batch mode --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 503ba96..2fa4148 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: - name: Conda env setup run: | curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" - bash Miniforge3-$(uname)-$(uname -m).sh + bash -b Miniforge3-$(uname)-$(uname -m).sh conda create -n cnv_facets conda activate cnv_facets From ecaf0eb4e4ccdd2cf767a9f93398e32addb295ff Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:23:47 +0100 Subject: [PATCH 08/22] Fix commands --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2fa4148..65ca7bc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,8 +8,8 @@ jobs: - name: Conda env setup run: | curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" - bash -b Miniforge3-$(uname)-$(uname -m).sh + bash Miniforge3-$(uname)-$(uname -m).sh -b - conda create -n cnv_facets + conda create --yes -n cnv_facets conda activate cnv_facets - conda install -c bioconda -c conda-forge cnv_facets + conda install --yes -c bioconda -c conda-forge cnv_facets From c0cb87fe04c96a407e2b66561841c26202868630 Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:35:54 +0100 Subject: [PATCH 09/22] More fixes --- .github/workflows/main.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 65ca7bc..1f0dfbd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,7 +9,9 @@ jobs: run: | curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" bash Miniforge3-$(uname)-$(uname -m).sh -b - - conda create --yes -n cnv_facets - conda activate cnv_facets - conda install --yes -c bioconda -c conda-forge cnv_facets + source ~/.bashrc + - name: Install cnv_facets + run: | + mamba create --yes -n cnv_facets + mamba activate cnv_facets + mamba install --yes -c bioconda -c conda-forge cnv_facets From 3a4a6f7f99e36ba0cd59576bc05155f7a0d5d94c Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:38:47 +0100 Subject: [PATCH 10/22] More fixes --- .github/workflows/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1f0dfbd..2c98f98 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,6 +9,9 @@ jobs: run: | curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" bash Miniforge3-$(uname)-$(uname -m).sh -b + + cat ~/.bashrc + source ~/.bashrc - name: Install cnv_facets run: | From 3520197da84286c3321314e8d72c051602a1f849 Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:48:28 +0100 Subject: [PATCH 11/22] Use option --- .github/workflows/main.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2c98f98..9297289 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,14 +5,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Conda env setup - run: | - curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" - bash Miniforge3-$(uname)-$(uname -m).sh -b - - cat ~/.bashrc - - source ~/.bashrc + - uses: conda-incubator/setup-miniconda@v2 + with: + auto-update-conda: false + use-only-tar-bz2: true + miniforge-version: latest - name: Install cnv_facets run: | mamba create --yes -n cnv_facets From b6edd9dc63287f2d485e54f5c0bb67a4288b79dd Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:50:36 +0100 Subject: [PATCH 12/22] Use option --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9297289..12edcb7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,6 +12,8 @@ jobs: miniforge-version: latest - name: Install cnv_facets run: | + mamba init + source ~/.bashrc mamba create --yes -n cnv_facets mamba activate cnv_facets mamba install --yes -c bioconda -c conda-forge cnv_facets From 3f1d24a11c07a184752c83af7170b900f0280a1b Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:54:50 +0100 Subject: [PATCH 13/22] Attempt tp remove source --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 12edcb7..d5d00c2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,6 @@ jobs: - name: Install cnv_facets run: | mamba init - source ~/.bashrc mamba create --yes -n cnv_facets mamba activate cnv_facets mamba install --yes -c bioconda -c conda-forge cnv_facets From ad95feb8de770637a640bfe6ac62955e1657cc6b Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 15:58:54 +0100 Subject: [PATCH 14/22] Add tests --- .github/workflows/main.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d5d00c2..7aba8ac 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,6 +13,17 @@ jobs: - name: Install cnv_facets run: | mamba init + source ~/.bashrc mamba create --yes -n cnv_facets mamba activate cnv_facets mamba install --yes -c bioconda -c conda-forge cnv_facets + - name: Install vcf_validator + run: | + curl -L -o test/vcf_validator -s https://github.com/EBIvariation/vcf-validator/releases/download/v0.9.1/vcf_validator_linux + chmod a+x test/vcf_validator + ./test/vcf_validator --help + - name: Run tests + run: | + cd test + Rscript testthat.R + python3 test_cnv_facets.py From 1215a2615b2d01eeafe459cdd1d89914e840bbdc Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 16:03:35 +0100 Subject: [PATCH 15/22] Add tests --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7aba8ac..4260485 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,6 +17,7 @@ jobs: mamba create --yes -n cnv_facets mamba activate cnv_facets mamba install --yes -c bioconda -c conda-forge cnv_facets + mamba install --yes --freeze-installed r-testthat - name: Install vcf_validator run: | curl -L -o test/vcf_validator -s https://github.com/EBIvariation/vcf-validator/releases/download/v0.9.1/vcf_validator_linux From 9fd1413b3b3a54a134996b157baf6ef0e6f792a4 Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 16:06:27 +0100 Subject: [PATCH 16/22] Add tests --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4260485..ad4e0f8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,6 @@ jobs: mamba create --yes -n cnv_facets mamba activate cnv_facets mamba install --yes -c bioconda -c conda-forge cnv_facets - mamba install --yes --freeze-installed r-testthat - name: Install vcf_validator run: | curl -L -o test/vcf_validator -s https://github.com/EBIvariation/vcf-validator/releases/download/v0.9.1/vcf_validator_linux @@ -25,6 +24,7 @@ jobs: ./test/vcf_validator --help - name: Run tests run: | + mamba activate cnv_facets cd test Rscript testthat.R python3 test_cnv_facets.py From 7218d2926264eefbf259048dd3763d9e5b256cf7 Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 16:09:23 +0100 Subject: [PATCH 17/22] Add tests --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ad4e0f8..4c20948 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,6 +24,7 @@ jobs: ./test/vcf_validator --help - name: Run tests run: | + source ~/.bashrc mamba activate cnv_facets cd test Rscript testthat.R From 53b4550494e0e52b685b01e6c170c734d28cc91d Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 16:28:45 +0100 Subject: [PATCH 18/22] Re-handle tests --- .github/workflows/main.yml | 2 +- test/test.py | 262 +++++++++++++++++++++++++++++++++++++ test/test_cnv_facets.py | 224 ------------------------------- 3 files changed, 263 insertions(+), 225 deletions(-) create mode 100755 test/test.py delete mode 100755 test/test_cnv_facets.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4c20948..b70aef7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: CI on: [push] jobs: build-and-test: - runs-on: ubuntu-latest + runs-on: [ubuntu-latest, ubuntu-20.04] steps: - uses: actions/checkout@v3 - uses: conda-incubator/setup-miniconda@v2 diff --git a/test/test.py b/test/test.py new file mode 100755 index 0000000..2fa4c28 --- /dev/null +++ b/test/test.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018-2019 University of Glasgow +# +# Author: Dario Beraldi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +import unittest +import shutil +import os +import subprocess +import sys +import gzip +import re +import filecmp +from collections import OrderedDict + + +class shell: + def __init__(self, cmd, strict=True, timeout=None): + print(cmd) + cmd = f"set -e; set -u; set -o pipefail\n{cmd}" + p = subprocess.Popen( + cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + executable="/bin/bash", + ) + try: + stdout, stderr = p.communicate(timeout=timeout) + except subprocess.TimeoutExpired: + p.kill() + sys.stderr.write(f"Error: Timeout after {timeout} seconds\n") + stdout, stderr = p.communicate() + self.returncode = p.returncode + self.stdout = stdout.decode() + self.stderr = stderr.decode() + self.cmd = cmd + if strict and self.returncode != 0: + raise subprocess.SubprocessError( + f"\nSTDOUT:\n{self.stdout}\nSTDERR:\n{self.stderr}\nEXIT CODE: {self.returncode}" + ) + + +def vcf_to_list(vcf_file): + vcf = [] + with gzip.open(vcf_file) as gz: + for line in gz: + vcf.append(line.decode().strip().split("\t")) + return vcf + + +def vcf_validator(vcf_file): + """Run vcf_validator and scan the report file. Return empty string if vcf + file is valid otherwise print the content of the report + """ + p = subprocess.Popen( + "export LC_ALL=C; gzip -c -d %s | ./vcf_validator --report text" % vcf_file, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + stdout, stderr = p.communicate() + log = stderr.decode().split("\n") + rfile = [x for x in log if x.startswith("[info] Text report written to : ")] + assert len(rfile) == 1 + rfile = rfile[0].replace("[info] Text report written to : ", "") + with open(rfile) as f: + report = f.readlines() + os.remove(rfile) + if len(report) == 1 and "the input file is valid" in report[0]: + return "" + return "".join("".join(report)) + + +class cnv_facets(unittest.TestCase): + def setUp(self): + sys.stderr.write("\n" + self.id().split(".")[-1] + "\n") # Print test name + if os.path.exists("test_out"): + shutil.rmtree("test_out") + + def tearDown(self): + if os.path.exists("test_out"): + shutil.rmtree("test_out") + + def testShowHelp(self): + p = shell("../bin/cnv_facets.R --help") + self.assertTrue("--tumour", p.stderr) + + def testBamInput(self): + shell( + "../bin/cnv_facets.R -d 1 8000 -t data/TCRBOA6-T-WEX.sample.bam -n data/TCRBOA6-N-WEX.sample.bam -vcf data/common.sample.vcf.gz -o test_out/out" + ) + self.assertTrue(os.path.exists("test_out/out.vcf.gz")) + self.assertTrue(os.path.exists("test_out/out.cnv.png")) + self.assertTrue(os.path.exists("test_out/out.cov.pdf")) + self.assertTrue(os.path.exists("test_out/out.spider.pdf")) + self.assertTrue(os.path.exists("test_out/out.csv.gz")) + self.assertEqual("", vcf_validator("test_out/out.vcf.gz")) + + def testDoNotPlot(self): + shell( + """../bin/cnv_facets.R --no-cov-plot -t data/TCRBOA6-T-WEX.sample.bam -n data/TCRBOA6-N-WEX.sample.bam -vcf data/common.sample.vcf.gz -o test_out/out""" + ) + self.assertTrue(os.path.exists("test_out/out.vcf.gz")) + self.assertTrue(os.path.exists("test_out/out.cnv.png")) + self.assertTrue(os.path.exists("test_out/out.spider.pdf")) + self.assertTrue(not os.path.exists("test_out/out.cov.pdf")) + + def testBamInputNotProperlyPaired(self): + # Prepare a bam files with 'properly paired' flag removed + shell( + r""" +samtools view -h data/TCRBOA6-N-WEX.sample.bam \ +| awk -v FS='\t' -v OFS='\t' '$1 ~ "^@" || $2 ~ "99|83|163|147" {if($1 ~ "^@"){print $0} else {$2=$2-2; print $0}}' \ +| samtools view -b - > tmp.n.bam && +samtools index tmp.n.bam && + +samtools view -h data/TCRBOA6-T-WEX.sample.bam \ +| awk -v FS='\t' -v OFS='\t' '$1 ~ "^@" || $2 ~ "99|83|163|147" {if($1 ~ "^@"){print $0} else {$2=$2-2; print $0}}' \ +| samtools view -b - > tmp.t.bam && +samtools index tmp.t.bam + """ + ) + + p = shell( + r""" +../bin/cnv_facets.R -d 1 8000 -t tmp.t.bam -n tmp.n.bam -vcf data/common.sample.vcf.gz -o test_out/out + """, + strict=False, + ) + self.assertEqual(1, p.returncode) + self.assertTrue(os.path.exists("test_out/out.csv.gz")) + os.remove("test_out/out.csv.gz") + + shell( + r""" +../bin/cnv_facets.R --snp-count-orphans -d 1 8000 -t tmp.t.bam -n tmp.n.bam -vcf data/common.sample.vcf.gz -o test_out/out + """ + ) + self.assertTrue(os.path.exists("test_out/out.csv.gz")) + self.assertTrue(os.path.getsize("test_out/out.csv.gz") > 60000) + self.assertTrue(os.path.getsize("test_out/out.vcf.gz") > 1000) + + for x in ["tmp.n.bam", "tmp.n.bam.bai", "tmp.t.bam", "tmp.t.bam.bai"]: + os.remove(x) + + def testPileupInput(self): + shell("../bin/cnv_facets.R --pileup data/stomach.csv.gz -o test_out/out") + self.assertTrue(os.path.exists("test_out/out.vcf.gz")) + self.assertTrue(os.path.exists("test_out/out.cnv.png")) + self.assertTrue(os.path.exists("test_out/out.cov.pdf")) + self.assertTrue(os.path.exists("test_out/out.spider.pdf")) + self.assertEqual("", vcf_validator("test_out/out.vcf.gz")) + + def testFailOnSnpPileup(self): + p = shell( + "../bin/cnv_facets.R -t data/INVALID.bam -n data/TCRBOA6-N-WEX.sample.bam -vcf data/common.sample.vcf.gz -o test_out/out", + strict=False, + ) + self.assertTrue(p.returncode != 0) + # Check we exited immediatly after failing the first snp-pileup + self.assertEqual(1, p.stderr.count("samtools view: failed to open")) + + def testTargetPanel(self): + shell( + "../bin/cnv_facets.R -T data/stomach_targets_chr.bed -p data/stomach_chr.csv.gz -o test_out/out" + ) + self.assertEqual("", vcf_validator("test_out/out.vcf.gz")) + vcf = vcf_to_list("test_out/out.vcf.gz") + vcf = [line for line in vcf if not line[0].startswith("#")] + chroms = set([line[0] for line in vcf]) + self.assertTrue("chr1" in chroms) + self.assertTrue("chr2" in chroms) + self.assertTrue("chr3" in chroms) + self.assertTrue("chr4" in chroms) + self.assertTrue("chrX" in chroms) + self.assertTrue("chr11" not in chroms) + self.assertTrue("chr12" not in chroms) + self.assertTrue("chr13" not in chroms) + + chr1 = [line for line in vcf if line[0] == "chr1"] + self.assertTrue(int(chr1[0][1]) > 1000000) + self.assertTrue(int(chr1[len(chr1) - 1][1]) < 100000000) + + # Without chr prefix + shell( + "../bin/cnv_facets.R -T data/stomach_targets.bed -p data/stomach.csv.gz -o test_out/out" + ) + self.assertEqual("", vcf_validator("test_out/out.vcf.gz")) + + vcf = vcf_to_list("test_out/out.vcf.gz") + vcf = [line for line in vcf if not line[0].startswith("#")] + chroms = set([line[0] for line in vcf]) + self.assertTrue("1" in chroms) + self.assertTrue("13" not in chroms) + + chr1 = [line for line in vcf if line[0] == "1"] + self.assertTrue(int(chr1[0][1]) > 1000000) + self.assertTrue(int(chr1[len(chr1) - 1][1]) < 100000000) + + def testSingleEndBam(self): + # Prepare single-end files + shell( + r""" + mkdir test_out + for sample in TCRBOA6-N TCRBOA6-T + do + samtools view -h data/${sample}-WEX.sample.bam \ + | awk -v OFS='\t' -v FS='\t' '{if($1 ~ "^@"){print $0} + if($2 == 99) { + $2 = 0; print $0 + } else if($2 == 163) { + $2 = 16; print $0} + }' \ + | samtools view -b - > test_out/${sample}-WEX.se.bam + samtools index test_out/${sample}-WEX.se.bam + done + """ + ) + + shell( + "../bin/cnv_facets.R -t test_out/TCRBOA6-T-WEX.se.bam -n test_out/TCRBOA6-N-WEX.se.bam -vcf data/common.sample.vcf.gz -o test_out/out" + ) + self.assertTrue(os.path.exists("test_out/out.csv.gz")) + self.assertEqual("", vcf_validator("test_out/out.vcf.gz")) + self.assertTrue( + os.path.getsize("test_out/out.csv.gz") > 60000 + and os.path.getsize("test_out/out.csv.gz") < 70000 + ) + + shell( + "../bin/cnv_facets.R -t test_out/TCRBOA6-T-WEX.se.bam --nbhd-snp 10 -n test_out/TCRBOA6-N-WEX.se.bam -vcf data/common.sample.vcf.gz -o test_out/out" + ) + self.assertTrue(os.path.exists("test_out/out.csv.gz")) + self.assertEqual("", vcf_validator("test_out/out.vcf.gz")) + self.assertTrue( + os.path.getsize("test_out/out.csv.gz") > 300000 + and os.path.getsize("test_out/out.csv.gz") < 400000 + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_cnv_facets.py b/test/test_cnv_facets.py deleted file mode 100755 index 3172925..0000000 --- a/test/test_cnv_facets.py +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2018-2019 University of Glasgow -# -# Author: Dario Beraldi -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import unittest -import shutil -import os -import subprocess as sp -import sys -import gzip -import re -import filecmp -from collections import OrderedDict - -def vcf_to_list(vcf_file): - vcf= [] - with gzip.open(vcf_file) as gz: - for line in gz: - vcf.append(line.decode().strip().split('\t')) - return vcf - -def vcf_validator(vcf_file): - """Run vcf_validator and scan the report file. Return empty string if vcf - file is valid otherwise print the content of the report - """ - p = sp.Popen("export LC_ALL=C; gzip -c -d %s | ./vcf_validator --report text" % vcf_file, shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - log= stderr.decode().split('\n') - rfile= [x for x in log if x.startswith('[info] Text report written to : ')] - assert len(rfile) == 1 - rfile= rfile[0].replace('[info] Text report written to : ', '') - with open(rfile) as f: - report= f.readlines() - os.remove(rfile) - if len(report) == 1 and 'the input file is valid' in report[0]: - return '' - return ''.join(''.join(report)) - -class cnv_facets(unittest.TestCase): - - def setUp(self): - sys.stderr.write('\n' + self.id().split('.')[-1] + ' ') # Print test name - if os.path.exists('test_out'): - shutil.rmtree('test_out') - - def tearDown(self): - if os.path.exists('test_out'): - shutil.rmtree('test_out') - - def testShowHelp(self): - p = sp.Popen("../bin/cnv_facets.R --help", shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertTrue('--tumour', stderr.decode()) - - def testBamInput(self): - p = sp.Popen("../bin/cnv_facets.R -d 1 8000 -t data/TCRBOA6-T-WEX.sample.bam -n data/TCRBOA6-N-WEX.sample.bam -vcf data/common.sample.vcf.gz -o test_out/out", shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertTrue(os.path.exists('test_out/out.vcf.gz')) - self.assertTrue(os.path.exists('test_out/out.cnv.png')) - self.assertTrue(os.path.exists('test_out/out.cov.pdf')) - self.assertTrue(os.path.exists('test_out/out.spider.pdf')) - self.assertTrue(os.path.exists('test_out/out.csv.gz')) - self.assertEqual('', vcf_validator('test_out/out.vcf.gz')) - - def testDoNotPlot(self): - p = sp.Popen("""../bin/cnv_facets.R --no-cov-plot -t data/TCRBOA6-T-WEX.sample.bam -n data/TCRBOA6-N-WEX.sample.bam -vcf data/common.sample.vcf.gz -o test_out/out""", shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertTrue(os.path.exists('test_out/out.vcf.gz')) - self.assertTrue(os.path.exists('test_out/out.cnv.png')) - self.assertTrue(os.path.exists('test_out/out.spider.pdf')) - self.assertTrue(not os.path.exists('test_out/out.cov.pdf')) - - def testBamInputNotProperlyPaired(self): - # Prepare a bam files with 'properly paired' flag removed - p = sp.Popen(r""" -samtools view -h data/TCRBOA6-N-WEX.sample.bam \ -| awk -v FS='\t' -v OFS='\t' '$1 ~ "^@" || $2 ~ "99|83|163|147" {if($1 ~ "^@"){print $0} else {$2=$2-2; print $0}}' \ -| samtools view -b - > tmp.n.bam && -samtools index tmp.n.bam && - -samtools view -h data/TCRBOA6-T-WEX.sample.bam \ -| awk -v FS='\t' -v OFS='\t' '$1 ~ "^@" || $2 ~ "99|83|163|147" {if($1 ~ "^@"){print $0} else {$2=$2-2; print $0}}' \ -| samtools view -b - > tmp.t.bam && -samtools index tmp.t.bam - """, shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - assert 0 == p.returncode - - p = sp.Popen(r""" -../bin/cnv_facets.R -d 1 8000 -t tmp.t.bam -n tmp.n.bam -vcf data/common.sample.vcf.gz -o test_out/out - """, shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(1, p.returncode) - self.assertTrue(os.path.exists('test_out/out.csv.gz')) - os.remove('test_out/out.csv.gz') - - p = sp.Popen(r""" -../bin/cnv_facets.R --snp-count-orphans -d 1 8000 -t tmp.t.bam -n tmp.n.bam -vcf data/common.sample.vcf.gz -o test_out/out - """, shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertTrue(os.path.exists('test_out/out.csv.gz')) - self.assertTrue(os.path.getsize("test_out/out.csv.gz") > 60000) - self.assertTrue(os.path.getsize("test_out/out.vcf.gz") > 1000) - - for x in ['tmp.n.bam', 'tmp.n.bam.bai', 'tmp.t.bam', 'tmp.t.bam.bai']: - os.remove(x) - - def testPileupInput(self): - p = sp.Popen("../bin/cnv_facets.R --pileup data/stomach.csv.gz -o test_out/out", shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertTrue(os.path.exists('test_out/out.vcf.gz')) - self.assertTrue(os.path.exists('test_out/out.cnv.png')) - self.assertTrue(os.path.exists('test_out/out.cov.pdf')) - self.assertTrue(os.path.exists('test_out/out.spider.pdf')) - self.assertEqual('', vcf_validator('test_out/out.vcf.gz')) - - def testFailOnSnpPileup(self): - p = sp.Popen("../bin/cnv_facets.R -t data/INVALID.bam -n data/TCRBOA6-N-WEX.sample.bam -vcf data/common.sample.vcf.gz -o test_out/out", - shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertTrue(p.returncode != 0) - # Check we exited immediatly after failing the first snp-pileup - self.assertEqual(1, stderr.count(b'samtools view: failed to open')) - - def testTargetPanel(self): - p = sp.Popen("../bin/cnv_facets.R -T data/stomach_targets_chr.bed -p data/stomach_chr.csv.gz -o test_out/out", - shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertEqual('', vcf_validator('test_out/out.vcf.gz')) - vcf= vcf_to_list('test_out/out.vcf.gz') - vcf= [line for line in vcf if not line[0].startswith('#')] - chroms= set([line[0] for line in vcf]) - self.assertTrue('chr1' in chroms) - self.assertTrue('chr2' in chroms) - self.assertTrue('chr3' in chroms) - self.assertTrue('chr4' in chroms) - self.assertTrue('chrX' in chroms) - self.assertTrue('chr11' not in chroms) - self.assertTrue('chr12' not in chroms) - self.assertTrue('chr13' not in chroms) - - chr1= [line for line in vcf if line[0] == 'chr1'] - self.assertTrue(int(chr1[0][1]) > 1000000) - self.assertTrue(int(chr1[len(chr1)-1][1]) < 100000000) - - # Without chr prefix - p = sp.Popen("../bin/cnv_facets.R -T data/stomach_targets.bed -p data/stomach.csv.gz -o test_out/out", - shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertEqual('', vcf_validator('test_out/out.vcf.gz')) - - vcf= vcf_to_list('test_out/out.vcf.gz') - vcf= [line for line in vcf if not line[0].startswith('#')] - chroms= set([line[0] for line in vcf]) - self.assertTrue('1' in chroms) - self.assertTrue('13' not in chroms) - - chr1= [line for line in vcf if line[0] == '1'] - self.assertTrue(int(chr1[0][1]) > 1000000) - self.assertTrue(int(chr1[len(chr1)-1][1]) < 100000000) - - def testSingleEndBam(self): - # Prepare single-end files - p= sp.check_call(r""" - mkdir test_out - for sample in TCRBOA6-N TCRBOA6-T - do - samtools view -h data/${sample}-WEX.sample.bam \ - | awk -v OFS='\t' -v FS='\t' '{if($1 ~ "^@"){print $0} - if($2 == 99) { - $2 = 0; print $0 - } else if($2 == 163) { - $2 = 16; print $0} - }' \ - | samtools view -b - > test_out/${sample}-WEX.se.bam - samtools index test_out/${sample}-WEX.se.bam - done - """, shell= True) - - p = sp.Popen("../bin/cnv_facets.R -t test_out/TCRBOA6-T-WEX.se.bam -n test_out/TCRBOA6-N-WEX.se.bam -vcf data/common.sample.vcf.gz -o test_out/out", shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertTrue(os.path.exists('test_out/out.csv.gz')) - self.assertEqual('', vcf_validator('test_out/out.vcf.gz')) - self.assertTrue(os.path.getsize("test_out/out.csv.gz") > 60000 and - os.path.getsize("test_out/out.csv.gz") < 70000) - - p = sp.Popen("../bin/cnv_facets.R -t test_out/TCRBOA6-T-WEX.se.bam --nbhd-snp 10 -n test_out/TCRBOA6-N-WEX.se.bam -vcf data/common.sample.vcf.gz -o test_out/out", shell=True, stdout= sp.PIPE, stderr= sp.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode) - self.assertTrue(os.path.exists('test_out/out.csv.gz')) - self.assertEqual('', vcf_validator('test_out/out.vcf.gz')) - self.assertTrue(os.path.getsize("test_out/out.csv.gz") > 300000 and - os.path.getsize("test_out/out.csv.gz") < 400000) - -if __name__ == '__main__': - unittest.main() From b0c90fcc8d0716f6f077a74b388366e4cd257ca4 Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 16:34:51 +0100 Subject: [PATCH 19/22] os matrix --- .github/workflows/main.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b70aef7..7daf6b0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,11 @@ name: CI on: [push] jobs: build-and-test: - runs-on: [ubuntu-latest, ubuntu-20.04] + name: Build & test on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, ubuntu-20.04] steps: - uses: actions/checkout@v3 - uses: conda-incubator/setup-miniconda@v2 From 1b58604da74b9c6d434597389dca0752f4f1013b Mon Sep 17 00:00:00 2001 From: dariober Date: Mon, 12 Aug 2024 16:39:04 +0100 Subject: [PATCH 20/22] Reset to older name --- test/{test.py => test_cnv_facets.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{test.py => test_cnv_facets.py} (100%) diff --git a/test/test.py b/test/test_cnv_facets.py similarity index 100% rename from test/test.py rename to test/test_cnv_facets.py From 51ca56f3d1594cbebb6b7eda74a2d7fd2da2a772 Mon Sep 17 00:00:00 2001 From: dariober Date: Tue, 13 Aug 2024 09:48:14 +0100 Subject: [PATCH 21/22] Use mamba for installation --- README.md | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 0dbd1c4..0d2cbe3 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,10 @@ command line call. Quick start =========== -Install with [bioconda](https://bioconda.github.io/recipes/cnv_facets/README.html) +Install with [mamba](https://github.com/mamba-org/mamba) from [bioconda](https://bioconda.github.io/recipes/cnv_facets/README.html) repository: ``` -conda install cnv_facets +mamba install cnv_facets ``` Detect CNVs: @@ -80,34 +80,31 @@ and MacOS could work but some tweaks are necessary. Install via bioconda (recommended) ---------------------------------- -Installation via the [conda](https://conda.io/docs/) package manager is the +Installation via the [mamba](https://github.com/mamba-org/mamba) package manager is the recommended route. Options `-c bioconda -c conda-forge` can be omitted if bioconda and conda-forge are already registered channels (see below). It is generally not recommended to install packages in the conda base environment. Better to install in a dedicated envirnment. E.g.: ``` -conda create -n my_project -conda activate my_project -conda install -c bioconda -c conda-forge cnv_facets +mamba create -n my_project +mamba activate my_project +mamba install -c bioconda -c conda-forge cnv_facets ``` -If the above fails with `conda: command not found` or similar, install conda first. +If the above fails with `mamba: command not found` or similar, install mamba first. Follow the official -[documentation](https://conda.io/docs/user-guide/install/linux.html) but +[documentation](https://mamba.readthedocs.io/en/latest/installation/mamba-installation.html) but basically, these commands should suite most users: ``` -# See https://conda.io/miniconda.html -wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh - -# Run and follow the prompt on screen -bash Miniconda3-latest-Linux-x86_64.sh +curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" +bash Miniforge3-$(uname)-$(uname -m).sh # Add some useful package repositories -conda config --add channels defaults -conda config --add channels bioconda -conda config --add channels conda-forge +mamba config --add channels defaults +mamba config --add channels bioconda +mamba config --add channels conda-forge ``` Install via setup script From ca8c7fbb105798d654ed055c9c7081f5a76b83d2 Mon Sep 17 00:00:00 2001 From: dariober Date: Thu, 12 Sep 2024 12:38:27 +0100 Subject: [PATCH 22/22] Require parallel package --- bin/cnv_facets.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/cnv_facets.R b/bin/cnv_facets.R index c4141a0..bbe088c 100755 --- a/bin/cnv_facets.R +++ b/bin/cnv_facets.R @@ -22,6 +22,7 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. +suppressMessages(library(parallel)) suppressMessages(library(argparse)) suppressMessages(library(facets)) suppressMessages(library(data.table)) @@ -31,7 +32,7 @@ suppressMessages(library(gridExtra)) # ----------------------------------------------------------------------------- -VERSION= sprintf('0.16.0; facets=%s', packageVersion('facets')) +VERSION= sprintf('0.16.1; facets=%s', packageVersion('facets')) docstring<- sprintf('DESCRIPTION \\n\\ Detect somatic copy number variants (CNVs) and estimate purity and ploidy in a\\n\\