Changelog#

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[2.11.2] - 2026-06-22#

Fixed#

  • CRITICAL: 4 remaining dead deprecation handlers removed that v2.11.1 missed:

    • loaders/third_party/straw.py:194 (run_straw)

    • resolution_enhancements/datasets/csr.py:78-93 (CMCSRDataset docstring + body)

  • metrics/reconstruction/n_way_interactions.py:130, 139: Internal calls to loaders.load_cm_data(...) still used resolution=bin_size_bp * ds_ratio — now use bin_size_bp=bin_size_bp * ds_ratio.

  • cli/loaders.py:95, 96, 125: CLI commands get-bins and get-balancing referenced an undefined resolution variable after v2.11.0’s parameter rename. Now use bin_size_bp. These CLI commands were completely broken in v2.11.1 (NameError on invocation).

  • cli/_discovery.py:45: if bin_size_bps:if resolutions: (typo bug with undefined variable).

  • Stale docstring entries removed from reconstructions/implementations/{h3dg, flamingo, shneigh, superrec}.py documenting a resolution parameter that no longer exists.

  • User-facing documentation updated in docs/source/{quickstart,getting_started}.md and docs/source/user_guide/{root,loaders,converters,datasets,normalization, reconstructions,pipeline}.md — all resolution= kwargs in code examples replaced with bin_size_bp= (30 occurrences) and cm.resolution attribute access replaced with cm.bin_size_bp (2 occurrences).

  • tutorial_29_multimodal.ipynb: cm.resolution attribute access fixed.

Deprecated#

  • get_resolutions() function name renamed to get_bin_size_bps(). The old name is preserved as a deprecated alias that emits DeprecationWarning and forwards to the canonical name. Will be removed in v2.13.0 (2 minor versions of deprecation per the project’s standard policy).

  • CLI command gunz-cm loaders get-resolutions renamed to gunz-cm loaders get-bin-size-bps. The old command is preserved as a hidden deprecated alias that prints a warning. Will be removed in v2.13.0.

Migration from v2.11.1#

No code changes required for users. The deprecated get_resolutions() and gunz-cm loaders get-resolutions continue to work but emit warnings. Switch to get_bin_size_bps() and gunz-cm loaders get-bin-size-bps at your earliest convenience.

# v2.11.1 (still works, deprecated)
from gunz_cm import get_resolutions
sizes = get_resolutions("data.mcool")

# v2.11.2 (canonical)
from gunz_cm import get_bin_size_bps
sizes = get_bin_size_bps("data.mcool")
# v2.11.1 CLI (still works, deprecated)
gunz-cm loaders get-resolutions data.mcool

# v2.11.2 CLI (canonical)
gunz-cm loaders get-bin-size-bps data.mcool

[2.11.1] - 2026-06-22#

Fixed#

  • CRITICAL: 11 dead deprecation handlers removed from public API functions. The v2.11.0 release shipped with deprecation handler blocks (the 7-line if resolution is not None: warnings.warn(...) pattern) remaining in 11 public functions where the resolution parameter had been removed from the signature. This caused NameError: name 'resolution' is not defined at runtime when callers passed resolution=... through the load_cm_data facade (which uses **kwargs and bypasses pydantic’s @validate_call boundary).

    Affected functions (all now correctly reject resolution= with TypeError / ValidationError instead of NameError):

    • get_bins (loaders/init.py + cool_loader.py)

    • get_balancing (loaders/init.py)

    • load_cm_data (loaders/init.py)

    • load_cooler, _load_cooler_data (cool_loader.py)

    • load_csv, _load_csv_data (csv_loader.py)

    • load_ginteractions (ginteractions_loader.py)

    • load_narrowpeak (narrowpeaks.py)

    • load_pickle, _load_pickle_data (pickle_loader.py — _load_pickle_data parameter rename resolutionbin_size_bp)

    • convert_to_gzcm (converters/gzcm.py)

    • build_straw_args, run_straw (loaders/third_party/straw.py)

    • gen_h3dg_coo, comp_h3dg_obj_perf, parse_h3dg_mapping, load_h3dg_points (reconstructions/implementations/h3dg.py)

    • gen_shneigh_coo, comp_shneigh_obj_perf (reconstructions/implementations/shneigh.py)

    • gen_superrec_coo, comp_superrec_obj_perf (reconstructions/implementations/superrec.py)

    • comp_flamingo_obj_perf (reconstructions/implementations/flamingo.py)

    • measure_nways_interaction_found (metrics/reconstruction/n_way_interactions.py)

    • comp_hicrep_third_party (metrics/ren/third_parties/hicrep_wrapper.py)

    • CSRDataset.__init__ (resolution_enhancements/datasets/csr.py)

    • get_genomic_mask, get_unified_mask (preprocs/matrices/masks.py)

  • Tutorial notebooks updated for v2.11.0 API. 16 tutorial notebooks

    • 4 analysis notebooks had resolution= / cm.resolution / positional-arg-order bugs. All affected notebooks now use the bin_size_bp= API. Bulk-fixed via tmp/fix_tutorials.py script.

  • load_pickle loader_kwargs dict had stale "resolution" key; renamed to "bin_size_bp" for consistency with the new _load_pickle_data signature.

  • Regression tests added in tests/loaders/test_api_regression.py to pin the correct TypeError behavior (not NameError) and prevent future regression of the dead-handler bug.

