mod backed;
pub mod memory;
mod dataset;
pub use backed::AnnData;
pub use memory::PyAnnData;
pub use dataset::AnnDataSet;
use anndata;
use anndata::Backend;
use anndata_hdf5::H5;
use pyo3::prelude::*;
use std::{path::PathBuf, collections::HashMap};
use anyhow::Result;
#[pyfunction]
#[pyo3(
signature = (filename, backed="r+", backend=None),
text_signature = "(filename, backed='r+', backend=None)",
)]
pub fn read<'py>(py: Python<'py>, filename: PathBuf, backed: Option<&str>, backend: Option<&str>) -> Result<PyObject> {
let adata = match backed {
Some(m) => AnnData::new_from(filename, m, backend).unwrap().into_py(py),
None => PyModule::import(py, "anndata")?
.getattr("read_h5ad")?
.call1((filename,))?
.to_object(py),
};
Ok(adata)
}
#[pyfunction]
#[pyo3(
signature = (mtx_file, *, obs_names=None, var_names=None, file=None, backend=None, sorted=false),
text_signature = "(mtx_file, *, obs_names=None, var_names=None, file=None, backend=None, sorted=False)",
)]
pub fn read_mtx(
py: Python<'_>,
mtx_file: PathBuf,
obs_names: Option<PathBuf>,
var_names: Option<PathBuf>,
file: Option<PathBuf>,
backend: Option<&str>,
sorted: bool,
) -> Result<PyObject> {
let mut reader = anndata::reader::MMReader::from_path(mtx_file)?;
if let Some(obs_names) = obs_names {
reader = reader.obs_names(obs_names)?;
}
if let Some(var_names) = var_names {
reader = reader.var_names(var_names)?;
}
if sorted {
reader = reader.is_sorted();
}
if let Some(file) = file {
match backend.unwrap_or(H5::NAME) {
H5::NAME => {
let adata = anndata::AnnData::<H5>::new(file)?;
reader.finish(&adata)?;
Ok(AnnData::from(adata).into_py(py))
},
backend => todo!("Backend {} is not supported", backend),
}
} else {
let adata = PyAnnData::new(py)?;
reader.finish(&adata)?;
Ok(adata.to_object(py))
}
}
#[pyfunction]
#[pyo3(
signature = (filename, *, update_data_locations=None, mode="r+", backend=None),
text_signature = "(filename, *, update_data_locations=None, mode='r+', backend=None)",
)]
pub fn read_dataset(
filename: PathBuf,
update_data_locations: Option<HashMap<String, String>>,
mode: &str,
backend: Option<&str>,
) -> Result<AnnDataSet> {
match backend.unwrap_or(H5::NAME) {
H5::NAME => {
let file = match mode {
"r" => H5::open(filename)?,
"r+" => H5::open_rw(filename)?,
_ => panic!("Unkown mode"),
};
Ok(anndata::AnnDataSet::<H5>::open(file, update_data_locations)?.into())
},
_ => todo!(),
}
}