Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initializing AnnData without X but with layers errors #1816

Open
3 tasks done
ilan-gold opened this issue Jan 9, 2025 · 1 comment
Open
3 tasks done

Initializing AnnData without X but with layers errors #1816

ilan-gold opened this issue Jan 9, 2025 · 1 comment
Labels
Milestone

Comments

@ilan-gold
Copy link
Contributor

Please make sure these conditions are met

  • I have checked that this issue has not already been reported.
  • I have confirmed this bug exists on the latest version of anndata.
  • (optional) I have confirmed this bug exists on the master branch of anndata.

Report

See COMBINE-lab/alevin-fry#151 (comment) and below for discussion. I think this problem could in theory be responsible, but also it might be unlikely. TBD

Code:

import anndata as ad
import numpy as np

ad.AnnData(X=None, layers={"foo": np.arange(4).reshape((2, 2)), "bar": np.arange(4).reshape((2, 2))}) # errors, probably erroneously

vs.

import anndata as ad
import numpy as np

adata = ad.AnnData(X=np.arange(4).reshape((2, 2)), layers={"foo": np.arange(4).reshape((2, 2)), "bar": np.arange(4).reshape((2, 2))})
del adata.X
adata.write_h5ad("foo.h5ad")
ad.read_h5ad("foo.h5ad").X == None

So I think it's something in __init__.

Traceback:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[4], line 1
----> 1 ad.AnnData(X=None, layers={"foo": np.arange(4).reshape((2, 2)), "bar": np.arange(4).reshape((2, 2))})

File ~/Projects/Theis/scanpy/venv/lib/python3.12/site-packages/anndata/_core/anndata.py:252, in AnnData.__init__(self, X, obs, var, uns, obsm, varm, layers, raw, dtype, shape, filename, filemode, asview, obsp, varp, oidx, vidx)
    250     self._init_as_view(X, oidx, vidx)
    251 else:
--> 252     self._init_as_actual(
    253         X=X,
    254         obs=obs,
    255         var=var,
    256         uns=uns,
    257         obsm=obsm,
    258         varm=varm,
    259         raw=raw,
    260         layers=layers,
    261         dtype=dtype,
    262         shape=shape,
    263         obsp=obsp,
    264         varp=varp,
    265         filename=filename,
    266         filemode=filemode,
    267     )

File ~/Projects/Theis/scanpy/venv/lib/python3.12/site-packages/anndata/_core/anndata.py:471, in AnnData._init_as_actual(self, X, obs, var, uns, obsm, varm, varp, obsp, raw, layers, dtype, shape, filename, filemode)
    468 self._clean_up_old_format(uns)
    470 # layers
--> 471 self.layers = layers

File ~/Projects/Theis/scanpy/venv/lib/python3.12/site-packages/anndata/_core/aligned_mapping.py:435, in AlignedMappingProperty.__set__(self, obj, value)
    431 def __set__(
    432     self, obj: AnnData, value: Mapping[str, Value] | Iterable[tuple[str, Value]]
    433 ) -> None:
    434     value = convert_to_dict(value)
--> 435     _ = self.construct(obj, store=value)  # Validate
    436     if obj.is_view:
    437         obj._init_as_actual(obj.copy())

File ~/Projects/Theis/scanpy/venv/lib/python3.12/site-packages/anndata/_core/aligned_mapping.py:407, in AlignedMappingProperty.construct(self, obj, store)
    405 def construct(self, obj: AnnData, *, store: MutableMapping[str, Value]) -> T:
    406     if self.axis is None:
--> 407         return self.cls(obj, store=store)
    408     return self.cls(obj, axis=self.axis, store=store)

File ~/Projects/Theis/scanpy/venv/lib/python3.12/site-packages/anndata/_core/aligned_mapping.py:210, in AlignedActual.__init__(self, parent, store)
    208 self._data = store
    209 for k, v in self._data.items():
--> 210     self._data[k] = self._validate_value(v, k)

File ~/Projects/Theis/scanpy/venv/lib/python3.12/site-packages/anndata/_core/aligned_mapping.py:97, in AlignedMappingBase._validate_value(self, val, key)
     91         dims = tuple(("obs", "var")[ax] for ax in self.axes)
     92         msg = (
     93             f"Value passed for key {key!r} is of incorrect shape. "
     94             f"Values of {self.attrname} must match dimensions {dims} of parent. "
     95             f"Value had shape {actual_shape} while it should have had {right_shape}."
     96         )
