From c898bcd71a9cff8ffbd9d3441d8118eeb2e0fd5a Mon Sep 17 00:00:00 2001 From: Lea Evers Date: Thu, 12 Mar 2026 15:18:08 +0100 Subject: [PATCH 1/2] move files into {{project_name}} folder --- config/config.yaml | 8 ------ copier.yml | 25 +++++++++++++++++++ .gitignore => {{ project_name }}/.gitignore | 0 .../.snakemake-workflow-catalog.yml | 0 LICENSE => {{ project_name }}/LICENSE | 0 .../README.md.jinja | 18 +++++++------ .../config}/README.md | 5 ---- {{ project_name }}/config/config.yaml | 0 .../profiles}/README.md | 0 .../workflow}/Snakefile | 3 +-- .../workflow}/envs/get_genome.yaml | 0 .../workflow}/envs/simulate_reads.yaml | 0 .../workflow}/envs/validate_genome.yaml | 0 .../workflow}/rules/common.smk | 0 .../workflow}/rules/process_reads.smk | 7 ------ .../workflow}/schemas/config.schema.yaml | 0 .../workflow}/schemas/samples.schema.yaml | 0 .../workflow}/scripts/validate_fasta.py | 0 18 files changed, 36 insertions(+), 30 deletions(-) delete mode 100644 config/config.yaml create mode 100644 copier.yml rename .gitignore => {{ project_name }}/.gitignore (100%) rename .snakemake-workflow-catalog.yml => {{ project_name }}/.snakemake-workflow-catalog.yml (100%) rename LICENSE => {{ project_name }}/LICENSE (100%) rename README.md => {{ project_name }}/README.md.jinja (78%) rename {config => {{ project_name }}/config}/README.md (76%) create mode 100644 {{ project_name }}/config/config.yaml rename {profiles => {{ project_name }}/profiles}/README.md (100%) rename {workflow => {{ project_name }}/workflow}/Snakefile (92%) rename {workflow => {{ project_name }}/workflow}/envs/get_genome.yaml (100%) rename {workflow => {{ project_name }}/workflow}/envs/simulate_reads.yaml (100%) rename {workflow => {{ project_name }}/workflow}/envs/validate_genome.yaml (100%) rename {workflow => {{ project_name }}/workflow}/rules/common.smk (100%) rename {workflow => {{ project_name }}/workflow}/rules/process_reads.smk (91%) rename {workflow => {{ project_name }}/workflow}/schemas/config.schema.yaml (100%) rename {workflow => {{ project_name }}/workflow}/schemas/samples.schema.yaml (100%) rename {workflow => {{ project_name }}/workflow}/scripts/validate_fasta.py (100%) diff --git a/config/config.yaml b/config/config.yaml deleted file mode 100644 index bb023b8..0000000 --- a/config/config.yaml +++ /dev/null @@ -1,8 +0,0 @@ -sample_sheet: ".test/config/samples.tsv" - -get_genome: - ncbi_ftp: https://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz - -simulate_reads: - read_length: 100 - read_number: 10000 diff --git a/copier.yml b/copier.yml new file mode 100644 index 0000000..bc045e9 --- /dev/null +++ b/copier.yml @@ -0,0 +1,25 @@ +project_name: + type: str + help: What is your project name? + +scripts: + type: + help: What kind of scripts are you planning to use? + choices: + - notebooks + - R + - python + multiselect: true + +isolation: + type: + help: What container? + choices: + - pixi + - conda + - apptainer/singularity + + +scripts: + type: boolean + help: Would you like to link this workflow to an ORCID ID? diff --git a/.gitignore b/{{ project_name }}/.gitignore similarity index 100% rename from .gitignore rename to {{ project_name }}/.gitignore diff --git a/.snakemake-workflow-catalog.yml b/{{ project_name }}/.snakemake-workflow-catalog.yml similarity index 100% rename from .snakemake-workflow-catalog.yml rename to {{ project_name }}/.snakemake-workflow-catalog.yml diff --git a/LICENSE b/{{ project_name }}/LICENSE similarity index 100% rename from LICENSE rename to {{ project_name }}/LICENSE diff --git a/README.md b/{{ project_name }}/README.md.jinja similarity index 78% rename from README.md rename to {{ project_name }}/README.md.jinja index 7bbce8e..49383c3 100644 --- a/README.md +++ b/{{ project_name }}/README.md.jinja @@ -1,13 +1,17 @@ -# Snakemake workflow: `` +# Snakemake workflow: `{{ project_name }}` [![Snakemake](https://img.shields.io/badge/snakemake-≥8.0.0-brightgreen.svg)](https://snakemake.github.io) -[![GitHub actions status](https://github.com///workflows/Tests/badge.svg?branch=main)](https://github.com///actions?query=branch%3Amain+workflow%3ATests) -[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) -[![workflow catalog](https://img.shields.io/badge/Snakemake%20workflow%20catalog-darkgreen)](https://snakemake.github.io/snakemake-workflow-catalog/docs/workflows//) -A Snakemake workflow for `` -- [Snakemake workflow: ``](#snakemake-workflow-name) +The workflow is built using [snakemake](https://snakemake.readthedocs.io/en/stable/) and consists of the following steps: + +1. Describe +2. your +3. rules +4. here + + +- [Snakemake workflow: `{{ project_name }}`](#snakemake-workflow-{{ project_name }}) - [Usage](#usage) - [Deployment options](#deployment-options) - [Workflow profiles](#workflow-profiles) @@ -17,8 +21,6 @@ A Snakemake workflow for `` ## Usage -The usage of this workflow is described in the [Snakemake Workflow Catalog](https://snakemake.github.io/snakemake-workflow-catalog/docs/workflows//). - Detailed information about input data and workflow configuration can also be found in the [`config/README.md`](config/README.md). If you use this workflow in a paper, don't forget to give credits to the authors by citing the URL of this repository or its DOI. diff --git a/config/README.md b/{{ project_name }}/config/README.md similarity index 76% rename from config/README.md rename to {{ project_name }}/config/README.md index 19d863b..b1cc208 100644 --- a/config/README.md +++ b/{{ project_name }}/config/README.md @@ -29,10 +29,5 @@ This table lists all parameters that can be used to run the workflow. | parameter | type | details | default | | ------------------ | ---- | ------------------------------------- | ------------------------------ | -| **sample_sheet** | | | | -| path | str | path to sample sheet, mandatory | "config/samples.tsv" | -| **get_genome** | | | | -| ncbi_ftp | str | link to a genome on NCBI's FTP server | link to _S. cerevisiae_ genome | | **simulate_reads** | | | | -| read_length | num | length of target reads in bp | 100 | | read_number | num | number of total reads to be simulated | 10000 | diff --git a/{{ project_name }}/config/config.yaml b/{{ project_name }}/config/config.yaml new file mode 100644 index 0000000..e69de29 diff --git a/profiles/README.md b/{{ project_name }}/profiles/README.md similarity index 100% rename from profiles/README.md rename to {{ project_name }}/profiles/README.md diff --git a/workflow/Snakefile b/{{ project_name }}/workflow/Snakefile similarity index 92% rename from workflow/Snakefile rename to {{ project_name }}/workflow/Snakefile index 08a5478..d1965cc 100644 --- a/workflow/Snakefile +++ b/{{ project_name }}/workflow/Snakefile @@ -6,13 +6,12 @@ # load configuration # ----------------------------------------------------- -configfile: "config/config.yaml" +# configfile: "config/config.yaml" # load rules # ----------------------------------------------------- include: "rules/common.smk" -include: "rules/process_reads.smk" # optional messages, log and error handling diff --git a/workflow/envs/get_genome.yaml b/{{ project_name }}/workflow/envs/get_genome.yaml similarity index 100% rename from workflow/envs/get_genome.yaml rename to {{ project_name }}/workflow/envs/get_genome.yaml diff --git a/workflow/envs/simulate_reads.yaml b/{{ project_name }}/workflow/envs/simulate_reads.yaml similarity index 100% rename from workflow/envs/simulate_reads.yaml rename to {{ project_name }}/workflow/envs/simulate_reads.yaml diff --git a/workflow/envs/validate_genome.yaml b/{{ project_name }}/workflow/envs/validate_genome.yaml similarity index 100% rename from workflow/envs/validate_genome.yaml rename to {{ project_name }}/workflow/envs/validate_genome.yaml diff --git a/workflow/rules/common.smk b/{{ project_name }}/workflow/rules/common.smk similarity index 100% rename from workflow/rules/common.smk rename to {{ project_name }}/workflow/rules/common.smk diff --git a/workflow/rules/process_reads.smk b/{{ project_name }}/workflow/rules/process_reads.smk similarity index 91% rename from workflow/rules/process_reads.smk rename to {{ project_name }}/workflow/rules/process_reads.smk index 35942e0..779d080 100644 --- a/workflow/rules/process_reads.smk +++ b/{{ project_name }}/workflow/rules/process_reads.smk @@ -1,10 +1,3 @@ -# ----------------------------------------------------- # -# EXAMPLE WORKFLOW # -# ----------------------------------------------------- # - - -# fetch genome sequence from NCBI -# ----------------------------------------------------- rule get_genome: output: fasta="results/get_genome/genome.fna", diff --git a/workflow/schemas/config.schema.yaml b/{{ project_name }}/workflow/schemas/config.schema.yaml similarity index 100% rename from workflow/schemas/config.schema.yaml rename to {{ project_name }}/workflow/schemas/config.schema.yaml diff --git a/workflow/schemas/samples.schema.yaml b/{{ project_name }}/workflow/schemas/samples.schema.yaml similarity index 100% rename from workflow/schemas/samples.schema.yaml rename to {{ project_name }}/workflow/schemas/samples.schema.yaml diff --git a/workflow/scripts/validate_fasta.py b/{{ project_name }}/workflow/scripts/validate_fasta.py similarity index 100% rename from workflow/scripts/validate_fasta.py rename to {{ project_name }}/workflow/scripts/validate_fasta.py From ae9216478d1e00a6e319b1e135ca9c5202554a72 Mon Sep 17 00:00:00 2001 From: Lea Evers Date: Thu, 12 Mar 2026 15:53:35 +0100 Subject: [PATCH 2/2] WIP --- .gitattributes | 2 + .gitignore | 3 + .test/config/config.yaml | 9 +- copier.yml | 57 +++++++--- {{ project_name }}/data/config.yaml.jinja | 19 ++++ {{ project_name }}/data/input.txt | 1 + {{ project_name }}/workflow/Snakefile | 9 +- .../workflow/envs/simulate_reads.yaml | 7 -- .../workflow/envs/validate_genome.yaml | 8 -- {{ project_name }}/workflow/rules/common.smk | 16 --- {{ project_name }}/workflow/rules/example.smk | 7 ++ .../workflow/rules/process_reads.smk | 105 ------------------ .../workflow/schemas/samples.schema.yaml | 25 ----- .../workflow/scripts/validate_fasta.py | 24 ---- 14 files changed, 75 insertions(+), 217 deletions(-) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 {{ project_name }}/data/config.yaml.jinja create mode 100644 {{ project_name }}/data/input.txt delete mode 100644 {{ project_name }}/workflow/envs/simulate_reads.yaml delete mode 100644 {{ project_name }}/workflow/envs/validate_genome.yaml delete mode 100644 {{ project_name }}/workflow/rules/common.smk create mode 100644 {{ project_name }}/workflow/rules/example.smk delete mode 100644 {{ project_name }}/workflow/rules/process_reads.smk delete mode 100644 {{ project_name }}/workflow/schemas/samples.schema.yaml delete mode 100644 {{ project_name }}/workflow/scripts/validate_fasta.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..997504b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# SCM syntax highlighting & preventing 3-way merges +pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae849e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# pixi environments +.pixi/* +!.pixi/config.toml diff --git a/.test/config/config.yaml b/.test/config/config.yaml index b7c08e1..db3b593 100644 --- a/.test/config/config.yaml +++ b/.test/config/config.yaml @@ -1,8 +1 @@ -sample_sheet: "config/samples.tsv" - -get_genome: - ncbi_ftp: https://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz - -simulate_reads: - read_length: 100 - read_number: 10000 +input_file: "data/input.txt" diff --git a/copier.yml b/copier.yml index bc045e9..53067b9 100644 --- a/copier.yml +++ b/copier.yml @@ -2,24 +2,45 @@ project_name: type: str help: What is your project name? -scripts: - type: - help: What kind of scripts are you planning to use? - choices: - - notebooks - - R - - python - multiselect: true +features: + type: str + help: Which of these features are you interested in? + choices: + - isolated conda environments + - Jupyter Notebook Integration + - Report Generation + - Schema Validation + +# plugins: +# type: str +# help: Which of these features are you interested in? +# choices: +# - Schema Validation +# - Jupyter Notebook Integration +# - Report Generation +# - + +# scripts: +# type: +# help: What kind of scripts are you planning to use? +# choices: +# - notebooks +# - R +# - python +# multiselect: true -isolation: - type: - help: What container? - choices: - - pixi - - conda - - apptainer/singularity +# isolation: +# type: +# help: What container? +# choices: +# - pixi +# - conda +# - apptainer/singularity +# profiles: +# type: boolean +# help: Would you like to set up a default profile? -scripts: - type: boolean - help: Would you like to link this workflow to an ORCID ID? +# orcid: +# type: boolean +# help: Would you like to link this workflow to an ORCID ID? diff --git a/{{ project_name }}/data/config.yaml.jinja b/{{ project_name }}/data/config.yaml.jinja new file mode 100644 index 0000000..a024df9 --- /dev/null +++ b/{{ project_name }}/data/config.yaml.jinja @@ -0,0 +1,19 @@ +### GENERAL SNAKEMAKE SETTINGS + +# Tell snakemake which remote executor plugin to use, in our case the plugin +# for the cluster system LSF, which is documented here: +# https://snakemake.github.io/snakemake-plugin-catalog/plugins/executor/lsf.html +# executor: "lsf" + +# Maximum number of cluster cores / cpus to schedule jobs for. +# +cores: { { max_cores } } + +# Always use conda environments for software deployment. Internally snakemake +# implicitly uses mamba for speed (at the time of writing). +software-deployment-method: { { sdm } } + +default-resources: + # The default amount of memory that is reserved for a rule, if the rule (and + # the snakemake command) don't specify anything else. + mem_mb: 4000 diff --git a/{{ project_name }}/data/input.txt b/{{ project_name }}/data/input.txt new file mode 100644 index 0000000..10239e6 --- /dev/null +++ b/{{ project_name }}/data/input.txt @@ -0,0 +1 @@ +Hello from Snakemake! diff --git a/{{ project_name }}/workflow/Snakefile b/{{ project_name }}/workflow/Snakefile index d1965cc..9daac34 100644 --- a/{{ project_name }}/workflow/Snakefile +++ b/{{ project_name }}/workflow/Snakefile @@ -6,12 +6,11 @@ # load configuration # ----------------------------------------------------- -# configfile: "config/config.yaml" - +configfile: "config/config.yaml" # load rules # ----------------------------------------------------- -include: "rules/common.smk" +include: "rules/example.smk" # optional messages, log and error handling @@ -19,11 +18,9 @@ include: "rules/common.smk" onstart: print("\n--- Analysis started ---\n") - onsuccess: print("\n--- Workflow finished! ---\n") - onerror: print("\n--- An error occurred! ---\n") @@ -32,5 +29,5 @@ onerror: # ----------------------------------------------------- rule all: input: - "results/multiqc/multiqc_report.html", + "results/output.txt" default_target: True diff --git a/{{ project_name }}/workflow/envs/simulate_reads.yaml b/{{ project_name }}/workflow/envs/simulate_reads.yaml deleted file mode 100644 index 701ae1f..0000000 --- a/{{ project_name }}/workflow/envs/simulate_reads.yaml +++ /dev/null @@ -1,7 +0,0 @@ -name: simulate_reads -channels: - - conda-forge - - bioconda - - nodefaults -dependencies: - - dwgsim=1.1.14 diff --git a/{{ project_name }}/workflow/envs/validate_genome.yaml b/{{ project_name }}/workflow/envs/validate_genome.yaml deleted file mode 100644 index 4cb2750..0000000 --- a/{{ project_name }}/workflow/envs/validate_genome.yaml +++ /dev/null @@ -1,8 +0,0 @@ -name: validate_genome -channels: - - conda-forge - - bioconda - - nodefaults -dependencies: - - python=3.12 - - biopython=1.85 diff --git a/{{ project_name }}/workflow/rules/common.smk b/{{ project_name }}/workflow/rules/common.smk deleted file mode 100644 index 456827e..0000000 --- a/{{ project_name }}/workflow/rules/common.smk +++ /dev/null @@ -1,16 +0,0 @@ -# import basic packages -import pandas as pd -from snakemake.utils import validate - - -# read sample sheet -samples = ( - pd.read_csv(config["sample_sheet"], sep="\t", dtype={"sample": str}) - .set_index("sample", drop=False) - .sort_index() -) - - -# validate sample sheet and config file -validate(samples, schema="../schemas/samples.schema.yaml") -validate(config, schema="../schemas/config.schema.yaml") diff --git a/{{ project_name }}/workflow/rules/example.smk b/{{ project_name }}/workflow/rules/example.smk new file mode 100644 index 0000000..90ab32f --- /dev/null +++ b/{{ project_name }}/workflow/rules/example.smk @@ -0,0 +1,7 @@ +rule copy_file: + input: + config["input"] + output: + "results/output.txt" + shell: + "cp {input} {output}" diff --git a/{{ project_name }}/workflow/rules/process_reads.smk b/{{ project_name }}/workflow/rules/process_reads.smk deleted file mode 100644 index 779d080..0000000 --- a/{{ project_name }}/workflow/rules/process_reads.smk +++ /dev/null @@ -1,105 +0,0 @@ -rule get_genome: - output: - fasta="results/get_genome/genome.fna", - conda: - "../envs/get_genome.yaml" - message: - """--- Downloading genome sequence.""" - params: - ncbi_ftp=lookup(within=config, dpath="get_genome/ncbi_ftp"), - log: - "results/get_genome/genome.log", - shell: - "wget -O results/get_genome/genome.fna.gz {params.ncbi_ftp} > {log} 2>&1 && " - "gunzip results/get_genome/genome.fna.gz >> {log} 2>&1" - - -# validate genome sequence file -# ----------------------------------------------------- -rule validate_genome: - input: - fasta=rules.get_genome.output.fasta, - output: - fasta="results/validate_genome/genome.fna", - conda: - "../envs/validate_genome.yaml" - message: - """--- Validating genome sequence file.""" - log: - "results/validate_genome/genome.log", - script: - "../scripts/validate_fasta.py" - - -# simulate read data using DWGSIM -# ----------------------------------------------------- -rule simulate_reads: - input: - fasta=rules.validate_genome.output.fasta, - output: - multiext( - "results/simulate_reads/{sample}", - read1=".bwa.read1.fastq.gz", - read2=".bwa.read2.fastq.gz", - ), - conda: - "../envs/simulate_reads.yaml" - message: - """--- Simulating read data with DWGSIM.""" - params: - output_type=1, - read_length=lookup(within=config, dpath="simulate_reads/read_length"), - read_number=lookup(within=config, dpath="simulate_reads/read_number"), - log: - "results/simulate_reads/{sample}.log", - shell: - "output_prefix=`echo {output.read1} | cut -f 1 -d .`;" - "dwgsim " - " -1 {params.read_length}" - " -2 {params.read_length}" - " -N {params.read_number}" - " -o {params.output_type}" - " {input.fasta}" - " ${{output_prefix}}" - " > {log} 2>&1" - - -# make QC report -# ----------------------------------------------------- -rule fastqc: - input: - fastq="results/simulate_reads/{sample}.bwa.{read}.fastq.gz", - output: - html="results/fastqc/{sample}.bwa.{read}_fastqc.html", - zip="results/fastqc/{sample}.bwa.{read}_fastqc.zip", - params: - extra="--quiet", - message: - """--- Checking fastq files with FastQC.""" - log: - "results/fastqc/{sample}.bwa.{read}.log", - threads: 1 - wrapper: - "v6.0.0/bio/fastqc" - - -# run multiQC on tool output -# ----------------------------------------------------- -rule multiqc: - input: - expand( - "results/fastqc/{sample}.bwa.{read}_fastqc.{ext}", - sample=samples.index, - read=["read1", "read2"], - ext=["html", "zip"], - ), - output: - report="results/multiqc/multiqc_report.html", - params: - extra="--verbose --dirs", - message: - """--- Generating MultiQC report for seq data.""" - log: - "results/multiqc/multiqc.log", - wrapper: - "v6.0.0/bio/multiqc" diff --git a/{{ project_name }}/workflow/schemas/samples.schema.yaml b/{{ project_name }}/workflow/schemas/samples.schema.yaml deleted file mode 100644 index d5aefc7..0000000 --- a/{{ project_name }}/workflow/schemas/samples.schema.yaml +++ /dev/null @@ -1,25 +0,0 @@ -$schema: "https://json-schema.org/draft/2020-12/schema" -description: entries for the sample sheet -properties: - sample: - type: string - description: sample name/identifier - condition: - type: string - description: sample condition that will be compared during differential analysis - replicate: - type: integer - default: 1 - description: consecutive numbers representing multiple replicates of one condition - read1: - type: string - description: names of fastq.gz files, read 1 - read2: - type: string - description: names of fastq.gz files, read 2 (optional) - -required: - - sample - - condition - - replicate - - read1 diff --git a/{{ project_name }}/workflow/scripts/validate_fasta.py b/{{ project_name }}/workflow/scripts/validate_fasta.py deleted file mode 100644 index e8bc43b..0000000 --- a/{{ project_name }}/workflow/scripts/validate_fasta.py +++ /dev/null @@ -1,24 +0,0 @@ -import sys -from Bio import SeqIO - -sys.stderr = open(snakemake.log[0], "w", buffering=1) - - -def validate_fasta(input_fasta, output_fasta): - try: - with open(input_fasta, "r") as fasta_file: - records = list(SeqIO.parse(fasta_file, "fasta")) - if not records: - raise ValueError("FASTA file is empty or improperly formatted.") - else: - summary = [f"Validated sequence records for {output_fasta}:"] - summary += [f"{i.name}: {i.description}" for i in records] - with open(output_fasta, "w") as validated_file: - SeqIO.write(records, validated_file, "fasta") - sys.stderr.write("\n".join(summary)) - except Exception as e: - sys.stderr.write(f"Validation failed: {e}\n") - raise - - -validate_fasta(snakemake.input["fasta"], snakemake.output["fasta"])