|
1 | | -use std::ops::Deref; |
| 1 | +use std::ops::{Deref, DerefMut}; |
2 | 2 |
|
3 | | -use anndata::{AnnData, AnnDataOp, ArrayData, ArrayElemOp, AxisArrays, Backend, ElemCollection}; |
| 3 | +use anndata::data::DataFrameIndex; |
| 4 | +use anndata::{ |
| 5 | + AnnData, AnnDataOp, ArrayData, ArrayElemOp, AxisArrays, Backend, ElemCollection, |
| 6 | + ElemCollectionOp, |
| 7 | +}; |
| 8 | +use anndata_hdf5::H5; |
4 | 9 | use anyhow::Ok; |
5 | 10 |
|
6 | | -use crate::{ad::helpers::{IMElement, IMAxisArrays}, IMAnnData, IMArrayElement, IMElementCollection}; |
| 11 | +use crate::{ |
| 12 | + ad::helpers::{IMAxisArrays, IMElement}, |
| 13 | + IMAnnData, IMArrayElement, IMElementCollection, |
| 14 | +}; |
7 | 15 |
|
8 | 16 | pub fn convert_to_in_memory<B: Backend>(anndata: AnnData<B>) -> anyhow::Result<IMAnnData> { |
9 | | - let obs_df = anndata.read_obs()?; |
| 17 | + let obs_df = anndata.read_obs()?; |
10 | 18 | let obs_names = anndata.obs_names(); |
11 | 19 | let var_df = anndata.read_var()?; |
12 | 20 | let var_names = anndata.var_names(); |
13 | 21 | let x = anndata.x().get::<ArrayData>()?.unwrap(); |
14 | | - let imad = IMAnnData::new_extended(x, obs_names.into_vec(), var_names.into_vec(), obs_df, var_df)?; |
| 22 | + let imad = IMAnnData::new_extended( |
| 23 | + x, |
| 24 | + obs_names.into_vec(), |
| 25 | + var_names.into_vec(), |
| 26 | + obs_df, |
| 27 | + var_df, |
| 28 | + )?; |
15 | 29 | convert_axis_arrays_to_mem(anndata.obsm(), imad.obsm())?; |
16 | 30 | convert_axis_arrays_to_mem(anndata.obsp(), imad.obsp())?; |
17 | 31 | convert_axis_arrays_to_mem(anndata.varm(), imad.varm())?; |
18 | 32 | convert_axis_arrays_to_mem(anndata.varp(), imad.varp())?; |
| 33 | + convert_axis_arrays_to_mem(anndata.layers(), imad.layers())?; |
19 | 34 | convert_uns_to_mem(anndata.uns(), imad.uns())?; |
20 | 35 | anndata.close()?; |
21 | 36 | Ok(imad) |
22 | 37 | } |
23 | 38 |
|
24 | | -fn convert_axis_arrays_to_mem<B: Backend>(axis_arr: &AxisArrays<B>, reference_element: IMAxisArrays) -> anyhow::Result<()> { |
| 39 | +fn convert_axis_arrays_to_mem<B: Backend>( |
| 40 | + axis_arr: &AxisArrays<B>, |
| 41 | + reference_element: IMAxisArrays, |
| 42 | +) -> anyhow::Result<()> { |
25 | 43 | if axis_arr.is_none() { |
26 | 44 | return Ok(()); |
27 | 45 | } |
28 | 46 | let x = axis_arr.inner(); |
29 | 47 | let iax = x.deref(); |
30 | 48 | let data = iax.deref(); |
31 | | - for (k,v) in data.iter() { |
| 49 | + for (k, v) in data.iter() { |
32 | 50 | let arr = v.get::<ArrayData>()?.unwrap(); |
33 | 51 | let im_arr = IMArrayElement::new(arr); |
34 | 52 | reference_element.add_array(k.to_string(), im_arr)?; |
35 | 53 | } |
36 | 54 | Ok(()) |
37 | 55 | } |
38 | 56 |
|
39 | | -fn convert_uns_to_mem<B: Backend>(elem_col: &ElemCollection<B>, reference_element: IMElementCollection) -> anyhow::Result<()> { |
| 57 | +fn convert_uns_to_mem<B: Backend>( |
| 58 | + elem_col: &ElemCollection<B>, |
| 59 | + reference_element: IMElementCollection, |
| 60 | +) -> anyhow::Result<()> { |
40 | 61 | if elem_col.is_none() { |
41 | 62 | return Ok(()); |
42 | 63 | } |
43 | 64 | let x = elem_col.inner(); |
44 | 65 | let iax = x.deref(); |
45 | 66 | let data = iax.deref(); |
46 | | - for (k,v) in data.iter() { |
| 67 | + for (k, v) in data.iter() { |
47 | 68 | let data = v.inner().data(); |
48 | 69 | let d = IMElement::new(data?); |
49 | 70 | reference_element.add_data(k.to_string(), d)?; |
50 | 71 | } |
51 | 72 | Ok(()) |
52 | 73 | } |
| 74 | + |
| 75 | +fn convert_axis_arrays_to_backed<B: Backend>( |
| 76 | + reference: IMAxisArrays, |
| 77 | + target_axis_arrays: &AxisArrays<B>, |
| 78 | +) -> anyhow::Result<()> { |
| 79 | + if reference.is_empty() { |
| 80 | + return Ok(()); |
| 81 | + } |
| 82 | + |
| 83 | + for key in reference.keys() { |
| 84 | + let value = reference.get_array(&key)?; |
| 85 | + let array_data = value.get_data()?; |
| 86 | + let mut guard = target_axis_arrays.lock(); |
| 87 | + let data = guard.deref_mut(); |
| 88 | + match (data) { |
| 89 | + None => {} |
| 90 | + Some(data) => data.add_data(&key, array_data)?, |
| 91 | + }; |
| 92 | + } |
| 93 | + |
| 94 | + Ok(()) |
| 95 | +} |
| 96 | + |
| 97 | +fn convert_uns_to_backed<B: Backend>( |
| 98 | + reference: IMElementCollection, |
| 99 | + target_file: &AnnData<B>, |
| 100 | +) -> anyhow::Result<()> { |
| 101 | + let uns = target_file.uns(); |
| 102 | + |
| 103 | + let keys = { |
| 104 | + let read_guard = reference.0.read_inner(); |
| 105 | + read_guard.keys().cloned().collect::<Vec<String>>() |
| 106 | + }; |
| 107 | + |
| 108 | + for key in keys { |
| 109 | + let val = reference.get_data(&key)?; |
| 110 | + { |
| 111 | + let elem_data = val.get_data()?; |
| 112 | + |
| 113 | + // Lock the uns structure and update it |
| 114 | + let mut guard = uns.lock(); |
| 115 | + let data = guard.deref_mut(); |
| 116 | + if let Some(data) = data { |
| 117 | + data.add_data(&key, elem_data)?; |
| 118 | + } |
| 119 | + } |
| 120 | + } |
| 121 | + Ok(()) |
| 122 | +} |
| 123 | + |
| 124 | +pub fn convert_to_backed<B: Backend>(imad: &IMAnnData, anndata: &AnnData<B>) -> anyhow::Result<()> { |
| 125 | + let x_data = imad.x().get_data()?; |
| 126 | + anndata.set_x(x_data)?; |
| 127 | + |
| 128 | + anndata.set_obs(imad.obs().get_data())?; |
| 129 | + anndata.set_obs_names(DataFrameIndex::from(imad.obs_names()))?; |
| 130 | + anndata.set_var(imad.var().get_data())?; |
| 131 | + anndata.set_var_names(DataFrameIndex::from(imad.var_names()))?; |
| 132 | + |
| 133 | + convert_axis_arrays_to_backed(imad.obsm(), anndata.obsm())?; |
| 134 | + convert_axis_arrays_to_backed(imad.obsp(), anndata.obsp())?; |
| 135 | + convert_axis_arrays_to_backed(imad.varm(), anndata.varm())?; |
| 136 | + convert_axis_arrays_to_backed(imad.varp(), anndata.varp())?; |
| 137 | + |
| 138 | + convert_axis_arrays_to_backed(imad.layers(), anndata.layers())?; |
| 139 | + |
| 140 | + convert_uns_to_backed(imad.uns(), anndata)?; |
| 141 | + |
| 142 | + Ok(()) |
| 143 | +} |
| 144 | + |
| 145 | +pub fn convert_to_new_backed_h5( |
| 146 | + imad: &IMAnnData, |
| 147 | + path: impl AsRef<std::path::Path>, |
| 148 | +) -> anyhow::Result<AnnData<H5>> { |
| 149 | + let anndata = AnnData::<H5>::new(path)?; |
| 150 | + |
| 151 | + convert_to_backed(imad, &anndata)?; |
| 152 | + |
| 153 | + Ok(anndata) |
| 154 | +} |
0 commit comments