Skip to content

Refactor conditional rules structure with enabled() helper and consolidated prepare_trimmed rule#16

Draft
Headonpillow with Copilot wants to merge 4 commits into
pipeline-refactorfrom
copilot/refactor-conditional-rules-structure
Draft

Refactor conditional rules structure with enabled() helper and consolidated prepare_trimmed rule#16
Headonpillow with Copilot wants to merge 4 commits into
pipeline-refactorfrom
copilot/refactor-conditional-rules-structure

Conversation

Copilot AI commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

Replaces ad-hoc conditional logic with a structured approach: helper functions for config evaluation and target generation, plus a single branching rule instead of mutually-exclusive trimming rules.

Changes

Helper functions

  • enabled(key): Handles YAML booleans and string values ("yes", "y", "true", "1") for backward compatibility
  • all_targets(): Dynamically builds target list based on config flags; replaces manual myoutput list construction

Consolidated trimming

# Before: Two mutually-exclusive rules wrapped in Python conditionals
if config['preprocess'] in ["yes"]:
  rule Trim_galore: ...
else:
  rule move_raw_files_to_trimmed: ...

# After: Single rule with internal branching
rule prepare_trimmed:
  params: should_trim = "true" if enabled("preprocess") else "false"
  shell: """
    if [ "{params.should_trim}" = "true" ]; then
      trim_galore ...
    else
      cp {params.indir}/*.gz {params.outdir}
    fi
  """

Config template

  • Updated config_templates/basic.yaml to use YAML booleans (preprocess: true) instead of strings (preprocess: "yes")

DAG behavior

  • preprocess=true, phylogeny=true: 13 jobs (all optional rules included)
  • preprocess=false, phylogeny=false: 7 jobs (core analysis only)
  • Backward compatible with string-based configs
Original prompt

This section details on the original issue you should resolve

<issue_title>Conditional rules structure</issue_title>
<issue_description>Summary:

  1. Replace the two mutually exclusive trimming rules with a single prepare_trimmed rule that branches on enabled("preprocess").
  2. Declare rules unconditionally; use branching inside run/shell blocks instead of wrapping entire rules in Python conditionals.
  3. Optionally split large rule groups into modules (e.g., rules/preprocess.smk, rules/phylogeny.smk) and include them conditionally to keep the DAG tidy.

Implementation notes / concrete refactor steps (proposed):

  1. Use proper booleans in config and add a small helper
  • Recommend config_templates/basic.yaml use YAML booleans (e.g., preprocess: true, phylogeny: true).
  • Add an enabled(key) helper in the Snakefile to accept multiple truthy formats (strings, integers, booleans).

Example:

def enabled(key):
    v = config.get(key, False)
    if isinstance(v, str):
        return v.lower() in ("yes","y","true","1")
    return bool(v)
  1. Build rule all targets dynamically
  • Replace the current ad-hoc myoutput list + manual appends with a function all_targets() that returns the final target list depending on flags.

Example:

def all_targets():
    targets = [
        "results/denoising/read_count_tracking.tsv",
        "results/asv/ASVs.fa",
        "results/asv/ASVs_counts.tsv",
        "results/asv/ASVs_taxonomy.tsv",
        "results/phyloseq/starting_phyla_table.tsv",
        "results/phyloseq/prevalence_graph.png",
        "results/phyloseq/Phyloseq.RData",
        "results/phyloseq/ASVs_good.fasta",
        "results/phyloseq/plots/plot_1.tiff",
    ]
    if enabled("preprocess"):
        targets += [
            "results/multiQC/report_R1.html",
            "results/multiQC/report_R2.html",
            "results/multiQC_trimmed/report_R1.html",
            "results/multiQC_trimmed/report_R2.html",
        ]
    if enabled("phylogeny"):
        targets += [
            "results/phyloseq/ASV_alignment.mafft",
            "results/phyloseq/ASV_alignment.mafft.treefile",
        ]
    return targets

rule all:
    input: all_targets()
  1. Declare rules unconditionally and branch inside rule bodies where needed
  • Avoid defining whole rules inside Python if blocks. Instead define rules always and use the enabled() helper inside run/shell blocks to branch behavior.
  • Example: replace the current two mutually-exclusive rules that create intermediate/trimmed/* with a single prepare_trimmed rule that either runs trim_galore or copies raw files depending on enabled("preprocess").
  1. Optionally split rule modules and use conditional includes
  • Put large groups of rules in rules/preprocess.smk, rules/phylogeny.smk, etc., and use if enabled("preprocess"): include: "rules/preprocess.smk". Use this only for large modules to keep the top-level Snakefile tidy.
  1. Safety and housekeeping
  • Remove transient print() calls from the Snakefile.
  • Use mkdir -p or directory() outputs instead of ad-hoc mkdir guards.
  • Add a short test checklist: create runs/demo with config.yaml toggling preprocess and phylogeny and run snakemake --configfile runs/demo/config.yaml --directory runs/demo -n to assert the DAG only contains intended targets.

Testing / Acceptance checklist for this issue

  • Add config_templates/basic.yaml with boolean flags.
  • Add enabled() and all_targets() to Snakefile.
  • Replace ad-hoc myoutput usage with all_targets().
  • Convert the two mutually-exclusive trimming rules into a single branching prepare_trimmed rule.
  • Run snakemake -n with permutations of the flags and confirm the DAG and planned jobs match expectations.

Notes on scope

  • This refactor touches Snakefile and possible new config_templates/basic.yaml.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits December 9, 2025 14:34
…l rules

Co-authored-by: Headonpillow <85705350+Headonpillow@users.noreply.github.com>
…er naming

Co-authored-by: Headonpillow <85705350+Headonpillow@users.noreply.github.com>
Co-authored-by: Headonpillow <85705350+Headonpillow@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor conditional rules structure for Trimmed rules Refactor conditional rules structure with enabled() helper and consolidated prepare_trimmed rule Dec 9, 2025
Copilot AI requested a review from Headonpillow December 9, 2025 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants