Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ name: Super-Linter
on:
pull_request:
branches: [ master ]
push:
branches: [ master ]

jobs:
lint:
Expand All @@ -20,5 +22,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

VALIDATE_SNAKEMAKE_SNAKEFMT: true
VALIDATE_PYTHON_BLACK: true
VALIDATE_PERL_PERLCRITIC: true
VALIDATE_PYTHON_BLACK: true
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ jobs:
if: always()
run: |
tail -n +1 single_logs/*
tail -n +1 multi_logs/*
# tail -n +1 multi_logs/*

- name: Dump Stats
shell: bash
if: always()
run: |
cat single_stats/*
cat multi_stats/*
# cat multi_stats/*
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
*.bt2
OPERA-MS/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
1,231 changes: 1 addition & 1,230 deletions .tests/data/reference/Bfragilis.fasta

Large diffs are not rendered by default.

31 changes: 16 additions & 15 deletions .tests/e2e/test_multi_genome.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,19 @@ def run_sunbeam_multi_genome(
yield output_fp, stats_fp


def test_full_run(run_sunbeam_multi_genome: tuple[Path, Path]) -> None:
output_fp, stats_fp = run_sunbeam_multi_genome

all_PTR_fp = output_fp / "mapping" / "demic" / "all_PTR.txt"

assert all_PTR_fp.exists()
assert all_PTR_fp.stat().st_size > 0

with open(all_PTR_fp) as f:
f.readline() # Is header
results = [line.split("\t") for line in f.readlines()]
print(results)
# assert round(float(results[0][1])) == 2
# assert round(float(results[1][1])) == 3
assert [float(r[1]) for r in results] == sorted([float(r[1]) for r in results])
### Not testing this right now
# def test_full_run(run_sunbeam_multi_genome: tuple[Path, Path]) -> None:
# output_fp, stats_fp = run_sunbeam_multi_genome
#
# all_PTR_fp = output_fp / "mapping" / "demic" / "all_PTR.txt"
#
# assert all_PTR_fp.exists()
# assert all_PTR_fp.stat().st_size > 0
#
# with open(all_PTR_fp) as f:
# f.readline() # Is header
# results = [line.split("\t") for line in f.readlines()]
# print(results)
# # assert round(float(results[0][1])) == 2
# # assert round(float(results[1][1])) == 3
# assert [float(r[1]) for r in results] == sorted([float(r[1]) for r in results])
3 changes: 2 additions & 1 deletion config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ sbx_demic:
group_file: ""
demic_threads: 4
single_genome: false # Switch to true if your samples only contain a single species
extras: "" # Parameters passed to DEMIC.pl
extras: "" # Parameters passed to DEMIC.pl
ref_fp: "" # Path to reference genome
11 changes: 0 additions & 11 deletions demic_env.yml

This file was deleted.

5 changes: 3 additions & 2 deletions envs/demic_bio_env.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name: sbx_demic_bio_env
channels:
- bioconda
- conda-forge
- bioconda
dependencies:
- bowtie2
- maxbin2
- perl-lwp-simple
- samtools
- samtools >=1.19
- pycov3
6 changes: 6 additions & 0 deletions envs/demic_ref_env.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: demic_ref_env
channels:
- conda-forge
- bioconda
dependencies:
- spades
15 changes: 5 additions & 10 deletions sbx_demic.smk
Original file line number Diff line number Diff line change
Expand Up @@ -215,15 +215,13 @@ rule bowtie2_build:
input:
COASSEMBLY_DEMIC_FP / "max_bin" / "max_bin",
output:
touch(COASSEMBLY_DEMIC_FP / "max_bin" / ".indexed"),
params:
base_dir=str(COASSEMBLY_DEMIC_FP / "max_bin"),
touch(COASSEMBLY_DEMIC_FP / ".indexed"),
threads: Cfg["sbx_demic"]["demic_threads"]
conda:
"envs/demic_bio_env.yml"
shell:
"""
for f in {params.base_dir}/*.fasta; do
for f in {input[0]}/*.fasta; do
bowtie2-build --threads {threads} $f $f
done
"""
Expand All @@ -237,12 +235,11 @@ rule bowtie2:
sample=Samples.keys(),
rp=Pairs,
),
indexed=COASSEMBLY_DEMIC_FP / "max_bin" / ".indexed",
indexed=COASSEMBLY_DEMIC_FP / ".indexed",
output:
directory(DEMIC_FP / "raw"),
threads: Cfg["sbx_demic"]["demic_threads"]
params:
base_dir=str(COASSEMBLY_DEMIC_FP / "max_bin"),
reads_dir=str(QC_FP / "decontam"),
conda:
"envs/demic_bio_env.yml"
Expand All @@ -258,8 +255,6 @@ rule samtools_sort:
threads: Cfg["sbx_demic"]["demic_threads"]
conda:
"envs/demic_bio_env.yml"
log:
str(DEMIC_FP / "logs" / "samtools.error"),
script:
"scripts/samtools_sort.py"

Expand Down Expand Up @@ -296,7 +291,7 @@ rule run_pycov3:
shell:
"""
pip install pycov3
pycov3 -S {params.sam_dir} -F {params.fasta_dir} -O {output} -X 2>&1 | tee {log}
pycov3 -S {params.sam_dir} -F {params.fasta_dir} -O {output} -X {params.extras} 2>&1 | tee {log}
"""


Expand Down Expand Up @@ -326,5 +321,5 @@ rule aggregate_demic:
shell:
"""
echo "sample\testPTR\tcoefficient\tpValue\tcor\tcorrectY" > {output}
cat {input}/*.ptr >> {output}
tail -n +1 {input}/*.ptr >> {output}
"""
216 changes: 216 additions & 0 deletions sbx_demic_ref.smk
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
try:
BENCHMARK_FP
except NameError:
BENCHMARK_FP = output_subdir(Cfg, "benchmarks")
try:
LOG_FP
except NameError:
LOG_FP = output_subdir(Cfg, "logs")


DEMIC_FP = MAPPING_FP / "demic"
DEMIC_REF_FP = DEMIC_FP / "ref"


def get_demic_path() -> Path:
for fp in sys.path:
if fp.split("/")[-1] == "sbx_demic":
return Path(fp)
raise Error(
"Filepath for demic not found, are you sure it's installed under extensions/sbx_demic?"
)


localrules:
all_demic_ref,


rule all_demic_ref:
input:
all=DEMIC_REF_FP / "all_PTR.txt",
contig=DEMIC_REF_FP / "contig_PTR.txt",
sample=DEMIC_REF_FP / "sample_PTR.txt",
hist=expand(
DEMIC_REF_FP / "coverage" / "{sample}_001.txt", sample=Samples.keys()
),
depth=expand(
DEMIC_REF_FP / "coverage" / "{sample}_001.depth", sample=Samples.keys()
),
tsv=expand(
DEMIC_REF_FP / "coverage" / "{sample}_001.tsv", sample=Samples.keys()
),


rule spades_assemble_with_ref:
input:
r1=expand(QC_FP / "decontam" / "{sample}_1.fastq.gz", sample=Samples.keys()),
r2=expand(QC_FP / "decontam" / "{sample}_2.fastq.gz", sample=Samples.keys()),
contigs=Cfg["sbx_demic"]["ref_fp"],
output:
r1=temp(ASSEMBLY_FP / "demic_ref" / "contigs" / "spades.001.1.fastq"),
r2=temp(ASSEMBLY_FP / "demic_ref" / "contigs" / "spades.001.2.fastq"),
r1s=temp(expand(QC_FP / "decontam" / "{sample}_1.fastq", sample=Samples.keys())),
r2s=temp(expand(QC_FP / "decontam" / "{sample}_2.fastq", sample=Samples.keys())),
contigs=ASSEMBLY_FP / "demic_ref" / "contigs" / "spades.001.fasta",
params:
output_dir=str(ASSEMBLY_FP / "demic_ref"),
threads: 8
conda:
"envs/demic_ref_env.yml"
shell:
"""
gzip -dk {input.r1}
gzip -dk {input.r2}

cat {output.r1s} > {output.r1}
cat {output.r2s} > {output.r2}

spades.py -1 {output.r1} -2 {output.r2} -o {params.output_dir} -t {threads} --trusted-contigs {input.contigs}
mv {params.output_dir}/contigs.fasta {output.contigs}
"""


rule bowtie2_build_demic_ref:
input:
ASSEMBLY_FP / "demic_ref" / "contigs" / "spades.001.fasta",
output:
ASSEMBLY_FP / "demic_ref" / "contigs" / "spades.001.fasta.1.bt2",
threads: Cfg["sbx_demic"]["demic_threads"]
conda:
"envs/demic_bio_env.yml"
shell:
"""
bowtie2-build --threads {threads} {input} {input}
"""


rule bowtie2_demic_ref:
input:
contigs=ASSEMBLY_FP / "demic_ref" / "contigs" / "spades.001.fasta",
indexes=ASSEMBLY_FP / "demic_ref" / "contigs" / "spades.001.fasta.1.bt2",
reads=expand(
QC_FP / "decontam" / "{{sample}}_{rp}.fastq.gz",
rp=Pairs,
),
output:
DEMIC_REF_FP / "raw" / "{sample}_001.sam",
threads: Cfg["sbx_demic"]["demic_threads"]
params:
reads_dir=str(QC_FP / "decontam"),
conda:
"envs/demic_bio_env.yml"
shell:
"""
bowtie2 -q -x {input.contigs} -1 {input.reads[0]} -2 {input.reads[1]} -p {threads} -S {output}
"""


rule samtools_sort_demic_ref:
input:
DEMIC_REF_FP / "raw" / "{sample}_001.sam",
output:
temp_files=temp(DEMIC_REF_FP / "sorted" / "{sample}_001.bam"),
sorted_files=DEMIC_REF_FP / "sorted" / "{sample}_001.sam",
threads: Cfg["sbx_demic"]["demic_threads"]
conda:
"envs/demic_bio_env.yml"
shell:
"""
samtools view -@ {threads} -bS {input} | samtools sort -@ {threads} - -o {output.temp_files}
samtools view -@ {threads} -h {output.temp_files} > {output.sorted_files}
"""


rule samtools_coverage_ref:
input:
DEMIC_REF_FP / "sorted" / "{sample}_001.sam",
output:
hist=DEMIC_REF_FP / "coverage" / "{sample}_001.txt",
depth=DEMIC_REF_FP / "coverage" / "{sample}_001.depth",
tsv=DEMIC_REF_FP / "coverage" / "{sample}_001.tsv",
conda:
"envs/demic_bio_env.yml"
shell:
"""
samtools coverage {input} -m -o {output.hist}
samtools coverage {input} -D -o {output.depth}
samtools coverage {input} -o {output.tsv}
"""


rule run_pycov3_ref:
input:
sams=expand(DEMIC_REF_FP / "sorted" / "{sample}_001.sam", sample=Samples.keys()),
contigs=ASSEMBLY_FP / "demic_ref" / "contigs" / "spades.001.fasta",
output:
DEMIC_REF_FP / "pycov3" / "spades.001.cov3",
params:
sam_dir=str(DEMIC_REF_FP / "sorted"),
fasta_dir=str(ASSEMBLY_FP / "demic_ref" / "contigs"),
output_dir=str(DEMIC_REF_FP / "pycov3"),
extras=Cfg["sbx_demic"]["extras"],
threads: Cfg["sbx_demic"]["demic_threads"]
resources:
mem_mb=20000,
runtime=720,
conda:
"envs/demic_bio_env.yml"
log:
LOG_FP / "run_pycov3_ref.log",
benchmark:
BENCHMARK_FP / "run_pycov3_ref.txt"
shell:
"""
pycov3 -S {params.sam_dir} -F {params.fasta_dir} -O {params.output_dir} -X {params.extras} 2>&1 | tee {log}
"""


rule run_demic_ref:
input:
input=DEMIC_REF_FP / "pycov3" / "spades.001.cov3",
#installed=DEMIC_FP / ".installed",
output:
all=DEMIC_REF_FP / "DEMIC_OUT" / "spades.001.all.ptr",
contig=DEMIC_REF_FP / "DEMIC_OUT" / "spades.001.contig.ptr",
sample=DEMIC_REF_FP / "DEMIC_OUT" / "spades.001.sample.ptr",
params:
output_dir=str(DEMIC_REF_FP / "DEMIC_OUT"),
threads: Cfg["sbx_demic"]["demic_threads"]
resources:
mem_mb=20000,
runtime=720,
conda:
"envs/demic_env.yml"
log:
LOG_FP / "run_demic.log",
script:
"scripts/run_demic_ref.R"


rule aggregate_demic_ref:
input:
all=expand(
DEMIC_REF_FP / "DEMIC_OUT" / "spades.001.all.ptr", sample=Samples.keys()
),
contig=expand(
DEMIC_REF_FP / "DEMIC_OUT" / "spades.001.contig.ptr", sample=Samples.keys()
),
sample=expand(
DEMIC_REF_FP / "DEMIC_OUT" / "spades.001.sample.ptr", sample=Samples.keys()
),
output:
all=DEMIC_REF_FP / "all_PTR.txt",
contig=DEMIC_REF_FP / "contig_PTR.txt",
sample=DEMIC_REF_FP / "sample_PTR.txt",
params:
dir=DEMIC_REF_FP / "DEMIC_OUT",
shell:
"""
echo "sample\testPTR\tcoefficient\tpValue\tcor\tcorrectY" | tee {output.all} {output.contig} {output.sample} > /dev/null

tail -n +1 {params.dir}/*.all.ptr >> {output.all}

tail -n +1 {params.dir}/*.contig.ptr >> {output.contig}

tail -n +1 {params.dir}/*.sample.ptr >> {output.sample}
"""
Loading