Rules Reference¶
Complete documentation for all Snakemake rules in the pipeline.
Processing Rules¶
These rules form the core data processing pipeline.
stage_pod5¶
Lay a directory of symlinks over a sample's raw POD5 files. Nothing copies the
signal: dorado basecalls the directory with --recursive, and escpod classify
walks it, looking each aligned read up by id. This replaced merge_pods, which
wrote a full second copy of every run per sample.
File: workflow/rules/aatrnaseq-process.smk
| Property | Value |
|---|---|
| Input | All POD5 files for sample |
| Output | pod5/{sample}/<run>/<pod5_pass\|pod5_fail\|pod5>/<file>.pod5 (symlinks) |
| GPU | No |
Notes:
- Links mirror the source layout so runs pooled into one sample cannot collide on a basename
- Targets are canonical paths; the directory works from anywhere
- A local rule: it is not submitted to the cluster
rebasecall¶
Re-basecall POD5 files with Dorado, emitting move tables for the charging model.
File: workflow/rules/aatrnaseq-process.smk
| Property | Value |
|---|---|
| Input | Staged POD5 directory (WarpDemuX: the split POD5), mod model sentinel |
| Output | bam/rebasecall/{sample}/{sample}.rbc.bam |
| GPU | Yes |
| Parameters | base_calling_model, opts.dorado, models_dir |
Command:
| Bash | |
|---|---|
1 | |
Notes:
- Depends on
download_mod_modelsrule to pre-download modification models - Respects
CUDA_VISIBLE_DEVICESenvironment variable - Default options include
--modified-bases pseU m5C inosine_m6A --emit-moves
bwa_idx¶
Build BWA index for reference FASTA.
File: workflow/rules/aatrnaseq-process.smk
| Property | Value |
|---|---|
| Input | Reference FASTA |
| Output | .amb, .ann, .bwt, .pac, .sa files |
Command:
| Bash | |
|---|---|
1 | |
Notes:
- Only runs once per reference
- Index files are stored alongside the FASTA
bwa_align¶
Align reads to the tRNA reference with BWA MEM, carrying dorado's tags through.
samtools fastq -T '*' writes every uBAM tag into the FASTQ comment and
bwa mem -C appends it to each aligned record, so the move table (mv, ns,
ts), the MM/ML modbase calls and RG arrive on the aligned BAM in one
streaming pass. No FASTQ is written and there is no separate tag-injection step.
File: workflow/rules/aatrnaseq-process.smk
| Property | Value |
|---|---|
| Input | Rebasecalled uBAM, EDX read-id list (EDX samples only), BWA index |
| Output | bam/aln/{sample}/{sample}.aln.bam, .bai, {sample}.rg.sam |
| Threads | 16 |
| Parameters | fasta, opts.bwa |
Command:
| Bash | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
Filtering:
-F 2324: Remove unmapped (0x4), reverse-strand (0x10), secondary (0x100) and supplementary (0x800) records
Notes:
-Hinserts the uBAM's own@RGlines withSM/LB/BCstamped, so the per-readRG:Z:that-Ccopies through resolves to a declared read group- On demultiplexed runs a constant
BC:Z:is added to every read via the FASTQ comment -K 100000000pins bwa's input batch at 100 Mbases regardless of thread count. The FASTQ comment is ~13x the read (the move table dominates), and bwa holds a batch plus its output in memory; pinning keeps that at a few GB where the default per-thread batch is what PR #86 saw OOM at 48 GB
Default BWA options:
-W 13 -k 6 -T 20 -x ont2d(RNA-optimized)
calmd¶
Recompute MD/NM against the reference so the aligned BAM carries an MD
tag (bwa mem does not emit one on its own). Required by the vendored-but-not-
yet-wired charging_tcn_sup6_rna004 bundle, which reconstructs its per-read
reference from MD rather than slicing the reference FASTA by coordinate.
File: workflow/rules/aatrnaseq-process.smk
| Property | Value |
|---|---|
| Input | Aligned BAM (bwa_align output), reference .fai |
| Output | bam/calmd/{sample}/{sample}.calmd.bam, .bai |
| Threads | 2 |
| GPU | No |
| Parameters | fasta |
Command:
| Bash | |
|---|---|
1 2 | |
Notes:
- Runs as its own pass right after alignment;
samtools calmdreads each record against its own reference span, so it needs no particular sort order - The per-record
MDcomputation is single-threaded —--threadsonly adds BGZF (de)compression workers, so this rule is worth a modest thread count, not a large one
classify_charging¶
Classify charged vs uncharged reads with escpod classify.
File: workflow/rules/aatrnaseq-process.smk
| Property | Value |
|---|---|
| Input | POD5 store (staged directory, split POD5, or raw LDX run), calmd BAM (with MD/NM), reference FASTA |
| Output | bam/charging/{sample}/{sample}.charging.bam, .bai, summary/tables/{sample}/{sample}.charging_calls.tsv.gz |
| Threads | 4 |
| GPU | Opt-in via charging.gpu (windowed/TCN bundle only; default bundles are CPU-only) |
| Parameters | charging.model, charging.min_mapq, charging.gpu |
Command:
| Bash | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
Output tags:
cl:round(P(charged) * 255), on every record the model scored; unscored records pass through untouched and are listed with areasonin the calls TSV
Notes:
- The POD5 argument is the sample's whole signal store, never a subset: classify looks each aligned read up by id, so reads the BAM does not name are never touched
add_adapter_tags¶
Detect adapter positions using parasail alignment and add PT tags to create final BAM.
File: workflow/rules/aatrnaseq-process.smk
| Property | Value |
|---|---|
| Input | Classified BAM |
| Output | bam/adapter_tagged/{sample}/{sample}.bam, .bai |
| Parameters | adapters.* config options |
Command:
| Bash | |
|---|---|
1 2 3 4 5 6 7 8 | |
PT tag format:
| Text Only | |
|---|---|
1 2 | |
Notes:
- Uses parasail Smith-Waterman alignment to find adapter positions
- Can infer 5' adapter presence from alignment position when adapter is truncated
- Output goes to
bam/adapter_tagged/; the downstreamfinalize_bamrule produces the final BAM atbam/final/
finalize_bam¶
Produce the final BAM for downstream analysis. Hardlinks the adapter-tagged BAM as the final output. EDX filtering happens before alignment: detect_edx_adapters / extract_edx_read_ids produce the read list bwa_align aligns.
File: workflow/rules/aatrnaseq-process.smk
| Property | Value |
|---|---|
| Input | bam/adapter_tagged/{sample}/{sample}.bam, .bai |
| Output | bam/final/{sample}/{sample}.bam, .bai |
Notes:
- Hardlinks the adapter-tagged BAM (zero-copy passthrough that survives
cascadecleanup) - This is the final BAM with all tags:
cl(charging),pt(adapters) andBC(barcode, demultiplexed runs only), plus dorado's MM/ML modbase tags - The header carries a valid
@RGwhoseSM/LB/BCare the pipeline's sample, run and barcode, with dorado'sIDand basecall-model provenance preserved
Charging Analysis Rules¶
get_cca_trna¶
Extract charging probability (CL tag) per read to TSV.
File: workflow/rules/aatrnaseq-charging.smk
| Property | Value |
|---|---|
| Input | Final BAM |
| Output | summary/tables/{sample}/{sample}.charging_prob.tsv.gz |
Command:
| Bash | |
|---|---|
1 | |
Output columns:
| Column | Description |
|---|---|
| read_id | Nanopore read identifier |
| tRNA | Aligned reference name |
| charging_likelihood | CL tag value (0-255) |
get_cca_trna_cpm¶
Calculate CPM-normalized charging counts per tRNA.
File: workflow/rules/aatrnaseq-charging.smk
| Property | Value |
|---|---|
| Input | Charging probability TSV |
| Output | summary/tables/{sample}/{sample}.charging.cpm.tsv.gz |
| Parameters | ml_thresh=200 (hardcoded) |
Command:
| Bash | |
|---|---|
1 2 3 4 | |
Classification:
- Score ≥ 200: Charged
- Score < 200: Uncharged
Output columns:
| Column | Description |
|---|---|
| tRNA | Reference name |
| counts_charged | Charged read count |
| counts_uncharged | Uncharged read count |
| cpm_charged | Charged CPM |
| cpm_uncharged | Uncharged CPM |
Quality Control Rules¶
compute_reference_similarity¶
Compute pairwise sequence similarity matrix for the reference FASTA.
File: workflow/rules/aatrnaseq-qc.smk
| Property | Value |
|---|---|
| Input | Reference FASTA |
| Output | summary/qc/reference_similarity.tsv, summary/qc/reference_similarity.clusters.tsv |
| Threads | 4 |
| GPU | No |
Command:
| Bash | |
|---|---|
1 2 | |
Identical sequences are collapsed before aligning (lossless). Gated by
qc.reference_similarity and skipped above qc.reference_similarity_max_seqs;
qc.reference_similarity_max_mismatch additionally collapses near-identical
sequences by Hamming distance.
Notes:
- Uses Needleman-Wunsch global alignment to compute all-vs-all pairwise similarity
- Percent identity = matches / max(len_seq1, len_seq2) * 100
- Identifies potential cross-mapping issues from homologous tRNA sequences
base_calling_error¶
Extract per-position basecalling error metrics.
File: workflow/rules/aatrnaseq-qc.smk
| Property | Value |
|---|---|
| Input | Final BAM, reference FASTA |
| Output | summary/tables/{sample}/{sample}.bcerror.tsv.gz |
Command:
| Bash | |
|---|---|
1 | |
Output columns:
| Column | Description |
|---|---|
| Position | Reference position |
| Coverage | Read coverage |
| A_Freq, T_Freq, G_Freq, C_Freq | Base frequencies |
| MismatchFreq | Mismatch rate |
| InsertionFreq | Insertion rate |
| DeletionFreq | Deletion rate |
| BCErrorFreq | Combined error rate |
| MeanQual | Mean base quality |
align_stats¶
Summarize alignment statistics across pipeline stages.
File: workflow/rules/aatrnaseq-qc.smk
| Property | Value |
|---|---|
| Input | Unmapped BAM, aligned BAM, classified BAM |
| Output | summary/tables/{sample}/{sample}.align_stats.tsv.gz |
Command:
| Bash | |
|---|---|
1 2 3 4 5 | |
Output columns:
| Column | Description |
|---|---|
| bam_file | Source BAM path |
| id | Sample identifier |
| info | Pipeline stage |
| n_reads | Total reads |
| pct_mapped | Percent mapped |
| mean_length | Mean read length |
| mean_bq | Mean base quality |
| mean_mapq | Mean mapping quality |
read_attrition¶
Report where the run's reads were lost, as one table.
File: workflow/rules/aatrnaseq-qc.smk
| Property | Value |
|---|---|
| Input | Per-sample align stats, anchor coverage, charging calls, demux summaries |
| Output | summary/read_attrition.tsv.gz |
Command:
| Bash | |
|---|---|
1 2 3 4 5 | |
Notes:
- Always produced
- The
aligned -> charge-calledgate is broken out by the model's ownreasoncolumn, so the loss is named rather than inferred
Modification Rules¶
bam_to_coverage¶
Generate BedGraph coverage tracks.
File: workflow/rules/aatrnaseq-modifications.smk
| Property | Value |
|---|---|
| Input | Final BAM |
| Output | summary/tables/{sample}/{sample}.{cpm,counts}.bg.gz (protected) |
| Threads | 4 |
| Parameters | opts.coverage |
Command:
| Bash | |
|---|---|
1 2 3 | |
modkit_pileup¶
Generate per-site modification consensus.
File: workflow/rules/aatrnaseq-modifications.smk
| Property | Value |
|---|---|
| Input | Final BAM |
| Output | summary/modkit/{sample}/{sample}.pileup.bed.gz |
| Parameters | fasta, modkit thresholds |
Command:
| Bash | |
|---|---|
1 | |
modkit_extract_calls¶
Extract per-read modification calls.
File: workflow/rules/aatrnaseq-modifications.smk
| Property | Value |
|---|---|
| Input | Final BAM |
| Output | summary/modkit/{sample}/{sample}.mod_calls.tsv.gz |
| Memory | 50 MB per MB of input BAM, floor 8 GB (Slurm; measured ~35-39 GB per GB) |
| Parameters | fasta, modkit thresholds |
Command:
| Bash | |
|---|---|
1 2 3 4 5 6 7 | |
modkit_extract_full¶
Export comprehensive modification information.
File: workflow/rules/aatrnaseq-modifications.smk
| Property | Value |
|---|---|
| Input | Final BAM |
| Output | summary/modkit/{sample}/{sample}.mod_full.tsv.gz |
| Threads | 4 |
| Memory | 50 MB per MB of input BAM, floor 8 GB (Slurm; same slope as modkit_extract_calls) |
Command:
| Bash | |
|---|---|
1 2 3 4 5 6 7 8 | |
Utility Rules¶
generate_squiggy_session¶
Generate a Squiggy session JSON file for loading pipeline outputs in Positron IDE.
File: workflow/rules/common.smk
| Property | Value |
|---|---|
| Input | All final BAMs, all merged POD5s, reference FASTA |
| Output | squiggy-session.json (at output root) |
| GPU | No |
Command:
| Bash | |
|---|---|
1 2 3 4 5 | |
Notes:
- Generates absolute paths to POD5, BAM, and FASTA files for each sample
- Computes MD5 checksums for file integrity verification
- Includes default plot options for the Squiggy viewer (eventalign mode, z-normalization)
Odds Ratio Rules¶
compute_odds_ratios¶
Compute per-tRNA pairwise modification odds ratios.
File: workflow/rules/aatrnaseq-odds-ratios.smk
| Property | Value |
|---|---|
| Input | Modkit extract calls TSV, charging probability TSV |
| Output | summary/tables/{sample}/{sample}.odds_ratios.tsv.gz |
| Parameters | odds_ratios.ml_threshold (default: 200), odds_ratios.min_coverage (default: 10) |
Command:
| Bash | |
|---|---|
1 2 3 4 5 6 | |
Notes:
- For each tRNA, tests whether modification at position X is correlated with modification at position Y (and with charging status) via 2x2 contingency tables
- Uses Haldane correction for zero cells and Fisher's exact test
- Applies BH correction across all results
- Charging status is represented as position 999
Output columns:
| Column | Description |
|---|---|
tRNA |
Reference tRNA name |
pos1 |
First position |
pos2 |
Second position (999 = charging) |
n00, n01, n10, n11 |
Contingency table counts |
total_obs |
Total observations |
odds_ratio |
Odds ratio |
log_odds_ratio |
Log odds ratio |
se_log_or |
Standard error of log OR |
ci_lower, ci_upper |
95% confidence interval |
fisher_or |
Fisher's exact test OR |
p_value |
Fisher's exact test p-value |
p_adjusted |
BH-adjusted p-value |
Report Rules¶
render_combined_qc_report¶
Render a combined Quarto QC report with per-sample tabs.
File: workflow/rules/aatrnaseq-report.smk
| Property | Value |
|---|---|
| Input | Alignment stats, charging probabilities, charging CPM, basecalling errors (all samples) |
| Output | reports/qc_report.html |
| Parameters | ml-threshold, report.custom_include |
Command:
| Bash | |
|---|---|
1 2 3 4 | |
Notes:
- Requires the
reportpixi environment:pixi run -e report snakemake render_combined_qc_report - Generates faceted QC plots with per-sample patchwork tabs
- Supports optional custom Quarto include via
report.custom_includeconfig
Demultiplexing Rules¶
See Demultiplexing for detailed documentation.
warpdemux¶
Run WarpDemuX barcode prediction.
| Output | demux/warpdemux_output/{run_id}/ |
parse_warpdemux¶
Parse predictions to barcode mapping file.
| Output | demux/read_ids/{run_id}/barcode_mapping.tsv.gz |
extract_sample_reads¶
Filter read IDs for specific sample's barcode.
| Output | demux/read_ids/{sample}.txt |
split_pod5¶
Split merged POD5 by sample using read ID list.
| Output | demux/pod5/{sample}.pod5 |
detect_edx_adapters¶
Detect 3' adapter identity per read on unaligned BAM (before alignment). Only runs for EDX samples.
| Output | demux/edx/{sample}/{sample}.edx_adapters.tsv.gz |
extract_edx_read_ids¶
Extract read IDs matching the sample's EDX adapter assignment.
| Output | demux/edx/{sample}/{sample}.edx_read_ids.txt |
edx_concordance¶
Build concordance table of WDX vs EDX adapter identity from adapter detection TSVs.
| Output | summary/edx/edx_concordance.tsv.gz |
Rule Dependencies¶
flowchart LR
stage_pod5 --> rebasecall
rebasecall --> bwa_align
rebasecall --> detect_edx_adapters
detect_edx_adapters --> extract_edx_read_ids
extract_edx_read_ids -.-> bwa_align
bwa_align --> calmd
calmd --> classify_charging
stage_pod5 --> classify_charging
classify_charging --> add_adapter_tags
add_adapter_tags --> finalize_bam
finalize_bam --> get_cca_trna
finalize_bam --> base_calling_error
finalize_bam --> align_stats
finalize_bam --> bam_to_coverage
finalize_bam --> modkit_pileup
finalize_bam --> modkit_extract_calls
get_cca_trna --> get_cca_trna_cpm
get_cca_trna --> compute_odds_ratios
modkit_extract_calls --> compute_odds_ratios
finalize_bam --> generate_squiggy_session
stage_pod5 --> generate_squiggy_session
finalize_bam --> compute_reference_similarity
align_stats --> render_combined_qc_report
get_cca_trna --> render_combined_qc_report
get_cca_trna_cpm --> render_combined_qc_report
base_calling_error --> render_combined_qc_report
Note: Dashed lines (-.->) indicate conditional paths. For EDX samples,extract_edx_read_idsbounds whatbwa_align` aligns; every other sample aligns its whole uBAM.