Skip to content

4.0.0 - #1452

Merged
WardDeb merged 397 commits into
masterfrom
4.0.0
Sep 5, 2026
Merged

4.0.0#1452
WardDeb merged 397 commits into
masterfrom
4.0.0

Conversation

@WardDeb

@WardDeb WardDeb commented Sep 4, 2026

Copy link
Copy Markdown
Member
  • new Rust-backed core for bamCoverage, bamCompare, computeMatrix, alignmentSieve and multiBamSummary (rayon multithreading, bigtools-based bigWig I/O), replacing the pure-Python implementations for these five tools; the previous Python implementations remain available as bamCoverage_old, bamCompare_old, computeMatrix_old, alignmentSieve_old and multiBamSummary_old during the transition, but will be removed in a future release
  • gzipped GTF/BED region files are supported in multiBamSummary, computeMatrix and alignmentSieve; gzipped blacklist files are supported in all five Rust-backed tools (multiBamSummary, computeMatrix, alignmentSieve, bamCompare, bamCoverage)
  • --exactScaling is removed as this is the only scaling option available with the new backend
  • --ignoreDuplicates has been removed from the bamCoverage and bamCompare tools. Duplicate reads can be removed via the --samFlagExclude option (assuming the provided BAM file has duplicate reads marked)
  • plotPCA re-implemented with a lightweight scipy/numpy SVD backend. Proper handling of --transpose, --log2/--rowCenter and --ntop options.
  • plotly backend removed entirely; plotCorrelation, plotPCA, plotHeatmap, plotProfile and plotEnrichment now use matplotlib, with a new optional --ggplot theme, and computeGCBias's --plotFileFormat plotly option has also been removed
  • removed the standalone cm.py colormap module; colormap handling now lives in the plotting tools directly
  • plot labels now show sample names only per default (dropped .filtered.bam/.bed suffixes)
  • prebuilt wheels now cover Linux manylinux_2_28 and musllinux_1_2 (x86_64 + aarch64) and macOS (Intel + Apple Silicon), built via maturin
  • CI overhauled: pytest/rust/planemo test workflows split up (test_pytest.yml, test_rust.yml, test_planemo.yml), zizmor hardening for GitHub Actions, dependabot enabled
  • extensive new pytest/cargo test coverage across the Rust-backed tools and plotCorrelation/plotPCA/plotFingerprint data outputs
  • --nanAfterEnd doesn't rescale the inner region anymore in reference-point mode
  • BED output doesn't show wrong blockstart values anymore
  • blacklist filtering is done at bp level instead of genome chunk level for rewritten tools
  • alignmentSieve output order matches input order exactly
  • --missingDataAsZero no longer takes bases exceeding chromosome bounds as 0 values but rather purges the bins
  • large scale values precision slightly altered with new backend (f32 vs f64)

Related issues:
Closes #1423, gzip support included for sort arm
Closes #1422, should be fixed (though not explicitly tested)
Closes #1421, single output stream for alignmentSieve
Closes #1384, fixed
Closes #1333, plotly backend is deprecated
Closes #1195, Closes #662, performance optimized
Closes #1194, regions should be respected strictly now
Closes #1180, Closes #1093, Closes #1088, alignmentSieve works with new back-end
Closes #1144, closes #1030
Closes #1140, multiprocessing no longer used in computeMatrix
Closes #1108, Closes #1130 fixed
Closes #1094, no longer relevant
Closes #1074, no longer relying on pysam
Closes #955, no longer relevant.
Closes #729

WardDeb and others added 27 commits April 23, 2025 15:56
build: cargo deps overhaul
build: cap htslib/rust-htslib -> build issues
test: update pytests to accomodate new mpl
test: dependabot for versions
test: pin mpl version to avoid hitting png differences
build: minimal python 3.12
test: fix planemo tests under latest MPL
test: planemo test to galaxy version 26
ci: boost action runner versions
* Added pytest for plotcorrelation

* Add missing file

* relaxed size tolerance

* Replace file size test with compare image

---------

Co-authored-by: Saim Momin <mominsaim12@gmail.com>
Salvaged from #1369: keeps only the computeMatrix test, which passes
against the current Rust bindings. The alignmentSieve, bamCompare and
bamCoverage tests from that PR were dropped because their Rust function
signatures have since changed (and alignmentSieve2 is not yet wired up
on 4.0.0).