Migration from v2.11.0#

No code changes required for users. v2.11.0 users who passed resolution=... already got NameError — now they correctly get TypeError / ValidationError. The error MESSAGE changed but the SITUATION is the same: you must use bin_size_bp=.

For users still on v2.10.x who haven’t migrated yet, see the v2.11.0 migration guide below. The resolution= kwarg is no longer accepted in any version.

[2.11.0] - 2026-06-22#

Removed (BREAKING)#

  • resolution= deprecated kwarg alias REMOVED (was deprecated in v2.10.0). Users must use bin_size_bp= exclusively. Code that still passes resolution= will raise TypeError: unexpected keyword argument 'resolution'.

  • CLI flag --resolution removed. Use --binsize instead.

  • Class DataResolutionError name retained for backward compat but the underlying concept is now split into bin_size_bp (geometry) and coverage_ratio / n_pairs (data quality).

Migration from v2.10.0#

This is a hard break. Update your code:

# v2.10.0 (deprecated, still works)
cm = load_cm_data("data.hic", bin_size_bp=10000, resolution=10000)

# v2.11.0 (REQUIRED — only this works)
cm = load_cm_data("data.hic", bin_size_bp=10000)
# v2.10.0 CLI
gunz-cm loaders load-data --binsize 10000 --resolution 10000 path/to/data.hic

# v2.11.0 CLI
gunz-cm loaders load-data --binsize 10000 path/to/data.hic

See docs/migration/v2.9.0-to-v2.10.0.md for the full v2.10.0 migration (this v2.11.0 release is the natural follow-on).

[2.10.0] - 2026-06-18#

Changed (BREAKING — deprecate-then-remove)#

  • Hi-C terminology refactor: standardized the overloaded English word “resolution” across the public API to disambiguate three orthogonal concepts:

    • bin_size_bp (NEW): matrix geometry (genomic span per bin in bp)

    • coverage_ratio / n_pairs (NEW): data quality (counts axis)

    • effective_resolution_bp (NEW): finest supported bin from coverage

    Public API parameter rename: resolution=bin_size_bp= in:

    • ContactMatrix.__init__ (new field name; old name is deprecated alias)

    • load_cm_data(), get_bins(), get_balancing() (loaders/init.py)

    • load_hic(), load_cooler(), load_csv(), load_ginteractions(), load_narrowpeak(), load_pickle(), load_memmap(), get_bins() (hic), get_sparsity(), _load_hic_data(), _load_cooler_data(), build_straw_args(), run_straw()

    • HiCSparseDataset.__init__() (datasets)

    • _generate_region_mask() private helper (loaders/utils.py)

    Deprecated resolution= keyword still works in v2.10.0 (emits DeprecationWarning). Will be removed in v2.11.0.

    See docs/migration/v2.9.0-to-v2.10.0.md for migration guide and docs/design/2026.06.18-hic-resolution-terminology.md for the full vocabulary reference.

Added#

  • ContactMatrix new metadata fields (all with safe defaults):

    • n_pairs: int = 0 — total valid pairs (counts axis)

    • coverage_ratio: float = 1.0 — downsampling ratio vs canonical depth

    • effective_resolution_bp: int | None = None — finest supported bin from the 80%/1000-contacts rule (Rao 2014, Ay & Noble 2015)

    • fragment_resolution_bp: int | None = None — physical fragment limit

    • protocol_type: str | None = None — “Hi-C” / “Micro-C” / etc.

  • ContactMatrix.compute_effective_resolution(method="80_1000"): lazy accessor for the effective resolution. Removed in v2.25.0 (DOP Phase 8); use the free function cm_compute_effective_resolution(cm, method="80_1000") from gunz_cm.structs.cm_views instead. The underlying computation (only the 80%/1000-contacts rule is currently implemented; method="dedoc" / method="quasar" reserved for future releases) is unchanged.

  • Migration guide: docs/migration/v2.9.0-to-v2.10.0.md with parameter rename table, ContactMatrix new fields, CLI flag rename (--resolution--binsize), quick sed migration command, manual review checklist, deprecation timeline.

