Skip to content

Releases: scholl-lab/plasmicheck

v0.43.0

Choose a tag to compare

@berntpopp berntpopp released this 20 Oct 06:33

Performance (#139, #140)

Heavily contaminated samples are much faster:

  • Per-base depth: computed with samtools depth instead of pysam count_coverage. On the HPC this took 503 s per call, 3 calls per construct, and now takes 3.3 s.
  • Junction lookup: binary search over the sorted junction positions in _scan_plasmid_bam.
  • Streaming comparison: mate keys and pairing are computed once per read group.
  • Local benchmark (1.8 M plasmid reads): compare_alignments 34.2 s → 16.8 s.
  • Unchanged: reads_assignment.tsv and the scan counts are byte-identical.
  • Depth convention: depth now counts N bases as covered (samtools convention). On a heavy real sample the relative change is 2.6e-5.

Feature (#138)

  • --minimap2-threads / config minimap2_threads: minimap2 threads per alignment.
  • New default: each of the two concurrent alignments gets threads // 2. Before, it was 1 thread of 4.

v0.42.3

Choose a tag to compare

@berntpopp berntpopp released this 20 Oct 04:37

Fix: f_junction now averages spliced reads per junction (#136, #137). Before, multi-exon constructs had an inflated f_plasmid and false plasmid_flag=positive calls. Rerun the sample scans to refresh the stored f_junction/f_plasmid values.

v0.42.2 — fast cohort scans: shared construct cache, seeded target-BED depth

Choose a tag to compare

@berntpopp berntpopp released this 19 Oct 20:24
  • perf(cohort): prepare_constructs builds the spliced-alignment cache with the same GTF, padding and shift settings as scan_sample, so scans hit the cache and never load the whole-genome index. The cache refreshes when the GTF changes (#133, #134).
  • perf(depth): the sample median depth for --target-bed uses samtools bedcov -j on a seeded random subsample of target intervals (--target-bed-max-intervals, default 5000, 0 = all; --target-bed-seed, default 42), kept in BED order. This replaces the pure-Python base-level pass over every target.
  • fix: --option=value overrides, an empty GTF, and depth-definition parity (quality_threshold=0).
  • BIH benchmark (real exome BAM, 17 constructs, 8 threads): 4:28 per sample at 173 MB, versus more than 70 min (unfinished) on v0.42.1.

v0.42.1 — schema declares target_bed, gtf_file, vcf_file

Choose a tag to compare

@berntpopp berntpopp released this 19 Oct 06:10
  • fix(snakemake): config.schema.yaml now declares the v0.42.0 keys target_bed, gtf_file and vcf_file (plus the gtf, mane_gtf and vcf aliases), documented in the README and the example config (#131, #132).

v0.42.0

Choose a tag to compare

@berntpopp berntpopp released this 18 Oct 23:48
  • feat(junctions): --gtf <MANE/Ensembl.gtf[.gz]> resolves exon-exon junctions from reference transcript models (_load_gtf_transcripts, _resolve_gtf_exons), clipping terminal overlapping exons and spurious 3' vector introns, writing MapExonLengths/GTFExonLengths, and bumping the spliced cache key to :v4 (#125).
  • feat(compare): depth-normalised plasmid excess fraction (compute_f_excess, compute_f_junction, compute_f_plasmid, compute_bed_median_depth, --target-bed, --dp-sample-median, --dp-locus, --r-cohort) and cohort r_cohort re-estimation (#126).
  • feat(variants): --MD spliced alignment (GenomicIntrons, ConstructVariants SNV/MNV extraction) and construct-agnostic --vcf variant flagging engine (flag_vcf_variants, load_summary_rows_for_flagging) detecting construct_allele, cdna_junction_artefact, disjoint construct_allele_cooccurrence, construct_allele_ad_ratio, and plasmid_explainable_vaf while isolating normal -N samples (#127).
  • feat(summary): combined per-sample×construct plasmid_flag (positive / weak / negative) in verdict_table.tsv (compute_plasmid_flag, _add_plasmid_flag) (#128).
  • feat(extract/scale): samtools view -u -M ... "*" + samtools fastq -n -F 0x900 region extraction with auto-derived spliced regions, $TMPDIR sample_temp_fastq isolation, lock-free MD5 precomputation, read-only cache hits without manifest rewrites, and hostname-scoped temp index paths (#124, #129).

v0.41.0 — Config-driven cohort Snakemake workflow and region-restricted extraction

Choose a tag to compare

@berntpopp berntpopp released this 18 Oct 23:22
  • feat(snakemake): config-driven cohort workflow (#129, #130): sample sheet / mapping / BAM list inputs, constructs list, per-rule SLURM resources, schema-validated config; one BAM extraction per sample against all constructs; references prepared once into the shared content-addressed cache.
  • feat(extract): --regions <BED> and --include-unmapped restrict extraction to construct-gene regions plus unmapped reads (#124).
  • fix: explicit --sample-name (no basename collisions), outputs verified before a sample is marked done, cohort summaries from an explicit manifest (no stale results), {sample} wildcard constrained to configured IDs.
  • test/ci: end-to-end Snakemake cohort run on the synthetic fixture (verdicts asserted) runs in CI with real minimap2/samtools/Snakemake.

v0.40.0 — Offline IGV.js 3.0.2 Inspector, Full-BAM bedGraph Depth & Unified Cohort Summary Tables

Choose a tag to compare

@berntpopp berntpopp released this 18 Oct 22:21

Highlights (v0.40.0)

  • Embedded Offline IGV.js 3.0.2 Pileup Inspector: Self-contained interactive genome browser inside single-sample reports (plasmicheck/static/js/igv-3.0.2.min.js.gz), featuring one-click locus navigation buttons (Full Construct, 5' V–I Junction, 3' I–V Junction, Insert Region, and individual cDNA Splice Junctions).
  • Exact Full-BAM bedGraph Coverage + Stratified PC-Tagged Alignment Pileup:
    • Computes exact per-base RLE bedGraph coverage tracks across 100% of primary reads (Plasmid, Tied, Backbone_Only) so visual coverage height always matches the exact BAM depth without downsampling bias.
    • Injects the custom SAM tag PC:Z:<Category> (Plasmid, Tied, Backbone_Only, Human) into a stratified subset BAM (<=1,200 reads prioritizing junction-spanning, exon-intron boundary, and backbone reads) colored by category (colorBy: 'tag', colorTable).
    • Adds a Human Spliced Alignment (N introns) track displaying N-CIGAR intron-spanning arcs mapped back onto plasmid insert coordinates, plus an Exon–Exon cDNA Junctions BED track.
  • Unified Interactive Cohort Summary Tables (pc-cohort-table):
    • Replaced all legacy Pandas .to_html() tables in the Cohort Summary Report with a single unified pc-cohort-table component across Sample × Plasmid Screening Results, Splice Junction & Boundary Evidence, and Backbone Resistance & Reporter Markers.
    • Added instant search filtering, verdict filter pills (All / Contaminated / Unclear / Clean), live row count badges, click-to-sort column headers, semantic verdict pills, right-aligned tabular numbers, and direct Open → links to single-sample reports.
    • Distilled report copy, unified visual hierarchy, and removed redundant duplicate raw DataFrame tables from the HTML view while preserving all .tsv and .xlsx exports.
  • Inline UMI Terminal Soft-Clip Tolerance: Relaxed terminal soft-clip filtering on splice-junction reads (<= 6 bp at read ends) to prevent false negatives on libraries with inline UMI/barcode overhangs.
  • CI & Packaging Hardening: Added hermetic wheel/sdist installation and resource verification in make smoke-package including igv-3.0.2.min.js.gz.

v0.39.0 — Circular Scoring, Junction/Bridge Metrics, Contamination Estimator, IGV Session, Anonymize & Simulator

Choose a tag to compare

@berntpopp berntpopp released this 18 Oct 19:45

Highlights (v0.39.0)

  • Alignment Scoring & Tie-Breaking (#120): Removed unconditional origin boost and per-read mate bonus; added opposite-end SA support validation (NM <= 2), circular-aware fragment mate bonus (0 < span <= 1000), and symmetric strand-aware MAPQ tie-breaking guarded against erasing mate bonuses.
  • Vector-Insert Junction & Bridge Pair Evidence (#121): Fixed wrapped-insert inside span calculation; added VectorInsertJunctionReads (>=10 bp anchor, NM <= 2) and circular-aware VectorInsertBridgePairs to .summary.tsv and reports.
  • Splice-Junction Event Counting & Contamination Estimator (#122): Added per-junction SpliceJunctionEvents (>=15 bp anchor), ExonIntronBoundaryReads (+-2 bp soft-clip with exon anchor check), primary-read depth callback, and EstimatedContaminationFraction.
  • Verdict Threshold Propagation & Plasmid Exon CIGAR Fix (#123): Fixed plasmid exon length CIGAR accumulation (op in (0, 1, 7, 8)), bumped spliced cache version (:v2 -> :v3), and unified verdict_bounds / categorize_value across comparison, reports, and Plotly/Matplotlib boxplots.
  • Pipeline Caching, Atomic FAI & Per-Sample Collation Scoping (#119): Cached spliced_reference.fasta indexes (.mmi/.fai), deduplicated per-plasmid preparation across samples, added atomic .fai writes with >0 size checks, scoped temp BAM/FASTQ files with try...finally cleanup, and hardened snakemake/plasmicheck.smk.
  • Config & Report Cleanup (#118): Removed dead config keys and constants, deduplicated ensure_plotly_assets, and simplified read_compare_outputs() to return a single DataFrame.
  • In-Silico Contamination Simulator (#117): Added standalone scripts/simulate_contamination.py supporting spike-in and de-novo circular multi-exon simulation with biophysical capture retention.
  • IGV Session Generation (#49): Added portable relative-path igv_session.xml output when --keep_intermediate is enabled (also closes #6).
  • Privacy Anonymization (#5): Added --anonymize flag hashing ReadID via keyed BLAKE2b (digest_size=8), forcing keep_intermediate=False, and redacting paths in reports.
  • Issue Housekeeping (#44, #6): Closed #44 and #6 as not planned per their Ponytail reviews.

v0.38.0 — Scientific Accuracy, Pipeline Speed & Report UI/UX

Choose a tag to compare

@berntpopp berntpopp released this 16 Oct 06:18
b3ee416

Highlights in v0.38.0 (including v0.35.0–v0.38.0 improvements)

Scientific Accuracy

  • Paired-End BAM Collation & Mate Scoring (#102, #115): Coordinate-sorted BAM inputs are now collated once per sample (samtools collate -u -O | samtools fastq -F 0x900 -) and aligned with interleaved paired-end mode (minimap2 -ax sr -p), restoring 100% read pairing and matching paired FASTQ ratios.
  • Boundary Off-by-One Fix in CoverageOutsideINSERT (#115): Fixed read_end - 1 > insert_end comparison between 0-based exclusive read.reference_end and 0-based inclusive insert_end, eliminating false outside-insert coverage on clean samples.
  • MAPQ Asymmetry & Circular Origin Scoring (#101, #103, #115): Excused soft-clipping at circular plasmid origin boundaries (0 / plasmid_length) and tied reads with identical CIGAR and NM when MAPQ = 60 on plasmid vs 48 <= MAPQ < 60 on the larger human spliced reference.
  • Minus-Strand & Origin-Wrapping cDNA Extraction (#103, #106, #108): Fixed query-coordinate extraction on reverse-complemented alignments, merged overlapping human genomic regions, added SpliceJunctionReads / SpliceJunctionsCovered metrics for sub-threshold cDNA detection, and added binary .xdna origin-wrapping fallback.

Speed & Concurrency

  • 2.27× Faster compare_alignments & 3.88× Faster Batch Runs (#104, #105, #115): Streamed samtools sort -N -u directly from minimap2 for human alignments, combined outside-insert/mismatch/splice-junction scanning into a single pass over plasmid_alignment.bam, hoisted plasmid preparation out of the sample loop, and ran plasmid + human alignments concurrently.
  • 768× Faster Summary Report Tables & Vectorized LOO t-tests (#109, #115): Replaced iterative DataFrame filtering in create_resistance_gene_table with a single O(N) lookup and vectorized leave-one-out one-sample t-tests with scipy.stats.false_discovery_control.
  • Thread-Safe Cache & Atomic Indexing (#104, #107): Added FileLock around CacheManager manifest operations and atomic .mmi creation.

Report UI/UX & Plotting

  • Clinical-Genomics HTML Reports & Non-Overlapping Contamination Scale (#110, #115): Redesigned single-sample and cohort summary reports with equal-width 3-zone Contamination Scale (Clean <0.6, Unclear 0.6–1.0, Contaminated >1.0), boundary ticks, CSS hover tooltips, full-width responsive Plotly containers, and publication-grade Matplotlib static figures.

v0.34.1 — Reproducible tooling and pipeline fixes

Choose a tag to compare

@berntpopp berntpopp released this 15 Oct 13:24
20e6389

Fixes

  • Match BAM read-name sorting to streaming comparison order, preventing duplicate or incorrect assignments for numeric read names.
  • Forward custom pipeline thresholds consistently to comparison and reporting.
  • Add the missing spliced --cDNA_output option.
  • Quote alignment arguments and propagate upstream pipeline failures with Bash pipefail.
  • Update pysam to fix Python 3.13 coverage compatibility.

Development and delivery

  • Use the uv lockfile consistently in local commands, hooks, CI, and Docker.
  • Add concise agent guidance and enforce a 70% statement/branch coverage floor.
  • Test Python 3.10, 3.12, and 3.13, installed distributions, workflow syntax, and Docker.
  • Require passing CI and matching version tags before publishing container images.

Alignment requires Bash and samtools >=1.19. Python >=3.10 remains supported.

Validation: 436 tests passed per Python version, with 14 optional-reference tests skipped; full-suite statement/branch coverage is 82.14%. All PR CI checks passed.

Changes: #95