Commit Graph
100 Commits
Author SHA1 Message Date
Eric Coissac 1c54e60c9a Rename Layer<D> to TypedLayer and introduce heterogeneous Layer enum
Renames `Layer<D>` to `TypedLayer<D>` to establish a distinct typed abstraction. Introduces a new heterogeneous `Layer` enum that unifies count and presence storage with runtime dispatch, delegating operations to the underlying typed variants. Updates cache, index, and phylo consumers to align with the renamed type and new extension traits, preserving full test suite stability while preparing the foundation for multi-partition caching.
2026-08-20 20:35:29 +02:00
Eric Coissac 6c860f120f refactor: merge KmerPartitions into KmerIndex and rename obikpartition
Consolidates partition logic, metadata storage, and layer management directly into KmerIndex. Renames obikpartitionner to obikpartition, retaining only PartitionRouter for superkmer routing. Removes intermediate .partition() accessors in favor of direct methods on the index and updates PartitionCache::build to accept &KmerIndex directly. Derives n_partitions from config.n_bits and consolidates k-mer/minimizer sizes into IndexMeta.config. Fixes a regression where PartitionRouter::open incorrectly defaulted to closed.
2026-08-20 20:23:58 +02:00
Eric Coissac b5ec0122d0 Rename obikpartition crate to obikpartitionner
Update all dependent crates and internal imports to reference the renamed module. Expose configuration parameters and genome metadata through new public accessor methods in the index API, and update documentation comments to align with the new package name.
2026-08-20 19:43:00 +02:00
Eric Coissac f64ac14f0e chore: make COUNTS_DIR constant pub(crate)
Adjusts the visibility of the COUNTS_DIR constant to pub(crate), enabling internal crate-wide access without altering runtime behavior or data structures.
2026-08-20 16:42:43 +02:00
Eric Coissac 9379bbaad8 refactor: rename obikpartitionner crate to obikpartition
Update Cargo manifests, dependency paths, and Rust imports across the workspace to reflect the `obikpartitionner` to `obikpartition` rename. Synchronize architecture and implementation documentation with the new module structure. Fix minor syntax issues in test assertions to ensure compilation compatibility. No behavioral or API changes are introduced.
2026-08-20 16:41:22 +02:00
Eric Coissac f9ef6b8391 rename KmerPartition to KmerPartitions and update Mat enum
Rename the KmerPartition type to KmerPartitions across obikindex, obikpartitionner, and obikphylo/siblings to reflect an updated data model. Update the Mat enum in siblings/cache.rs to add a SparsePresence variant and simplify opening logic by delegating sparse versus dense detection to PersistentBitMatrix. Apply consistent code formatting, import reordering, and multi-line refactoring throughout the affected modules.
2026-08-20 15:57:33 +02:00
Eric Coissac 76cbd3a886 Centralize partition metadata access and add layer introspection APIs
Replaced scattered direct metadata loading with centralized instance methods on `KmerPartition` to guarantee consistent error mapping and legacy recovery. Introduced `StorageKind`, `LayerContent`, and `EvidenceKind` enums alongside lightweight disk-probe methods that inspect file presence without opening heavy data structures. Updated callers across the index, partitioner, and phylo modules to use the new partition API, and added unit tests validating the introspection behavior.
2026-08-20 15:29:53 +02:00
Eric Coissac f7ebc7a1ab Centralize partition directory resolution and add caching design spec
Introduce a design specification outlining performance bottlenecks in layer data access and an agreed-upon implementation direction for caching. Refactor the codebase to centralize index and layer directory path resolution within the partition object, replacing manual string joining and external helper functions with dedicated accessor methods.
2026-08-20 15:10:57 +02:00
Eric Coissac 7eaa8c2016 Replace manual layer path construction with obilayeredmap::layer_dir
Standardizes layer directory path resolution across obikindex, obikpartitionner, and obikphylo by replacing inline string formatting and join calls with the centralized obilayeredmap::layer_dir utility. This refactoring removes redundant path construction logic while preserving existing iteration bounds, control flow, and public APIs.
2026-08-20 14:54:13 +02:00
Eric Coissac 5a91817488 centralize layer path construction and data loading
Replace manual directory formatting and inline matrix opening with the newly introduced `layer_dir` and `open_data` helpers from the `obilayeredmap` crate. This standardizes filesystem access, encapsulates layer naming conventions, and simplifies error handling without altering computational behavior or test suites.
2026-08-20 14:43:10 +02:00
Eric Coissac 640f29725b Optimize sparse bit matrix packing to avoid intermediate copies
Refactor `pack_sparse_bit_matrix` to conditionally open either a packed or columnar dense representation based on file existence. This eliminates the previous unconditional pre-conversion step that forced a full packed copy. Update cleanup logic and add tests to verify direct transposition, proper file handling, and idempotency for both formats.
2026-08-20 14:38:20 +02:00
Eric Coissac c2e0533fa9 Refactor bit matrix operations and optimize distance computations
Consolidate row extraction and parallel column reduction into reusable generic utilities within the pairwise module. Replace manual iteration in builder and view methods with iterator-based zipped loops and deferred overflow processing to improve memory access patterns. Optimize distance functions by switching to bulk byte passes for branch-free SIMD vectorization, adding a merge-like helper to correct masked overflow values without secondary allocations. Add a comprehensive test validating the optimized distance paths against naive references across multiple thresholds and overflow scenarios.
2026-08-20 14:35:22 +02:00
Eric Coissac 9abee87af3 refactor: delegate distance computations and simplify matrix logic
Consolidate bit matrix operations by delegating pairwise metric calculations to IntSliceView and col_view implementations. Introduce chunked_presence_count in colgroup to handle threshold-based accumulation efficiently. Add a direct point lookup method to the sparse matrix representation to eliminate buffer allocations, and simplify match arms in persistent accessors accordingly. All public APIs and behavioral contracts remain unchanged.
2026-08-20 14:27:32 +02:00
Eric Coissac 19f9954050 refactor: centralize nonzero slot iteration logic across views
Extract duplicated traversal logic into a shared `NonzeroSlotsView` trait and `nonzero_triples` helper. Update slice view iterators to consistently yield `(position, value)` tuples and use a temporary buffer with explicit permutation mapping for sorted access. Delegate manual slot sorting and column iteration to the new shared helper, eliminating per-format duplication and eager collection while preserving existing public API signatures.
2026-08-20 14:20:24 +02:00
Eric Coissac 82374deca5 refactor: simplify sub_matrix with iterator-driven column population
Refactored `sub_matrix` to delegate column population to `fill_sub_matrix`, replacing manual buffer allocation and explicit permutation loops with direct value assignment via `enumerate_slots_values`. This eliminates intermediate allocations, reduces pipeline overhead, and simplifies control flow while preserving slot ordering and permutation semantics.
2026-08-20 14:17:05 +02:00
Eric Coissac ac38aa759b refactor: rename batch retrieval methods and update common_traits
Renames `get_batch`, `fill_batch`, and `fill_batch_sorted` to `collect_slots_values`, `fill_slots_values`, and `fill_slots_values_sorted` to align with updated `common_traits 0.13` APIs. Introduces optimized batch retrieval that sorts input indices for sequential mmap access before reordering outputs to match the original query order. Updates test suites to reflect the new method signatures without altering validation logic or coverage.
2026-08-20 14:15:28 +02:00
Eric Coissac 82ddeaddcd Introduce unified nonzero_iter API across matrix types
Replaces nested column-major point lookups with a batched iterator that delegates to format-native traversal strategies. The implementation enforces a single pass per matrix type, using row-major iteration for sparse formats and eager collection for packed/columnar layouts while preserving original slot ordering. Memory allocation is optimized by removing `n_cols`-wide buffers in favor of per-row buffering or lazy iteration. Correctness tests verify iterator output against dense baselines across all supported layouts, and architecture documentation is updated to reflect the new format-agnostic query pattern.
2026-08-20 14:07:09 +02:00
Eric Coissac a4eb20e67e add some doc about optimisation for query 2026-08-20 13:59:12 +02:00
Eric Coissac 89ea077456 Add benchmark pipeline for dense and sparse query testing
Introduces a complete query benchmark track to evaluate performance and verify consistency between dense and sparse index formats. Adds scripts to simulate fixed-size paired-end reads, pack a sparse presence index, execute queries in both modes, and capture wall time and RSS metrics. Includes a verification step that compares outputs by read ID to ensure content identity across parallel processing. Updates build configuration, documentation, and ignore patterns to support the new pipeline for two microbial specimens.
2026-08-20 13:59:12 +02:00
Eric Coissac 5a9d903e51 chore: update dependencies and adapt to updated crate APIs
Bumps core dependencies including ndarray, rand, hashbrown, niffler, ureq, sysinfo, indicatif, lru, and remove_dir_all. Adapts source code to accommodate breaking changes by migrating RNG initialization, adjusting HTTP response handling, and replacing the fs4 crate with standard library file locking. Adds a planning document for query benchmarking and sparse index regression tests.
2026-08-20 13:45:41 +02:00
Eric Coissac 32bcbd1465 chore(deps): update dependencies and clean up imports
Updated core libraries and ecosystem packages, including the full serde suite and regex dependencies. Restructured syn dependency resolution by pinning 2.0.117 while introducing a standalone 3.0.3 entry for derive macros. Downgraded windows-sys to 0.59.0 and replaced the anes dependency in criterion2 with bpaf and walkdir. Removed an unused IntSliceView import from test modules.
2026-08-20 13:25:35 +02:00
Eric Coissac 0da725ffe9 refine k-mer index architecture documentation and remove obsolete spec
Introduces raw mapping and iteration APIs that bypass membership checks, clarifies variant-specific storage layouts and auto-detection logic, and documents optimized batch access patterns with caller-provided buffers. Removes the outdated obicompactvector_reflexion.md specification to consolidate architectural details into current implementation docs.
2026-08-20 13:20:29 +02:00
Eric Coissac 3b65319529 Remove precomputed data assets, configurations, and documentation
This change removes precomputed model parameters, phylogenetic tree datasets, k-mer spectrum data, and compressed profile archives. It also deletes runtime logs and detailed pipeline documentation. The repository ignore list is updated to exclude the sandbox directory.
2026-08-20 13:15:56 +02:00
Eric Coissac 69747dcb53 chore: add editor and memory directory patterns to .gitignore 2026-08-20 12:50:54 +02:00
Eric Coissac 2dba217482 chore: remove src/profile.json.gz
Removes the compressed JSON archive containing profile configuration and data model definitions. Build processes and runtime loaders referencing this path will require updates to prevent missing file errors.
2026-08-20 12:49:48 +02:00
Eric Coissac dbd8af376c Consolidate compare_sparse as example and clean up project artifacts
Restructure the project by moving the standalone compare_sparse utility into an example directory, removing Sankoff parameter configurations and benchmark scripts, updating version control ignores, and expanding the test suite with diagnostic checks and performance benchmarks.
2026-08-20 12:48:42 +02:00
Eric Coissac dc3d82f8db Add resume API to persistent matrix builders for incremental appending
Introduce a `resume` method for persistent bit and int matrix builders to restore dimensions from persisted metadata. This enables incremental column appending across separate build sessions without requiring manual dimension tracking. Consolidate builder lifecycle management in the merge layer using a unified `MatrixBuilder` enum, simplify closure logic, and add instrumentation. Include tests verifying state preservation and data integrity across multiple resume cycles.
2026-08-20 12:36:47 +02:00
Eric Coissac 308d2b9f92 chore(deps): bump obikmer dependency to 1.2.2
Update Cargo.lock to track the patch release of obikmer. This modification only adjusts the version in the lockfile and introduces no behavioral or API changes.
2026-08-20 12:27:26 +02:00
Eric Coissac 66ab1d0947 chore: bump obikmer to 1.2.1 and disable obikindex default features
Release / create-release (push) Successful in 2m25s
ci.yml / build (pull_request) Successful in 4m34s
Release / build-linux-x86_64 (push) Successful in 8m18s
Release / build-macos-arm64 (push) Successful in 1m55s
Updates the obikmer lockfile version to 1.2.1 and configures the obikindex dependency to explicitly disable default features. These are manifest and lockfile adjustments that do not modify source code or alter application behavior.
2026-08-17 13:32:30 +02:00
Eric Coissac fceb523f1a chore: disable default features for obikindex
Release / create-release (push) Successful in 2m28s
ci.yml / build (pull_request) Successful in 4m41s
Release / build-linux-x86_64 (push) Successful in 8m23s
Release / build-macos-arm64 (push) Failing after 2m4s
Explicitly sets `default-features = false` for the `obikindex` dependency to ensure no default features are activated during dependency resolution and compilation.
2026-08-17 12:33:59 +02:00
Eric Coissac 700eaeaed2 test: simplify k-mer test setup for updated canonical API
Adapts sibling k-mer tests to the updated canonical API by replacing string-based construction with direct byte conversion. Removes intermediate reverse complement steps and introduces a helper function to compute reverse complement strings directly from canonical k-mers, preserving existing test output while streamlining setup.
2026-08-17 12:32:44 +02:00
Eric Coissac 6def18fa88 Add TNT configuration directives and tree export commands to script
Release / create-release (push) Successful in 2m28s
ci.yml / build (pull_request) Failing after 3m31s
Release / build-linux-x86_64 (push) Successful in 8m29s
Release / build-macos-arm64 (push) Failing after 1m49s
Updates the generated TNT script with configuration parameters and appends tree management commands for saving and exporting results. Modifications are strictly limited to string literals written to the output stream.
2026-08-17 11:39:51 +02:00
Eric Coissac 70b0527957 Add diagnostic logging and minor internal refactoring
Introduce runtime dimension tracking, matrix shape validation, and per-layer diagnostics across multiple modules to improve execution observability. Extract intermediate computation results into local variables, standardize collection patterns in partial methods, and replace naive iteration with optimized pairwise counting. All modifications are strictly additive or structural; public APIs, data models, and core logic remain unchanged.
2026-08-17 11:29:31 +02:00
Eric Coissac 11476bc557 Add sparse bit matrix support and enhance dimension logging
Introduce a `Sparse` variant for `PersistentBitMatrix` with full method dispatch and implementations of `ColumnWeights` and `BitPartials` traits. Refactor distance matrix computations in layered stores to eagerly collect results before reduction, enabling reliable dimension tracking. Add comprehensive debug logging across phylo commands and distance modules to report matrix shapes and flag out-of-bounds indices during CSV iteration.
2026-08-17 11:24:23 +02:00
Eric Coissac dbb969f087 style: reformat iqtree module for line-length compliance
Apply consistent multi-line formatting to iterator chains, struct initializations, function signatures, and CLI string literals. Convert sequence vector declarations to single-line format while expanding assertions and variable initializations across multiple lines. Reorder imports in the sankoff module and align test fixtures with updated line-length constraints. This change is purely syntactic with no functional or behavioral impact.
2026-08-17 11:19:44 +02:00
Eric Coissac 1f9c6388eb Introduce compare_sparse CLI tool to verify index consistency
Adds a new binary that validates bit-level consistency between dense and sparse K-mer index representations by sampling slots across partitions and reporting discrepancies. Refactors sibling cache matrix initialization into a centralized factory method to simplify control flow and standardize error handling. Introduces diagnostic configurations, benchmark scripts, and an ignored test case to support k-mer resolution analysis.
2026-08-17 11:16:42 +02:00
Eric Coissac 128db64564 feat(phylo): add --iqtree-min-freq to filter rare nucleotide states
Introduces --iqtree-min-freq (default 0.001) to treat low-frequency nucleotide states as missing data during IQ-TREE alignment generation when --free-loss is active. This triggers a recoding pass that folds rare states into the missing symbol, followed by non-informative site removal and alphabet recomputation to maintain output consistency. The change also adds Sankoff model configuration files and updates related tests and documentation.
2026-08-17 11:06:03 +02:00
Eric Coissac c8f2b16b4c fix: prevent probability underflow in pairwise cost matrix
Replaces premature exponentiation-based row normalization with log-sum-exp arithmetic to prevent tiny probabilities from collapsing to exactly zero. This eliminates spurious infinite costs for valid but rare transitions while preserving correct IEEE 754 semantics for genuinely unobserved pairs. Adds explicit guards against NaN in degenerate rows and includes a regression test verifying finite costs for probabilities as low as 1e-200.
2026-08-17 09:41:50 +02:00
Eric Coissac 9654201885 feat: introduce _iqtree_states.csv for compact symbol mapping
Generates a new CSV output that maps IQ-TREE's compact state symbols to canonical states alongside full-precision empirical frequencies. Updates documentation to clarify that state frequencies sum to 1.0 by design and documents conditional behavior under `--free-loss`. Includes unit tests verifying absent state exclusion, frequency summation, and CSV structure. Also restricts entropy annex resolution to non-monomorphic minorants to eliminate redundant per-genome checks.
2026-08-17 09:38:26 +02:00
Eric Coissac c6cfdac043 perf: optimize entropy computation by pre-filtering monomorphic minorants
Shift monomorphism filtering from the entropy scan layer to a lightweight, annex-only pre-pass. By replacing `Selection::All` with a pre-filtered subset, expensive per-genome resolution is strictly limited to non-monomorphic families. This avoids processing ~98% of minorants that are known to be monomorphic, while preserving positional read speedups for subsequent runs. The change is an internal performance refinement with no public API modifications.
2026-08-17 09:32:45 +02:00
Eric Coissac 7bac0f3850 large refactoring 2026-08-17 09:28:53 +02:00
Eric Coissac 49e66f16a2 docs: document architecture analysis and refactoring plans for siblings
Documents architectural analysis, identified performance bottlenecks including hardcoded selection flags and redundant full-index scans causing I/O-bound stalls. Details planned pipeline refactoring to unify stages around a single shared selection for a fused single-pass scan, noting future dependencies on entropy-biased family selection.
2026-08-16 21:54:07 +02:00
Eric Coissac 53c40b7a53 refactor: format tnt script generation and add tree export commands
Reworks `writeln!` macro invocations to multi-line syntax and adjusts whitespace for improved readability. Additionally, appends four commands to the generated phylogenetic script to explicitly export trees and manage taxon naming at runtime.
2026-08-16 21:52:30 +02:00
Eric Coissac 3ba26b3dc1 feat: add sparse on-disk format for presence matrices
The index packing API now accepts a `sparse` parameter to generate `PersistentSparseBitMatrix` files alongside existing dense matrices. The sibling cache automatically detects this format via an `is_multi.prsb` marker file and routes queries identically to the dense variant. A new `--sparse` CLI flag exposes the option, with tests verifying end-to-end pipeline correctness and storage equivalence.
2026-08-16 21:51:02 +02:00
Eric Coissac 50f4820cb9 feat(obicompactvec): introduce sparse bit matrix with supporting primitives
Implements a compact, row-major sparse bit matrix backed by memory-mapped components, introducing EliasFano, PersistentFixedIntVec, and PersistentRankSelectBitVec primitives for efficient storage and decoding. Adds a BinaryMatrix trait to unify row-level operations across dense and sparse implementations. Corrects edge-case behaviors for zero-width bit storage and cardinality-0 rows. Delivers reduced on-disk size and faster random row access, with column reads remaining dense-only. Test suites and benchmarks are included but currently marked as ignored.
2026-08-16 21:43:09 +02:00
Eric Coissac 45b19503a1 Add proportional subsampling and Shannon entropy calculation
Introduces `--subsample N` and `--shannon` CLI flags to cap retained variable families via proportional reservoir sampling and compute per-family Shannon entropy. Updates the family scanning API to support explicit selection filtering with early-exit optimization, resolving an indexing drift issue in monomorphic layers. Streams entropy metrics for 15-state and 4-nucleotide spaces directly to CSV while maintaining parallel processing across sibling layers.
2026-08-16 21:31:06 +02:00
Eric Coissac f5e4bbfc6b Document architecture redesign and add partition layer accessor
Documents a proposed redesign for cross-partition batch resolution, shifting trigger logic to per-destination accumulator thresholds and introducing entropy-based pruning criteria. Adds an `n_layers_per_partition` method to the index, exposing partition metadata with consistent error handling and clarified documentation regarding build-time structural properties.
2026-08-16 21:20:55 +02:00
Eric Coissac 151493526c perf: add #[inline] attributes to obicompactvec methods
Adds compiler inlining hints to accessors, iterators, bitwise operations, and distance functions across multiple modules. This optimization aims to reduce call overhead for frequently invoked methods without modifying runtime behavior, API contracts, or data models.
2026-08-16 21:18:58 +02:00
Eric Coissac 693c18bfa7 introduce fast mode for optimized sibling presence checks
Centralize the layer count validation into PartitionCache and track it via a new fast_mode flag. Extend query tuples to include a pre-resolved destination layer index, enabling a fast-path batch lookup that bypasses per-layer probing when enabled. Refactor neighbor iteration and hit resolution to eliminate duplication and conditionally dispatch to the optimized path based on the cache state.
2026-08-16 21:12:05 +02:00
Eric Coissac 0ce934b111 Refactor sibling annex to use mmap-backed concurrent storage
Shift the sibling annex construction pipeline from an in-memory atomic mask to a memory-mapped file backend. This enables lock-free concurrent writes directly into the mapped region, streamlining the two-phase write process to accumulate bits atomically before finalization. Adjusted the cache lookup to return the specific matching layer index rather than a boolean flag, and added tests to verify correct layer tracking and cross-partition resolution in merged indexes.
2026-08-16 21:07:39 +02:00
Eric Coissac fecfe84ea6 Move sibling annex implementation to obikphylo siblings module
Relocates `SiblingAnnex`, `FamilyMask`, and `SiblingAnnexBuilder` from `obicompactvec` to the local `obikphylo::siblings` module. Replaces the previous implementation with a memory-mapped version using `memmap2`, featuring a 2-byte-per-slot layout, explicit bitfield manipulation, and support for concurrent atomic writes. Updates all sibling module imports to local paths and adds the `memmap2` dependency to `obikphylo`.
2026-08-16 21:04:14 +02:00
Eric Coissac c990087ef3 Add execution timing and parallelize sibling stats
Instruments the phylo command pipeline with structured execution timing, wrapping major computational blocks with stage hooks and printing aggregated metrics upon completion. Additionally, parallelizes sibling counting logic using Rayon to process independent layer directories concurrently, preserving identical functionality and public API contracts.
2026-08-16 20:53:22 +02:00
Eric Coissac 32d6720f50 Fix batch enumeration offsets and refactor sibling annex construction
Shifts sibling annex construction from slot-indexed enumeration to iteration-order traversal by correcting cumulative k-mer offset tracking in batch enumeration. Replaces coarse per-partition parallelism with chunked work distribution to prevent thread starvation on skewed partitions. Decouples custom progress messages from ETA updates to eliminate display clobbering during high-frequency callbacks. Adds regression tests validating batch offset correctness, partial batch handling, and iterator-order consistency across layer builds.
2026-08-16 20:51:19 +02:00
Eric Coissac d2548e8c33 feat(progress): implement configurable ETA throttling
Introduces timing constants and atomic fields to control ETA calculation intervals. Replaces the static template placeholder with dynamic messages, delegating formatting to a new helper that applies throttling thresholds and suppresses automatic updates during custom message hold periods.
2026-08-16 14:32:25 +02:00
Eric Coissac 5997de6707 Extract phylogenetic sibling logic into new obikphylo crate
Relocate the `siblings` and `cardcomp` modules from `obikindex` to a dedicated `obikphylo` workspace member. Convert inherent methods on `KmerIndex` into extension traits, update import paths across `obikmer`, and add supporting accessor methods to `obikseq` and `obilayeredmap`. This restructuring reduces the public API surface of `obikindex` while organizing phylogenetic iteration, caching, and distance calculation logic under a dedicated crate.
2026-08-16 14:30:34 +02:00
Eric Coissac 519195d4a1 Replace slot-based indexing with iteration order and stream k-mers
Transitions the index from MPHF slot-based to physical iteration-order indexing, aligning with the unitig layout. Introduces a streaming-only pipeline for k-mer iteration that adheres to memory constraints by avoiding full in-memory collections. Updates layer and sibling iterators to own an Arc clone of the file reader, making them Send + 'static and safe for concurrent use without borrowing the parent. Exposes batch and k-mer iterator types publicly while simplifying signature syntax with modern lifetime elision.
2026-08-16 14:07:22 +02:00
Eric Coissac b1f54b7d2f Add cache-optimized batch retrieval and sub-matrix methods
Introduces batch retrieval and sub-matrix extraction methods across vector, view, reader, and matrix types. These implementations optimize cache locality by sorting requested indices for sequential memory access before applying an inverse permutation to restore original order. Includes allocation-free variants that populate caller-provided buffers. Updates architecture documentation to define sibling annex persistence in iteration order and clarify pipeline separation.
2026-08-16 14:01:35 +02:00
Eric Coissac dae543fdfc Add raw lookup and iteration APIs to Layer struct
Introduces `index` and `index_batch` methods for direct MPHF slot mapping without membership validation, alongside four public iterator methods for deterministic traversal of canonical kmers. These are backed by dedicated `KmerIter` and `KmerBatchIter` structs that wrap the underlying unitig file reader. Updates `LayerEvidence::Approx` to eagerly open the unitig reader during initialization, enforcing a clear separation between raw mapping and verified lookup workflows.
2026-08-16 13:54:09 +02:00
Eric Coissac 0de078fdf1 Store minorant flag in family mask to avoid costly k-mer reconstruction
Transition the minorant flag from a derived value to a stored field within the family mask, resolving a performance regression where on-the-fly reconstruction consumed significant query time. This change introduces O(1) k-mer reconstruction APIs, shifts minorant computation to the index build phase, and enables direct annex-based statistics. Supporting updates include adopting shared ownership for partition caches and refactoring batch processing pipelines.
2026-08-16 13:50:44 +02:00
Eric Coissac c7679fac90 refactor: replace eager family collection with callback processing
Refactor `scan_layer_families` across the siblings module to accept a closure callback instead of returning an intermediate collection. This eliminates eager materialization and per-layer buffering by streaming results directly into genome-specific buffers or tally matrices. The update introduces bounded batch processing and scratch buffer reuse to cap peak auxiliary memory, while preserving existing computational behavior, control flow, and error semantics.
2026-08-16 13:36:20 +02:00
Eric Coissac 0e2e3b5bae Switch sibling modules to sequential layer directory processing
The sibling calculation modules now process layer directories sequentially instead of in parallel. This eliminates concurrent processing overhead and prevents interleaved cache sweeps, improving disk I/O and page-cache locality for partition-grouped data access. Progress bar updates and result accumulation have been adapted to the sequential control flow, while core filtering logic and output structures remain unchanged.
2026-08-16 13:30:30 +02:00
Eric Coissac cd57cf0cbd refactor: extract sibling family scanning into shared module
Introduces a dedicated `family_scan` submodule to consolidate per-layer family traversal logic. Centralizes path validation, minorant filtering, and conditional matrix instantiation into a shared `scan_layer_families` function. Updates sibling-annex consumers to leverage the new abstraction, reducing inline scanning code. Adds a test fixture to verify numerical consistency across consumer methods for co-occurrence and base-pair metrics.
2026-08-16 13:25:25 +02:00
Eric Coissac 3da501349b docs: clarify phylogenetic output files and tool usage
Restructure the output files section into categorized subsections with tables. Add explicit mappings between command-line options and generated files. Define CSV matrix conventions, clarify mathematical formulas for distance calculations, and document execution commands for external phylogenetic tools.
2026-08-16 13:17:51 +02:00
Eric Coissac d54ae272a4 refactor: centralize index setup logic and add progress bar ETA
Extracts directory cleanup, partition initialization, and finalization into dedicated helper methods within KmerIndex. This centralizes force-flag handling and reduces boilerplate across merge, rebuild, and select workflows. Additionally updates the CLI progress bar template to display an ETA indicator following elapsed time.
2026-08-16 13:15:59 +02:00
Eric Coissac eee71430a4 add name-tree command and fix --free-loss cost matrix
Introduce the obikmer name-tree subcommand to map numeric leaf labels in phylogenetic tree exports back to taxon names using a reference FASTA file. Correct the --free-loss flag behavior by removing cardinality transition costs from pairwise cost calculations, ensuring sibling gains and losses are priced identically to whole-family events. Update documentation, configuration parameters, and add reference phylogenetic data files.
2026-08-16 13:11:06 +02:00
Eric Coissac 8615da59a8 Add phylogenetic CLI options for family overlap and missing data
Introduces CLI flags for computing pairwise family overlap matrices and filtering genomes below a shared family threshold. Adds a free-loss mode that recodes locus non-detection states to missing data symbols in Sankoff-calibrated alignments, resolving ascertainment bias handling for IQ-TREE. Updates empirical transition parameters, removes the legacy model asset, and extends output writers for CSV diagnostics, FASTA pseudo-alignments, and Newick trees.
2026-08-16 11:54:43 +02:00
Eric Coissac e2b9374426 fix: respect --force flag during index and partition creation
The index creation routine now uses the CLI `--force` argument instead of a hardcoded false value, enabling explicit overwrite control. Partition existence checks also verify for the designated subdirectory rather than the root path, ensuring conflict detection and cleanup only trigger when an actual partition layout exists.
2026-08-16 11:37:26 +02:00
Eric Coissac dd889854cb rename distance subcommand to phylo
Rename the distance CLI subcommand to phylo across the codebase, documentation, and build configurations. Relocate source files from cmd/distance/ to a dedicated cmd/phylo/ module, update all internal routing references, and adjust benchmark scripts and Makefile targets to reflect the new command name.
2026-08-15 10:07:03 +02:00
Eric Coissac 79346c0c86 Add modular data structures, parallel pipelines, and system profiling
Establishes foundational infrastructure across multiple crates by introducing unified persistent bit matrix storage with columnar, packed, and implicit variants, alongside De Bruijn graph node encoding and unitig iteration logic. Adds a macro-driven parallel pipeline scheduler featuring NUMA-aware runners, bounded channels, and memory budgets to enforce concurrency limits. Implements streaming nucleotide parsers with pooled page buffers for FASTA, FASTQ, and Genbank formats, complemented by system resource monitoring, progress tracking, and stage profiling utilities. Collectively, these changes provide the core data models, execution frameworks, and I/O pipelines required for downstream k-mer indexing and analysis workloads.
2026-08-14 14:20:08 +02:00
Eric Coissac cc67023e2c feat: centralize genome metadata predicates in obikindex
Introduces a new predicate module in obikindex that implements genome metadata predicate parsing, evaluation, and group classification using three-valued logic. Extends the IndexMeta API with methods for single-predicate filtering and group quorum filtering. Updates obikmer command modules to delegate filter construction and matching to the centralized index API, removing local definitions and simplifying call sites.
2026-08-13 18:56:02 +02:00
Eric Coissac 8967a20ed7 refactor(cmd): restructure modules and decompose query command
Convert single-file modules to directory-based layouts across the cmd crate. Decompose the monolithic query command into dedicated submodules for batching, chunk processing, sparse finding, and output formatting. Introduce a new utils module to handle index management operations including statistics reporting, label renaming, and partition analysis.
2026-08-13 17:55:58 +02:00
Eric Coissac 6acafa7f2c docs: add obikmer user guide and MkDocs build configuration
Introduces a comprehensive documentation set covering theoretical foundations, CLI usage, installation, and system architecture. Adds MkDocs configuration and Makefile targets to generate, serve with live reload, and clean the documentation site. Includes citation styles and bibliography files for academic references.
2026-08-13 17:19:01 +02:00
Eric Coissac 0c86ea0385 Replace Sankoff cost matrix with cardinality-composition decomposition
Replaced the legacy Sankoff parsimony pipeline with a new cardinality-composition decomposition that constructs row-normalized transition probability matrices symmetrized via geometric mean. This ensures reversibility, reduces free parameters from 240 to 120, and guarantees a zero diagonal. Tallies are now explicitly restricted to variable families to align with +ASC-corrected alignment populations. Additionally, fixed `--exclude-genome` handling to re-scan surviving sequences and drop newly monomorphic columns, preventing silent data corruption in downstream tree inference tools.
2026-08-13 16:58:12 +02:00
Eric Coissac c26623fa00 Add repeatable --exclude-genome flag to obikmer distance command
Integrate in-memory row/column zeroing and alignment filtering across SNP, Sankoff, TNT, and IQ-TREE output paths. Add strict validation for missing labels, implement `write_iqtree` with empirical stationary frequencies, and introduce `--raw-snp-counts` diagnostic CSV output. Update documentation to reflect experimental validation of backbone resolution limits and theoretical considerations for CTMC rate matrices.
2026-08-13 16:36:02 +02:00
Eric Coissac 28d841c7be feat(distance): add IQ-TREE output and optimize state index mapping
Introduce `--iqtree` and `--raw-snp-counts` flags to generate IQ-TREE model files, recoded FASTA alignments, and per-pair diagnostic counts. Centralize alphabet conversion by extracting a precomputed state index lookup table into the Sankoff module, eliminating redundant iterations across downstream adapters.
2026-08-12 20:05:10 +02:00
Eric Coissac adf5b52dc7 feat(distance): implement native Sankoff calibration and backends
Replaces external Python glue with native Rust modules for Sankoff model calibration, exporting calibrated cost matrices, FASTA alignments, and YAML parameters. Adds dedicated writers for TNT and PhyG that apply integer scaling and Floyd-Warshall metric closure to enforce triangle inequality. Integrates these exporters into the distance command pipeline to streamline downstream tree inference workflows, while updating theory documentation to reflect IQ-TREE integration and state renumbering improvements.
2026-08-12 20:05:10 +02:00
Eric Coissac 55d7fa2067 feat: add Sankoff parsimony model and directory locking
Implements a calibrated 16-state Sankoff substitution cost matrix and CLI pipeline for evolutionary distance computation, including empirical calibration via saturation-filtered SNP counts. Refactors the sibling scanning stage to use batched transforms for improved synchronization efficiency. Introduces an OS-level advisory directory lock across all index-modifying commands to prevent concurrent write corruption. Updates dependencies and exposes new Sankoff utilities in the public API.
2026-08-12 20:05:10 +02:00
Eric Coissac c95c47155e fix: resolve test race conditions, add logging, and fix CI deadlock
Release / create-release (push) Successful in 2m26s
ci.yml / build (pull_request) Successful in 4m4s
Release / build-linux-x86_64 (push) Successful in 8m19s
Release / build-macos-arm64 (push) Successful in 1m48s
Re-enables the `numa` feature in CI workflows to prevent container/cgroup deadlocks while preserving validation correctness. Fixes concurrent test race conditions by replacing thread-local parameter storage with process-wide atomics and mutex locks. Integrates `tracing-subscriber` for structured logging and adds thread-ID tracking to debug worker lifecycles. Additionally bumps the crate version, updates `.gitignore`, documents experimental evolutionary distance pipelines, and refactors hardcoded test constants.
2026-08-11 23:04:06 +02:00
Eric Coissac e6f0ca472c ci: disable numa feature, bump obikmer, and document Sankoff costs
Release / create-release (push) Successful in 2m28s
ci.yml / build (pull_request) Failing after 3h0m41s
Release / build-linux-x86_64 (push) Successful in 8m31s
Release / build-macos-arm64 (push) Successful in 1m53s
Disable the `numa` default feature in CI build and test steps to prevent container environment deadlocks, and add comments explaining the cache key salt bump (`v2`) to mitigate incremental compilation corruption. Document a 16-state Sankoff cost matrix derived from set-edit distances, including substitution, gain/loss, and context-disappearance costs compatible with TNT's interface. Bump `obikmer` crate version to 1.1.43.
2026-08-11 18:26:54 +02:00
Eric Coissac a63692b8c4 chore: update ci cache, document distance metrics, and bump version
Release / create-release (push) Successful in 2m26s
Release / build-linux-x86_64 (push) Successful in 8m43s
Release / build-macos-arm64 (push) Successful in 2m7s
ci.yml / build (pull_request) Canceled after 59m15s
Updated CI workflow cache keys with a `v2` salt and `Cargo.lock` hash to prevent stale incremental compilation caches and deadlocks, while updating restore keys and documenting interrupted job state. Introduced a 3-way ordinal distance metric framework that replaces ambiguous IUPAC encoding with explicit k-mer scoring, bridging pairwise methods to character-based phylogenetics via Sankoff parsimony. Bumped the `obikmer` crate version to 1.1.42.
2026-08-11 17:12:28 +02:00
Eric Coissac 5f95e866f8 refactor: centralize CPU core detection using cgroup-aware utility
Release / create-release (push) Successful in 2m26s
Release / build-linux-x86_64 (push) Successful in 8m13s
Release / build-macos-arm64 (push) Successful in 1m43s
ci.yml / build (pull_request) Canceled after 1h29m17s
Introduce `obisys::effective_parallelism()` to read Linux cgroup v1/v2 CPU quotas from sysfs, preventing thread pool oversubscription in containerized environments. Replace direct `std::thread::available_parallelism()` calls across `obikindex` and `obikmer` with this centralized function. Bump `obikmer` version to 1.1.41.
2026-08-11 12:23:05 +02:00
Eric Coissac f5e508ed33 feat: add multi-genome SNP pseudo-alignment and CLI export
Release / create-release (push) Successful in 5m58s
Release / build-macos-arm64 (push) Successful in 2m47s
Release / build-linux-x86_64 (push) Successful in 8m50s
CI / build (pull_request) Canceled after 5m42s
Introduces a `SnpAlignment` struct and helper methods to construct per-genome SNP pseudo-alignments from sibling k-mer data, filtering monomorphic families and encoding bases as IUPAC ambiguity codes. Exposes the type at the crate root for simplified imports. Adds a `--snp` CLI flag to compute and export these alignments as an IUPAC-coded FASTA file. Updates theory documentation to propose a multi-genome framing approach for joint phylogenetic inference, resolving pairwise correspondence ambiguities through positional homology and partial coverage thresholds. Bumps crate version to 1.1.40.
2026-08-10 22:38:38 +02:00
Eric Coissac 49f329edd5 feat: add raw SNP distance calculation and CLI flag
Exposes RawSnpDistanceOutput and implements KmerIndex::raw_snp_distance() to compute pairwise single-copy locus counts under a paralogy-aware rule. The implementation leverages ndarray for parallel matrix aggregation, producing raw p-distance matrices for sanity-checking. A --raw-snp-distance CLI flag is added to export results as CSV, mapping zero-eligible pairs to NA.
2026-08-10 22:17:07 +02:00
Eric Coissac 1a470eab9e Refactor k-mer sibling tracking to compact bitmask and on-demand counts
Replaces the explicit `SiblingInfo` struct and 3-bit minorant flags with a derived 4-bit presence mask (`FamilyMask`) that tracks observed bases per family. This eliminates redundant file I/O overhead by introducing a `PartitionCache` for batch lookups, simplifies serialization, and updates all downstream builders, stats computation, and tests to operate on the new bitmask representation. Adjusts CLI output to report deduplicated family sizes instead of histograms, ignores generated CSV files, and updates documentation to reflect the fixed canonical reference and new theory.
2026-08-10 17:53:52 +02:00
Eric Coissac ba990a48a0 feat: add obipipeline for concurrent sibling annex stats
Add the `obipipeline` crate and replace sequential scatter/gather logic with a concurrent pipeline using `Flat` and `Transform` stages. Introduce `SiblingAnnexStats` API to compute distributions, and add CLI flags to `distance.rs` for constructing the annex and exporting statistics as CSV.
2026-08-10 15:31:04 +02:00
Eric Coissac ea914bb536 feat: implement per-k-mer sibling counts and central neighbor generation
Introduce the siblingannex module in obicompactvec to store per-slot minorant flags and sibling counts in a memory-mapped annex file. Add a scatter-gather pipeline in obikindex to compute these values across index layers and write them to .psib files. Implement central_canonical_neighbors in obikseq for generating strand-aware k-mer variants around the middle base. Expose rolling statistics in obiskbuilder and update dependency graphs accordingly.
2026-08-10 15:01:59 +02:00
Eric Coissac 8bc6d533e5 feat: support negative count filters as group size offsets
Updates CLI parsing to accept negative integers for count filters, interpreting them as offsets from the group size (e.g., `-1` means all but one). A resolution closure enforces a floor of 1 to prevent unconstrained filtering on small groups. Additionally, refines evolutionary distance documentation to condition comparisons on local homology, replacing union-based Jaccard with a self-contained `SnpTally`. This unified approach streamlines SNP and shared count computation, incorporates paralogy and heterozygosity handling, and enables direct derivation of corrected distance matrices without external dependencies.
2026-08-10 12:38:35 +02:00
Eric Coissac 45df9919e5 docs: add central-position SNP distance estimator spec
Introduces a design specification for inferring substitution rates directly from k-mers with conserved flanks. The document details a memory-efficient implementation that computes 4x4 base-pair tallies using existing MPHF structures, enabling classical corrections without de Bruijn graph materialization. Updates MkDocs navigation to include the new theory page.
2026-07-10 09:49:49 +02:00
Eric Coissac 2610a4af79 feat: add Mash distance metric and rolling entropy support
Implement the Mash distance metric across the CLI, index, and compact vector traits. This includes adding a `Mash` variant to the `DistanceMetric` enum and `MetricArg` CLI argument, implementing the conversion from Jaccard distances using the standard mutation-rate estimator formula, and updating documentation with supported metrics and algorithmic references. Additionally, add an `entropy` method to rolling statistics for computing order-specific entropy.
2026-07-09 11:40:48 +02:00
Eric Coissac fd2c23e7df refactor: remove equivalence class folding from entropy pipeline
Release / create-release (push) Successful in 2m27s
Release / build-linux-x86_64 (push) Successful in 8m17s
Release / build-macos-arm64 (push) Successful in 1m41s
CI / build (pull_request) Successful in 3m33s
Removes circular-reverse complement machinery and explicit k-mer canonicalization across the entropy pipeline. Frequency tallying and Shannon entropy computation now operate directly on raw k-mer values, eliminating prior score inflation and alignment-dependent artifacts while preserving orientation invariance. Updates build scripts to generate normalized lookup tables for k-mer lengths 1–6, restricts the public API to `EntropyTracker`, and bumps crate versions. Documentation is updated to reflect the simplified raw-value approach and revised module structure.
2026-07-08 19:36:30 +02:00
Eric Coissac 912f788f7f feat: extract k-mer entropy computation into new obikentropy crate
Extracts streaming entropy logic and sliding-window frequency tracking from obiskbuilder into a dedicated obikentropy crate. Introduces an EntropyTracker accumulator for O(1) per-base normalized Shannon entropy, replaces inline rolling statistics with delegated state management, and updates workspace dependencies across obikindex, obikpartitionner, and obiskbuilder. Adds criterion benchmarks to validate the refactored pipeline throughput.
2026-07-08 18:36:16 +02:00
Eric Coissac e725523898 feat: add entropy-driven k-mer complexity filtering
Introduces a MinComplexity filter driven by new CLI arguments, enabling sequence-aware threshold checks during index reconstruction and partitioning. Adds the kmer_entropy module for normalized complexity scoring, updates the KmerFilter trait to evaluate per-kmer context, and refactors test modules for better organization.
2026-07-08 12:48:25 +02:00
Eric Coissac 2740f52326 Bump obikmer version to 1.1.38 and add memory footprint logging
Release / create-release (push) Successful in 2m26s
CI / build (pull_request) Successful in 3m32s
Release / build-linux-x86_64 (push) Successful in 8m8s
Release / build-macos-arm64 (push) Successful in 1m43s
Updates Cargo.toml version from 1.1.37 to 1.1.38. Adds explicit memory footprint estimation for the `by_partition` k-mer dedup HashMap by computing capacity-based byte sizes for map slots and stored descriptors. These metrics are logged via `debug!` to track actual memory pressure during chunk processing.
2026-07-08 12:14:58 +02:00
Eric Coissac eea884f393 ci: improve release workflow and bump obikmer to v1.1.37
Release / create-release (push) Successful in 2m27s
CI / build (pull_request) Successful in 3m32s
Release / build-linux-x86_64 (push) Successful in 8m5s
Release / build-macos-arm64 (push) Successful in 1m41s
Replace inline `docker run` with explicit container lifecycle management to improve isolation and verify exit statuses. Bump `obikmer` crate version to 1.1.37. Add debug logging for sparse hit structure memory tracking, update chunk memory documentation to reflect the Findere rework, and clarify `BYTES_PER_KMER_PER_GENOME` as a pathological bound for safety tuning.
2026-07-07 19:11:50 +02:00
Eric Coissac ae42a061bd perf: optimize k-mer queries with sparse index and run-based aggregation
Replaces the dense `KmerResults` matrix with a sparse `SmerIndex` (`Vec<bool>` + offsets) that tracks k-mer presence independently of per-genome counts. Introduces a new aggregation pass, `sparse_findere_for_genome`, which sorts hits, detects contiguous runs, and applies monotone-deque scans to compute sliding-window minimums. This reduces query complexity from O(n_smers) to O(hits log hits), significantly lowering memory overhead and computational cost for low-density queries. Adds a deterministic PRNG and dense reference oracle in tests to validate correctness against randomized inputs without external property-testing crates.
2026-07-07 18:56:41 +02:00
Eric Coissac 040eff140c refactor(query): optimize mmap locality with column-major matrix fetch
Refactor the query pipeline into a two-stage MPHF hit-detection pass followed by a column-major matrix fetch to improve cache efficiency. Introduce a QueryHit enum for event-driven callbacks, decoupling hit detection from data population. Add scan/fetch metrics to QueryStats, update Phase 4 architecture docs, and align tests with the new callback signature.
2026-07-07 18:44:09 +02:00
Eric Coissac a348637f3b refactor(query): deduplicate k-mers upfront and split MPHF lookup
Refactor `QueryBatch` construction to perform canonical k-mer deduplication and partition routing during initialization, eliminating post-batch splitting. Split the `QueryLayer` MPHF lookup into separate `find_slot` and `fill_row` methods, updating callbacks to pass occurrence descriptors instead of indices. Introduce `QueryStats` for tracking MPHF calls and dereplication ratios, and add comprehensive unit tests for batch construction, stats arithmetic, and safe partition handling. Expose new query-layer types in the public API.
2026-07-07 18:36:25 +02:00
Eric Coissac 9d7ced4493 perf(query): replace static divisor with dynamic overhead multiplier
Replaces the static 16 divisor with a dynamic overhead_multiplier that scales chunk size based on n_genomes, the --detail flag, and a safety factor. This bounds per-chunk memory usage to ≤50% of available RAM across concurrent workers by accounting for genome-scaled k-mer buffers and optional coverage data.
2026-07-07 16:14:10 +02:00
Eric Coissac 9d49929b0c refactor(query): implement throttled per-file streaming pipeline
Replace the flat chunk iterator with a throttled, per-file streaming architecture using `obipipeline::throttle`. The new `GuardedChunkIter` binds file handles to their `ThrottleGuard`, enforcing concurrent open-file limits and tracking active files via an atomic counter. Pipeline stages and the progress spinner are updated to support this resource-aware, parallelized I/O flow.
2026-07-07 16:07:33 +02:00
Eric Coissac 61c390503d feat(query): add throughput metering and --max-open-files flag
Introduces an EMA-based throughput meter that dynamically updates a spinner with MB/s rates, along with atomic counters for tracking cumulative bytes and active chunks. Adds final pipeline reporting and consolidates imports for cleaner performance instrumentation.
2026-07-07 15:19:09 +02:00