---> 97     raise ValueError(msg)
     99 name = f"{self.attrname.title().rstrip('s')} {key!r}"
    100 return coerce_array(val, name=name, allow_df=self._allow_df)

ValueError: Value passed for key 'foo' is of incorrect shape. Values of layers must match dimensions ('obs', 'var') of parent. Value had shape (2, 2) while it should have had (0, 0).

Versions

| Package | Version |
| ------- | ------- |
| numpy   | 2.1.3   |

| Dependency                    | Version     |
| ----------------------------- | ----------- |
| parso                         | 0.8.4       |
| more-itertools                | 10.3.0      |
| jaraco.collections            | 5.1.0       |
| packaging                     | 24.2        |
| sphinxcontrib-devhelp         | 2.0.0       |
| jaraco.functools              | 4.0.1       |
| psutil                        | 6.1.0       |
| prompt_toolkit                | 3.0.48      |
| python-dateutil               | 2.9.0.post0 |
| jaraco.context                | 5.3.0       |
| decorator                     | 5.1.1       |
| stack-data                    | 0.6.3       |
| charset-normalizer            | 3.4.1       |
| rich                          | 13.9.4      |
| awkward                       | 2.7.2       |
| numcodecs                     | 0.14.1      |
| traitlets                     | 5.14.3      |
| sparse                        | 0.16.0a9    |
| pyarrow                       | 18.1.0      |
| wcwidth                       | 0.2.13      |
| sphinxcontrib-htmlhelp        | 2.1.0       |
| jaraco.text                   | 3.12.1      |
| numba                         | 0.61.0rc1   |
| sphinxcontrib-serializinghtml | 2.0.0       |
| six                           | 1.17.0      |
| legacy-api-wrap               | 1.4.1       |
| Jinja2                        | 3.1.4       |
| fsspec                        | 2024.10.0   |
| attrs                         | 24.2.0      |
| sphinxcontrib-qthelp          | 2.0.0       |
| Pygments                      | 2.18.0      |
| llvmlite                      | 0.44.0rc1   |
| zarr                          | 2.18.3      |
| zappy                         | 0.2.0       |
| dask                          | 2024.7.1    |
| pandas                        | 2.2.3       |
| toolz                         | 1.0.0       |
| pytz                          | 2024.2      |
| msgpack                       | 1.1.0       |
| sphinxcontrib-jsmath          | 1.0.1       |
| cloudpickle                   | 3.1.0       |
| tblib                         | 3.0.0       |
| asttokens                     | 3.0.0       |
| MarkupSafe                    | 3.0.2       |
| asciitree                     | 0.3.3       |
| sphinxcontrib-bibtex          | 2.6.3       |
| ipython                       | 8.31.0      |
| setuptools-scm                | 8.1.0       |
| PyYAML                        | 6.0.2       |
| scipy                         | 1.14.1      |
| coverage                      | 7.6.8       |
| session-info2                 | 0.1.2       |
| sphinxcontrib-applehelp       | 2.0.0       |
| natsort                       | 8.4.0       |
| h5py                          | 3.12.1      |
| pure_eval                     | 0.2.3       |
| jedi                          | 0.19.2      |
| awkward_cpp                   | 43          |
| executing                     | 2.1.0       |
| setuptools                    | 75.6.0      |

| Component | Info                                                                                |
| --------- | ----------------------------------------------------------------------------------- |
| Python    | 3.12.3 | packaged by Anaconda, Inc. | (main, May  6 2024, 14:46:42) [Clang 14.0.6 ] |
| OS        | macOS-15.1-arm64-arm-64bit                                                          |
| Updated   | 2025-01-09 15:41                                                                    |
@rob-p
Copy link

rob-p commented Jan 10, 2025

Thanks for raising this issue @ilan-gold. Given that you're able to trigger the same directly reading and writing from the anndata package suggests it's not an issue specific to the Rust package (or my use of it), but rather is related to an absent X layer when loading in the object itself using the AnnData initialization method, as you suggest. I also see this when I load in the file with anndata.read which, I presume, internally calls the relevant __init__ method?

@ilan-gold ilan-gold modified the milestones: 0.11.3, 0.11.4 Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants