Skip to main content

cuttlefish_rs/
lib.rs

1//! External-memory compacted de Bruijn graph construction.
2//!
3//! This crate implements the Rust Cuttlefish 3 pipeline. The production path
4//! intentionally follows the phase ordering of the C++ implementation:
5//!
6//! 1. [`partition`] parses sequences and emits weak super-k-mers into atlas
7//!    buckets.
8//! 2. [`subgraph`] constructs and contracts each local de Bruijn subgraph.
9//! 3. [`discontinuity`] contracts and expands the external discontinuity graph,
10//!    then collates local unitigs into maximal unitigs.
11//! 4. [`color`] stores deduplicated source sets and positional color runs.
12//!
13//! Intermediate formats are private to this implementation. Their compact
14//! layouts, ordering, and bucket fanouts are performance-sensitive; changing
15//! them requires both topology tests and matched scale benchmarks.
16#![warn(rustdoc::broken_intra_doc_links)]
17
18pub mod bgzf;
19pub mod buckets;
20pub mod color;
21pub mod colored;
22pub mod discontinuity;
23pub mod dna;
24pub mod hash;
25pub mod input;
26pub mod kmer;
27pub mod minimizer;
28pub mod params;
29pub mod partition;
30pub mod state;
31pub mod subgraph;
32pub mod uncolored;
33
34/// Default k-mer length used by the CLI.
35pub const DEFAULT_K: u16 = 31;
36/// Default minimizer length used to partition k-mers.
37pub const DEFAULT_MINIMIZER_LEN: u16 = 12;
38/// Default edge-frequency cutoff for sequencing-read input.
39pub const DEFAULT_CUTOFF_READS: u32 = 2;
40/// Default edge-frequency cutoff for reference-sequence input.
41pub const DEFAULT_CUTOFF_REFS: u32 = 1;
42/// Number of atlases in the C++-compatible default partition layout.
43pub const DEFAULT_ATLAS_COUNT: usize = 128;
44/// Number of subgraphs buffered by each atlas.
45pub const DEFAULT_GRAPHS_PER_ATLAS: usize = 128;
46/// Total number of local subgraphs in the default partition layout.
47pub const DEFAULT_SUBGRAPH_COUNT: usize = DEFAULT_ATLAS_COUNT * DEFAULT_GRAPHS_PER_ATLAS;
48/// Number of vertex partitions in the external discontinuity graph.
49pub const DEFAULT_VERTEX_PARTITIONS: usize = 128;
50/// Default number of local-unitig buckets.
51pub const DEFAULT_LMTIG_BUCKETS: usize = 1024;
52/// Default number of maximal-unitig coordinate buckets.
53pub const DEFAULT_GMTIG_BUCKETS: usize = 1024;
54/// Largest k-mer length supported by the packed two-word representation.
55pub const MAX_K: u16 = 63;
56/// Largest supported minimizer length.
57pub const MAX_MINIMIZER_LEN: u16 = 32;
58
59/// Returns the platform temporary directory used for intermediate files.
60pub fn default_work_dir() -> String {
61    std::env::temp_dir().to_string_lossy().into_owned()
62}
63
64/// Returns the default worker count, matching Cuttlefish's quarter-machine policy.
65pub fn default_threads() -> usize {
66    std::thread::available_parallelism()
67        .map(|threads| (threads.get() / 4).max(1))
68        .unwrap_or(8)
69}
70
71/// Configures the process-wide Rayon pool for code paths that use it.
72///
73/// The compact production pipeline primarily uses phase-local pools. Call this
74/// at most once, before performing parallel work.
75pub fn configure_global_parallelism(threads: usize) -> Result<(), rayon::ThreadPoolBuildError> {
76    rayon::ThreadPoolBuilder::new()
77        .num_threads(threads.max(1))
78        .build_global()
79}
80
81/// Side of a canonical k-mer vertex.
82///
83/// `Front` and `Back` describe incidence in the canonical representation, not
84/// the strand chosen for a final unitig label.
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
86pub enum Side {
87    /// The prefix side of the canonical vertex.
88    Front = 0,
89    /// The suffix side of the canonical vertex.
90    Back = 1,
91}
92
93impl Side {
94    /// Returns the opposite side of the vertex.
95    #[inline]
96    pub const fn inverse(self) -> Self {
97        match self {
98            Self::Front => Self::Back,
99            Self::Back => Self::Front,
100        }
101    }
102}
103
104/// Semantic class of sequence input.
105#[derive(Debug, Clone, Copy, PartialEq, Eq)]
106pub enum GraphInput {
107    /// Sequencing reads, for which low-frequency edges are normally filtered.
108    Reads,
109    /// Reference sequences, whose edges are retained by default.
110    References,
111}
112
113impl GraphInput {
114    /// Returns the default edge-frequency cutoff for this input class.
115    #[inline]
116    pub const fn default_cutoff(self) -> u32 {
117        match self {
118            Self::Reads => DEFAULT_CUTOFF_READS,
119            Self::References => DEFAULT_CUTOFF_REFS,
120        }
121    }
122}