Skip to main content

bixverse_core/
prelude.rs

1//! Various functions, structures, etc. to expose more broadly when using this
2//! crate in other libraries
3
4use std::time::Duration;
5use thousands::Separable;
6
7pub use crate::core::math::MAD_SCALE;
8pub use crate::core::math::sparse::{
9    CompressedSparseData2, CompressedSparseFormat, LanczosParams, SparseAxis,
10    parse_compressed_sparse_format,
11};
12pub use crate::errors::*;
13pub use crate::utils::heap_structures::RevOrderedFloat;
14pub use crate::utils::matrix_utils::*;
15pub use crate::utils::simd::BixverseSimd;
16pub use crate::utils::traits::*;
17pub use crate::utils::vec_utils::*;
18pub use crate::{assert_nrows, assert_same_len, assert_symmetric_mat};
19
20////////////
21// Consts //
22////////////
23
24/// Step size, in percent, between progress reports.
25///
26/// Reporting on decile crossings rather than per unit of work bounds the number
27/// of lines a sweep can emit at ten, no matter whether it walks ten blocks or
28/// ten thousand genes.
29const PROGRESS_STEP_PCT: usize = 10;
30
31///////////
32// Enums //
33///////////
34
35/// Enum that controls verbosity
36#[derive(Clone, Copy, Debug, Default)]
37pub enum Verbosity {
38    /// No verbosity at all
39    #[default]
40    Quiet,
41    /// Normal levels of verbosity
42    Normal,
43    /// Detailed verbosity with increased messages
44    Detailed,
45}
46
47impl Verbosity {
48    /// Returns true if normal or detailed verbosity is set
49    pub fn normal_verbosity(&self) -> bool {
50        matches!(self, Verbosity::Normal | Verbosity::Detailed)
51    }
52
53    /// Returns true if detailed verbosity is set
54    pub fn detailed_verbosity(&self) -> bool {
55        matches!(self, Verbosity::Detailed)
56    }
57}
58
59/// Parse verbosity leverl
60///
61/// ### Params
62///
63/// * `level` - If `1` returns [Verbosity::Normal], with `2`
64///   [Verbosity::Detailed]
65///
66/// ### Returns
67///
68/// The desired [Verbosity] level.
69pub fn parse_verbosity_level(level: usize) -> Verbosity {
70    match level {
71        0 => Verbosity::Quiet,
72        1 => Verbosity::Normal,
73        2 => Verbosity::Detailed,
74        _ => Verbosity::Quiet,
75    }
76}
77
78//////////////
79// Progress //
80//////////////
81
82/// Prints a progress line whenever a sweep crosses a decile of its work.
83///
84/// Cheap enough to call on every unit of work: it formats nothing unless `done`
85/// and `prev_done` fall either side of a [PROGRESS_STEP_PCT] boundary, or the
86/// sweep has just finished. The verbosity check stays with the caller, since
87/// not every sweep reports its progress at the same level.
88///
89/// ### Params
90///
91/// * `done` - Units of work finished, including the one just completed
92/// * `prev_done` - Units of work finished before it
93/// * `total` - Units of work in the whole sweep. Nothing prints if this is `0`
94/// * `unit` - What is being counted, e.g. `"genes"`. Printed as given
95/// * `elapsed` - Time since the sweep started
96pub fn report_decile_progress(
97    done: usize,
98    prev_done: usize,
99    total: usize,
100    unit: &str,
101    elapsed: Duration,
102) {
103    if total == 0 {
104        return;
105    }
106
107    let pct = done * 100 / total;
108    let prev_pct = prev_done * 100 / total;
109
110    if pct / PROGRESS_STEP_PCT > prev_pct / PROGRESS_STEP_PCT || done == total {
111        println!(
112            "  Progress: {pct}% ({} / {} {unit}, {elapsed:.2?})",
113            done.separate_with_underscores(),
114            total.separate_with_underscores()
115        );
116    }
117}