Co-authored-by: gerikson <galina.erikson@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Both existing tests only compared the rendered PNG. Adds numeric
assertions on the tabular outputs, filling gaps found while triaging
the stalled #1372/#1374 tests:
- plotPCA: verify --outFileNameData (the existing test passed this flag
  but the check was commented out). Asserts the sign-independent
  eigenvalue column and table shape.
- plotFingerprint: verify --outQualityMetrics + --JSDsample (AUC and
  JS Distance), neither previously tested anywhere.

Expected values derived by running the current tools; verified with
`pixi run pytest`.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…t/strand filtering (#1434)

Fills coverage gaps identified while triaging the stalled #1369 tests:
- bamCoverage: --normalizeUsing RPKM (RPKM was untested; suite only had
  CPM/RPGC) and --scaleFactor.
- alignmentSieve: --minFragmentLength/--maxFragmentLength and
  --filterRNAstrand (neither was tested anywhere).

Expected values derived by running the current tools; all pass under
`pixi run pytest`.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Compute PCA with scipy instead of scikit-learn

Replace the sklearn PCA and StandardScaler in Correlation.plot_pca with a
scipy/numpy SVD implementation, reproducing sklearn's output (column
standardization with population std, deterministic svd_flip sign convention,
explained_variance_ from singular values). Drop the now-unused pandas and
scikit-learn dependencies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix transpose, log2/rowCenter, and small-ntop bugs in plot_pca; add PCA tests

The scipy/SVD PCA rewrite inherited three pre-existing plot_pca bugs from
the sklearn version:

- --transpose crashed with a shape mismatch (np.dot(m, Wt.T)); U*S already
  gives sample projections, so orient as (components, samples) via Wt.T.
- --log2 / --rowCenter were no-ops: they mutated self.matrix after m had
  been copied during ntop filtering. Now applied to a float copy before
  variance filtering.
- --ntop below the sample count crashed the scatter with IndexError; guard
  with a clear sys.exit instead.

Adds test_plotPCA.py coverage (sign-invariant coordinate/eigenvalue
regressions, ntop behavior, transpose, CLI validation exits) that passes
against both the sklearn and scipy implementations.

* Make plotPCA coordinate test portable across BLAS backends

test_plotPCA_default_coordinates failed on macOS CI: after PC1 the
untransposed eigenvalues are near-degenerate, so the eigenvectors rotate
freely and np.argpartition breaks top-ntop variance ties differently on
Accelerate vs OpenBLAS, making per-feature coordinates non-reproducible.
Replace it with test_plotPCA_default_eigenvalues, asserting only the
portable eigenvalues; coordinate-level regression stays covered by the
well-separated transpose case (test_plotPCA_transpose).

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The second plotPCA test compared the PCA tabular output with an exact
diff. Its duplicate-sample column is mathematically zero and comes out
as tiny, BLAS/platform-dependent noise (~1e-18), which failed the diff
in CI. Replace the exact compare with assert_contents pinning structure,
the stable PC1 coordinates, and the leading eigenvalue.
* boost rust edition, pin pyo3 together with minimal python version
* fix set_bad deprecation mpl
* set mpl defaults
* alignmentsieve rust implementation
* drop hardcoded /tmp in pytests in favor of tempfile
* cramfile ref included for pytest/planemo test

---------

Co-authored-by: Mohit Navandar <133376879+NavandarM@users.noreply.github.com>
some optimizations on computematrix / mbs
start exhaustive testing of computematrix module - reference point
collect computematrix tests in one place
- Add zizmor pre-commit hook (.pre-commit-config.yaml)
- Pin all GitHub Actions to commit SHAs (unpinned-uses)
- Add persist-credentials: false to checkout steps (artipacked)
- Add minimal top-level permissions to workflows (excessive-permissions)
* tests

* Fix stale plot baselines, support matplotlib 3.10.5+

Several baseline PNGs weren't regenerated after the dpi/rcParams
change in matplotlib_defaults.py, breaking image comparison tests
even on the pinned mpl 3.11. Regenerated them and bumped tolerances
for cross-version antialiasing drift.

Loosened the mpl pin from ==3.11 to >=3.10.5,<3.12 since 3.10.0-3.10.4
have a Path.__deepcopy__ RecursionError on Python 3.14.

* Regenerate plotHeatmap ggplot baseline for matplotlib 3.11.1

