use std::path::Path;
use thousands::Separable;
use crate::core::math::sparse::transpose_sparse;
use crate::prelude::*;
use crate::single_cell::sc_data::data_io::{CellGeneSparseWriter, write_cell_chunks_parallel};
pub fn write_r_counts<P: AsRef<Path>, T>(
bin_path: P,
compressed_data: CompressedSparseData2<T>,
cell_quality: MinCellQuality,
verbose: bool,
) -> Result<(usize, usize, CellQuality), BixverseErrors>
where
T: BixverseNumeric + Into<f64> + Into<u32>,
{
let (no_cells, no_genes) = compressed_data.shape();
if verbose {
println!(
"Processing R sparse matrix (shape: {} x {})...",
no_cells.separate_with_underscores(),
no_genes.separate_with_underscores()
);
}
match compressed_data.cs_type {
CompressedSparseFormat::Csr => {
write_r_counts_csr(bin_path, compressed_data, cell_quality, verbose)
}
CompressedSparseFormat::Csc => {
if verbose {
println!("Converting CSC to CSR...");
}
let csr_data = transpose_sparse(&compressed_data);
write_r_counts_csr(bin_path, csr_data, cell_quality, verbose)
}
}
}
pub fn write_r_counts_csr<P: AsRef<Path>, T>(
bin_path: P,
compressed_data: CompressedSparseData2<T>,
cell_quality: MinCellQuality,
verbose: bool,
) -> Result<(usize, usize, CellQuality), BixverseErrors>
where
T: BixverseNumeric + Into<f64> + Into<u32>,
{
let (no_cells, no_genes) = compressed_data.shape();
if verbose {
println!("Generating cell chunks...");
}
let target_size = cell_quality.target_size;
let (cell_chunk_vec, cell_qc): (Vec<CsrCellChunk>, CellQuality) =
CsrCellChunk::generate_chunks_sparse_data(compressed_data, cell_quality);
let cells_passing = cell_qc.cell_indices.len();
let genes_passing = cell_qc.gene_indices.len();
if verbose {
println!(
"Cells passing QC: {} / {}",
cells_passing.separate_with_underscores(),
no_cells.separate_with_underscores()
);
println!(
"Genes passing QC: {} / {}",
genes_passing.separate_with_underscores(),
no_genes.separate_with_underscores()
);
println!("Writing to binary format...");
}
let mut writer =
CellGeneSparseWriter::new(bin_path, true, cells_passing, genes_passing, target_size)?;
let mut passing_chunks: Vec<_> = cell_chunk_vec
.into_iter()
.filter(|chunk| chunk.to_keep)
.collect();
for (new_idx, chunk) in passing_chunks.iter_mut().enumerate() {
chunk.original_index = new_idx;
}
write_cell_chunks_parallel(&passing_chunks, &mut writer)?;
if verbose {
println!(
" Written {} / {} cells (complete).",
cells_passing.separate_with_underscores(),
cells_passing.separate_with_underscores()
);
println!("Finalising file...");
}
writer.finalise()?;
Ok((cells_passing, genes_passing, cell_qc))
}