Skip to content

Commit 55a53a1

Browse files
committed
fix reading anndatas with .raw attributes (closes #142)
(cherry picked from commit 9783f74)
1 parent d89f36e commit 55a53a1

4 files changed

Lines changed: 26 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ and this project adheres to [Semantic Versioning][].
1717
- The settings API has changed. Use e.g. `mudata.settings.pull_on_update = True` instead of `mudata.set_options(pull_on_update=True)` and use
1818
`mudata.settings.override` as context manager for local settings overrides.
1919

20+
## [0.3.7]
21+
22+
### Fixed
23+
24+
- MuData objects with modalities containing `.raw` attributes can once again be read from disk.
25+
2026
## [0.3.6]
2127

2228
### Fixed
@@ -166,6 +172,7 @@ To copy the annotations explicitly, you will need to use `pull_obs()` and/or `pu
166172
Initial `mudata` release with `MuData`, previously a part of the `muon` framework.
167173

168174
[0.4.0]: https://github.com/scverse/mudata/releases/tag/v0.4.0
175+
[0.3.7]: https://github.com/scverse/mudata/releases/tag/v0.3.7
169176
[0.3.6]: https://github.com/scverse/mudata/releases/tag/v0.3.6
170177
[0.3.5]: https://github.com/scverse/mudata/releases/tag/v0.3.5
171178
[0.3.4]: https://github.com/scverse/mudata/releases/tag/v0.3.4

src/mudata/_core/io.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ def _write_h5mu(file: h5py.File, mdata: MuData, write_data=True, **kwargs):
6767
if write_data or not adata.isbacked:
6868
write_elem(group, "X", adata.X, dataset_kwargs=kwargs)
6969
if adata.raw is not None:
70-
write_elem(group, "raw", adata.raw)
70+
if not adata.isbacked:
71+
write_elem(group, "raw", adata.raw, dataset_kwargs=kwargs)
72+
else:
73+
rawgrp = group.require_group("raw")
74+
write_elem(rawgrp, "var", adata.raw.var, dataset_kwargs=kwargs)
75+
write_elem(rawgrp, "varm", dict(adata.raw.varm), dataset_kwargs=kwargs)
7176

7277
write_elem(group, "obs", adata.obs, dataset_kwargs=kwargs)
7378
write_elem(group, "var", adata.var, dataset_kwargs=kwargs)
@@ -168,7 +173,12 @@ def write_zarr(
168173
else:
169174
write_elem(group, "X", adata.X, dataset_kwargs=kwargs)
170175
if adata.raw is not None:
171-
write_elem(group, "raw", adata.raw)
176+
if write_data or not adata.isbacked:
177+
write_elem(group, "raw", adata.raw, dataset_kwargs=kwargs)
178+
else:
179+
rawgrp = group.require_group("raw")
180+
write_elem(rawgrp, "var", adata.raw.var, dataset_kwargs=kwargs)
181+
write_elem(rawgrp, "varm", dict(adata.raw.varm), dataset_kwargs=kwargs)
172182

173183
write_elem(group, "obs", adata.obs, dataset_kwargs=kwargs)
174184
write_elem(group, "var", adata.var, dataset_kwargs=kwargs)

tests/conftest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def rng() -> np.random.Generator:
3434

3535

3636
@pytest.fixture
37-
def mdata(rng: np.random.Generator, request: pytest.FixtureRequest):
37+
def mdata(rng: np.random.Generator, request: pytest.FixtureRequest) -> MuData:
3838
axis = getattr(request, "param", 0)
3939
mod1 = AnnData(
4040
np.arange(0, 200, 0.1).reshape(-1, 20), obs=pd.DataFrame(index=rng.choice(150, size=100, replace=False))
@@ -46,6 +46,8 @@ def mdata(rng: np.random.Generator, request: pytest.FixtureRequest):
4646
mod2.var["assert-bool"] = False
4747
mod1.var["assert-boolean-1"] = True
4848
mod2.var["assert-boolean-2"] = False
49+
50+
mod1.raw = mod1[:, :10].copy()
4951
mods = {"mod2": mod2, "mod1": mod1}
5052

5153
attr = "obs" if axis == 0 else "var"

tests/test_view_copy.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,14 @@ def _test_view_after_setattr(mdata: md.MuData, mdata_ref: md.MuData, skip: Seque
191191

192192
for k, v in mdata.obsm.items():
193193
if k in mdata_ref.obsm:
194-
assert v.shape[1] == mdata_ref.obsm[k].shape[1]
194+
if v.ndim > 1:
195+
assert v.shape[1] == mdata_ref.obsm[k].shape[1]
195196
if isinstance(v, pd.DataFrame):
196197
assert (v.columns == mdata_ref.obsm[k].columns).all()
197198
for k, v in mdata.varm.items():
198199
if k in mdata_ref.varm:
199-
assert v.shape[1] == mdata_ref.obsm[k].shape[1]
200+
if v.ndim > 1:
201+
assert v.shape[1] == mdata_ref.obsm[k].shape[1]
200202
if isinstance(v, pd.DataFrame):
201203
assert (v.columns == mdata_ref.varm[k].columns).all()
202204

0 commit comments

Comments
 (0)