bbox_inches='tight' makes the --ggplot heatmap's saved size depend on
exact text/legend extents, which shifted by 15px in height between
3.11.0 and 3.11.1. CI resolves the newest matching matplotlib via pip
(3.11.1), so pin the baseline there. Pixel dimension mismatches can't
be absorbed by tolerance since compare_images requires exact size.

* Regenerate stale Galaxy wrapper test baselines

Same root cause as the pytest suite: the matplotlib_defaults.py dpi
rewrite changed every plot's pixel output, but galaxy/wrapper/test-data
baselines were never regenerated. planemo's sim_size comparison was
failing size deltas of roughly 2x on plotPCA, plotCorrelation,
plotCoverage, plotEnrichment, plotFingerprint, plotHeatmap, and
bamPEFragmentSize. Regenerated all of them by replaying each tool's
<test> block CLI args directly.

* Widen Galaxy wrapper sim_size deltas for remaining plot tests

plotCorrelation, plotCoverage, plotEnrichment, and plotHeatmap still
failed planemo's byte-size comparison after the baseline regen: CI's
actual output is consistently 5-15% larger than what's reproducible
locally, in a way that doesn't respond to CLI-arg fixes (some outputs
are byte-identical before and after). Two separate CI runs produced
identical actual byte counts, so this is a stable environmental
difference (matplotlib patch version), not flakiness - widen delta to
give it headroom rather than chase an exact match.

Also corrected plotCorrelation's test invocation to use the real
Galaxy default corMethod (spearman, not pearson).

* Drop bbox_inches='tight' from plotHeatmap savefig

The figure already has an explicit figsize and constrained_layout, so
the tight-bbox recrop was redundant - and it was also the actual
source of the plotHeatmap_ggplot size drift between matplotlib patch
versions (finding C), since it recomputes the crop from rendered
text/legend extents that shift slightly release to release. Confirmed
output dimensions are now identical (393x2519) under both 3.11.0 and
3.11.1, so pixi's conda-resolved matplotlib and CI's pip-resolved
matplotlib no longer need to match exactly for this test to pass.

Regenerated the four affected baselines (pytest + galaxy wrapper).

* Widen plotHeatmap Galaxy wrapper deltas after bbox_inches fix

Dropping bbox_inches='tight' changed the output size for both
heatmapper tests (not just the ggplot one), so result2's previously-
fine delta now also needs headroom for the same environmental
rendering drift documented for the other Galaxy wrapper tests.

* Drop argparse.FileType in favor of path validation + explicit open()

Python 3.14's argparse.FileType.__init__ now emits a
PendingDeprecationWarning on every construction, which fired once per
parser build across the test suite (58 warnings). Every FileType
usage in this codebase only ever consumed the '.name' attribute or
passed the handle straight into a single write call, so none of it
needed an eagerly-opened handle at parse time.

Added parserCommon.readableFile alongside the existing writableFile
as a path-validating argparse type, switched all 8 FileType(...)
call sites to the appropriate one, and open() explicitly at the
point of use for the handful of writes that need a real file object
(save_BED). Down to 2 warnings suite-wide (an unrelated scipy one).
 exhaustive testing for multibamsummary, and computematrix (scale-regions/refpoint). Edge cases (chromosome boundaries, filtering, blacklist) taken care of.
* gz bed/gtf and test

* gz blacklist testcase

* test matrix planemo

* planemo test defaults

* include channels in planemo action

* include panic message over bare unwraps
* update changelog

* mend

* docs orphan for warnings

* drop doc reqs, fix python docstring

* drop unused code from new entrypoints

* point rtd to docs req

* drop mpl from action reqs

* action to test docs

* minimal versions, include lock

* centralize version check deeptools/galaxy, rust version in docs/deeptools

* include authors

* ensure rust in rtd yaml is an allowed rust version

* cleanup readme, https

* docs overhauls, remove plotly refs, update parser

* rust 1.87 minimum

* ignore venv

* move pytest action over to pixi

* pip as a pixi dep

* of course dist upload needs mussllinux builds

* set stack min for osx build in pixi env

* up stack

* 100MB stack for osx build ?

* strip wheels, cap rust version to avoid conda-forge rust build error for osx

* https in docs, clarify installation instructions, delete rst
@WardDeb
WardDeb merged commit 0693cc4 into master Sep 5, 2026
74 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment