diff --git a/python-spec/src/somacore/query/query.py b/python-spec/src/somacore/query/query.py index 1032517e..7dd65b8c 100644 --- a/python-spec/src/somacore/query/query.py +++ b/python-spec/src/somacore/query/query.py @@ -227,6 +227,20 @@ def X( platform_config=platform_config, ) + def obsm(self, layer: str) -> data.SparseRead: + """Returns an ``obsm`` layer as a sparse read. + + Lifecycle: maturing + """ + return self._axism_inner(_Axis.OBS, layer) + + def varm(self, layer: str) -> data.SparseRead: + """Returns an ``varm`` layer as a sparse read. + + Lifecycle: maturing + """ + return self._axism_inner(_Axis.VAR, layer) + def obsp(self, layer: str) -> data.SparseRead: """Returns an ``obsp`` layer as a sparse read. @@ -415,6 +429,25 @@ def _read_axis_dataframe( arrow_table = arrow_table.drop(["soma_joinid"]) return arrow_table + def _axism_inner( + self, + axis: "_Axis", + layer: str, + ) -> data.SparseRead: + key = axis.value + "m" + + if key not in self._ms: + raise ValueError(f"Measurement does not contain {key} data") + + axism = self._ms.obsm if axis is _Axis.OBS else self._ms.varm + if not (layer and layer in axism): + raise ValueError(f"Must specify '{key}' layer") + if not isinstance(axism[layer], data.SparseNDArray): + raise TypeError(f"Unexpected SOMA type stored in '{key}' layer") + + joinids = getattr(self._joinids, axis.value) + return axism[layer].read((joinids, joinids)) + def _axisp_inner( self, axis: "_Axis",