Deprecated (will be removed in v2.11.0)#

  • The resolution keyword argument across all loader functions and ContactMatrix.__init__. Use bin_size_bp instead. DeprecationWarning is emitted when used.

[2.9.0] - 2026-06-18#

Added#

  • 12 new tutorial notebooks in notebooks/, completing the 2026.06.18 curriculum plan (docs/tasks/active/2026.06.18-tutorial-curriculum-plan.md):

    • tutorial_18_balancing.ipynb — Choosing the Right Balancing Method (KR / VC / VC_SQRT / NONE decision tree)

    • tutorial_19_resolution.ipynb — Resolution Selection (memory + analysis trade-offs)

    • tutorial_20_resolution_for_analysis.ipynb — Resolution × Analysis Type matrix (TADs / compartments / loops / 3D recon)

    • tutorial_21_micro_c.ipynb — Micro-C Data Processing (sparse matrix handling, Hsieh 2015/2020 references)

    • tutorial_22_capture_hic.ipynb — Capture Hi-C Basics (viewpoint baits, Mifsud 2015 references)

    • tutorial_23_tad_loops.ipynb — TAD and Loop Calling (directionality index; flags missing TAD-calling algorithms as future gap)

    • tutorial_24_replicate_hicrep.ipynb — Replicate Reproducibility with HiCRep (Yang 2017 SCC)

    • tutorial_25_reconstruction_methods.ipynb — Comparing 3D Reconstruction Methods (MDS vs SHNEIGH-style, Spearman quality metric)

    • tutorial_26_resolution_enhancement.ipynb — Resolution Enhancement with the ren extra (graceful degradation when ren missing)

    • tutorial_27_population_hic.ipynb — Population Hi-C and Structural Variants (simulated deletion + differential analysis)

    • tutorial_28_pipelines.ipynb — Pipeline Orchestration (Pipeline().step().step().run())

    • tutorial_29_multimodal.ipynb — Multi-modal Integration (Hi-C + ChIP-seq)

  • Tutorial infrastructure (bf913e1):

    • notebooks/README.md — author guidance, 49-notebook inventory, conventions

    • notebooks/_synthetic_data.py — 6 shared data generators: make_synthetic_hic, make_synthetic_hic_grid, make_synthetic_microc, make_synthetic_capture_hic, make_synthetic_compartment_matrix, make_synthetic_3d_coords

    • notebooks/_template.ipynb — full canonical header (Learning Objectives, Prerequisites, Estimated Time, Data)

    • .pre-commit-config.yaml — ruff + nbstripout for notebook output stripping

Changed#

  • notebooks/README.md — expanded tutorial inventory from 16 to 28 production tutorials

  • docs/source/concepts.md, docs/source/tutorials/index.md — no changes (tutorials ship as .ipynb, not rendered into HTML per the myst_parser/myst-nb incompatibility documented in docs/MANUAL_UPLOAD.md)

Stats#

  • 130 new code cells across 12 tutorials — all 130 compile cleanly (validated with compile())

  • ~225,000 lines of new tutorial content

  • 7 commits (infrastructure + 4 buckets + README update + this version bump)

  • Field coverage: QC (4), Hi-C variants (2), 3D Genome (2), Workflow (1), Advanced (3)

  • Skill coverage: Beginner (2), Intermediate (5), Advanced (5)

Notes#

  • Tutorials use synthetic data generated inline via _synthetic_data.py — no real data is bundled or required.

  • All 12 tutorials use np.random.default_rng(42) for reproducibility.

  • Per audit recommendation #4: no AI model attribution lines (Qwen, Osiris, etc.) in any tutorial.

[2.8.0] - 2026-06-12#

