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}