Added#

  • Chromosome name normalization across the loaders API. Users can now pass region1="chr1" (UCSC) or region1="1" (Ensembl) regardless of whether the underlying file uses the chr prefix or not. The facade transparently normalizes the input to match the file’s actual chrom names before dispatching to the format-specific loader.

  • Design document at docs/design/specs/chrom-name-normalization.md with user stories, edge cases, and the 6 design decisions.

  • 21 new tests in tests/loaders/test_chrom_name_normalization.py covering the chr-swap, no-op, interval preservation, error cases, format pass-through, and end-to-end facade integration.

Fixed#

  • cool_loader.get_chrom_infos was failing on cooler 0.10.4 because it used cooler.is_mcool() which doesn’t exist in that version. Replaced with extension-based detection plus a fallback for single-resolution files. This was a pre-existing bug that surfaced during v2.8.0 development.

Notes#

  • Not normalized (out of scope per the design): chrM/MT/M (mitochondrial), chr1_KI270706v1_random (random contigs), GenBank accessions, case variants (Chr1chr1). Users should use get_chrom_infos(fpath) to see the actual file chrom names.

  • Round-trip behavior: ContactMatrix.chromosome1 returns the file’s actual chrom name (not the user’s input). The user’s form is not “normalized” on output — pass-through.

[2.7.0] - 2026-06-12#

Added#

  • Loaders API: region1 and region2 are now truly optional at all four layers (facade, format-specific loaders, CLI, library). Previously, the facade accepted None but the 4 format-specific loaders all required str, causing a confusing pydantic ValidationError when calling load_cm_data(file, resolution) without a region.

  • Per-format full-genome support matrix:

    • HIC: rejects region1=None with UnsupportedLoaderFeatureError (no safe full-genome API in hictkpy/hicstraw/straw)

    • COOLER: implements per-chromosome iteration with a memory warning if estimated load > 1 GB

    • CSV/COO/MCOO: rejects with UnsupportedLoaderFeatureError (format has no chromosome column)

    • GINTERACTIONS: implements full-genome by dropping the chr1 filter; ContactMatrix.chromosome1 = "ALL"

    • PICKLE/NPY/MEMMAP: no change (already optional before v2.7.0)

  • Facade-level normalization: region1="ALL" / "all" / "All" / "" are silently normalized to None. This prevents the confusing “chromosome ALL not found” error.

  • CLI dual-discovery helper: when a region1-related error occurs in load-data, to-coo, to-bigmat, or to-gzcm, the CLI now automatically prints available chromosomes and resolutions (via get_chrom_infos and get_resolutions) to help the user recover. Opt-out with --no-discovery.

  • 12 new tests in tests/loaders/test_region1_optional.py covering all per-format behaviors and the discovery helper.

Changed#

  • CLI surface: to-coo and to-gzcm changed from region1: str = typer.Argument(...) to region1: t.Optional[str] = typer.Option(None, ...). Existing scripts that pass region1 as a positional argument will need to switch to --region1.

  • docs/design/specs/loaders.md updated to document the v2.7.0 semantics and the format support matrix.

Notes#

  • Superseded by v2.8.0: chrom name normalization (chr1 vs 1) was deferred in v2.7.0 but shipped in v2.8.0 (commit 72dc1b0). See v2.8.0 entry for details.

  • Pre-existing test failures (6 + 13) in compressions/, resolution_enhancements/, and visualizations/metrics/ are unchanged from v2.6.x.

2.6.3 - 2026-06-11#

Added#

  • CLI-level tests for all 6 gunz-cm converters subcommands (smoke test that catches import-chain regressions; would have caught the preprocs bug shipped in v2.6.2)

  • 6 CLI-level tests for gunz-cm converters hic2cool (regression coverage for the v2.6.0 migration): help, dry-run, single-resolution roundtrip, multi-resolution invocation, corrupt-file error message, nproc no-op behavior

  • Tests build their own synthetic .hic files at test time using hictkpy (no binary fixtures committed to the repo)

Fixed#

  • preprocs/__init__.py referenced infer_mat_shape_coo (which does not exist; only the private _infer_mat_shape_coo is defined). This broke the entire converters CLI (every subcommand failed at module-import time with ImportError). Caught by the new test_all_commands_help smoke test. The bug was introduced by commit 333a1fb.

[2.6.2] - 2026-06-11#

Skipped (released as part of v2.6.3 — see v2.6.3 above for the preprocs fix).

2.6.1 - 2026-06-10#

Changed#

  • Cleanup: removed 135 per-file __version__ declarations across the codebase. Kept only pyproject.toml and src/gunz_cm/__init__.py as canonical sources (the standard pkg.__version__ convention). The 134 deleted lines were unused dead code that had drifted to 6+ different version strings.

  • Added AGENTS.md rule: do not add per-file or per-module __version__; if a module-internal version is genuinely needed, document it explicitly in the docstring and ask first.

2.6.0 - 2026-06-10#

Added#

  • gunz-cm converters hic2cool rewritten using hictkpy + cooler.create

  • .hic v8 and v9 support (was v6-v7 only)

  • Clear error diagnostic for corrupt-footered .hic files (names package, version, bug #41, workaround)

  • Source and attribution docstrings in the converter module

  • GZCM format user guide and improved Sphinx configuration

Changed#

  • conv extra is now empty; hic2cool PyPI package is no longer required

  • hictkpy and cooler (both already hard deps) handle hic-to-cool conversion in-process

  • README overhaul with professional structure

Fixed#

  • Constants ROW_IDS_COLNAME, COL_IDS_COLNAME, COUNTS_COLNAME were used in loaders/utils.py but not exported from gunz_cm.consts; added local definitions via DataFrameSpecs to avoid circular import

  • Balancing type cast in CLI-to-API bridge (converters.py)

  • 4 loader tests that were silently skipped now have documented root causes

  • Handle partial tiles at boundary in _get_compressed_patch

Removed#

  • hic2cool from conv, all, all-gpu extras in pyproject.toml

2.5.0 - 2026-05-03#

Added#

  • GZCM v3 multi-codec compression with streaming decode (GZCMChunkedWriter, sparse matrix support)

  • BSC-CMC codec with diag_mode parameter

  • Comprehensive resolution benchmark across 5 codecs and 6 resolutions

  • Transform experiment documentation (bsc_cmc concluded as optimal)

  • Task tracking files for sprint management

Changed#

  • Adaptive tiling (no compression benefit found - exp6)

  • Multi-resolution provides no compression benefit (exp7)

  • Updated codec guide with 5kb benchmarks, resolution-dependent recommendations

  • GZCM format specs updated to v1/v2/v3

Fixed#

  • KR normalization formula corrected to (n/sum)^0.25

  • CLI warnings with proper stacklevel

Removed#

  • Deprecated GNZ loader (replaced by GZCM v1-v3 support)

2.4.0 - 2026-04-15#

Added#

  • GNZ v2 chunked loader with 41 passing tests

  • GNZ v2 and normalization performance benchmarks

  • GZCM v1-v3 support in converters (replacing GNZ converter)

  • CMC codec implementation

  • GNZ layout space-speed tradeoff benchmark

Changed#

  • Converters refactored to replace GNZ with GZCM support

Fixed#

  • rc_filters import path

2.3.0 - 2026-03-20#

Added#

  • Centralized masking logic

  • Points module refactoring

  • Python best practices guidelines

  • Ruff and MyPy CI/CD integration

  • Chunked loader verification tests

Changed#

  • Third-party code restructured into implementations/ and originals/

  • CLI migrated and expanded using Typer

Fixed#

  • Hanging tests skipped

  • Test import issues resolved

Removed#

  • Hanging tests that block CI

2.2.0 - 2026-03-01#

Added#

  • Reliability standards for data submodules

  • Standardized logging and exception hierarchy

  • Sphinx documentation with furo theme

  • Cloudflare deployment via GitHub Actions

  • Vectorized HiCSpector and Numba JIT preprocessing helpers

Changed#

  • Metrics, preprocs, and reconstructions refactored for reliability

Fixed#

  • Missing test dependencies breaking unittest discover

  • Exception handling in tests for newly integrated specific exceptions

2.1.0 - 2026-02-10#

Added#

  • Multi-chromosome parallelism

  • Modernized coo.py

  • Centromere fetcher from UCSC

  • Fully Sparse HiCSparseDataset with on-the-fly augmentation

Changed#

  • preprocs NameError and shape assumption fixes in points reconstruction

Fixed#

  • Test suite discovery failures due to missing optional dependencies

  • gunz-utils dependency error in CI

2.0.0 - 2026-01-15#

Added#

  • GEMINI.md guide with multi-backend and multi-data loading info

  • Initial project structure with loaders, preprocs, converters, metrics, reconstructions

  • Support for HIC, COOLER, CSV, MEMMAP formats

  • GPU-accelerated 3D reconstruction (MDS-based)

  • Resolution enhancement models

  • Pipeline architecture for workflow composition

  • GZCM v1/v2 format specifications

Changed#

  • Project restructured from gunz to gunz-cm