From 720cdc50e3e5c915151f78295ad310d52f75235d Mon Sep 17 00:00:00 2001 From: Yi Su <90744702+suu-yi@users.noreply.github.com> Date: Wed, 5 Nov 2025 14:05:52 +0100 Subject: [PATCH 1/4] Update test_datastore.py --- scarf/tests/test_datastore.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scarf/tests/test_datastore.py b/scarf/tests/test_datastore.py index 6f67d2e..3e3d476 100644 --- a/scarf/tests/test_datastore.py +++ b/scarf/tests/test_datastore.py @@ -193,7 +193,7 @@ def test_run_pseudotime_marker_search(self, pseudotime_markers): def test_run_pseudotime_aggregation(self, pseudotime_aggregation, datastore): precalc_values = np.load(full_path("aggregated_feat_idx.npy")) test_values = datastore.z.RNA.aggregated_I_I_RNA_pseudotime.feature_indices[:] - assert np.all(precalc_values == test_values) + assert np.array_equal(precalc_values.astype(np.int64), test_values.astype(np.int64)) precalc_values = np.load(full_path("aggregated_df_top_10.npy")) test_values = datastore.z.RNA.aggregated_I_I_RNA_pseudotime.data[:10] From 9155eb17753ed1d8643660985b58932c02770cc6 Mon Sep 17 00:00:00 2001 From: Yi Su <90744702+suu-yi@users.noreply.github.com> Date: Wed, 19 Nov 2025 14:31:05 +0100 Subject: [PATCH 2/4] Update readers.py --- scarf/readers.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/scarf/readers.py b/scarf/readers.py index 148059f..ae70f97 100644 --- a/scarf/readers.py +++ b/scarf/readers.py @@ -772,7 +772,7 @@ def feat_names(self) -> np.ndarray: if self.groupCodes[self.featureAttrsKey] == 1: values = self.h5[self.featureAttrsKey][self.featNamesKey] else: - values = self.h5[self.featureAttrsKey][self.featNamesKey][:] + values = self.h5[self.featureAttrsKey][self.featNamesKey] return self._replace_category_values( values, self.featNamesKey, self.featureAttrsKey ).astype(object) @@ -782,6 +782,25 @@ def feat_names(self) -> np.ndarray: return self.feat_ids() def _replace_category_values(self, v: np.ndarray, key: str, group: str): + # check if v is a Group with codes + categories structure + if isinstance(v, h5py.Group): + if "codes" in v and "categories" in v: + codes = v["codes"][:] + categories = v["categories"][:] + try: + return np.array([categories[x] for x in codes]) + except (IndexError, TypeError): + logger.warning(f"Failed to decode categorical data for {key}") + return np.array([f"feature_{x}" for x in range(len(codes))]) + else: + # It's a Group but doesn't have the expected structure, try to read it as dataset + logger.warning(f"{key} is a Group but missing 'codes' or 'categories', attempting to extract data") + return v[:] + + # if v is a Dataset + if isinstance(v, h5py.Dataset): + v = v[:] + if self.catNamesKey is not None: if self._check_exists(group, self.catNamesKey): cat_g = self.h5[group][self.catNamesKey] From 95e470715604b223f23e88fb43ca8f488fe4baf3 Mon Sep 17 00:00:00 2001 From: Yi Su <90744702+suu-yi@users.noreply.github.com> Date: Wed, 19 Nov 2025 17:11:53 +0100 Subject: [PATCH 3/4] clean up --- scarf/readers.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scarf/readers.py b/scarf/readers.py index ae70f97..7120aef 100644 --- a/scarf/readers.py +++ b/scarf/readers.py @@ -769,10 +769,7 @@ def feat_ids(self) -> np.ndarray: def feat_names(self) -> np.ndarray: """Returns a list of feature names.""" if self._check_exists(self.featureAttrsKey, self.featNamesKey): - if self.groupCodes[self.featureAttrsKey] == 1: - values = self.h5[self.featureAttrsKey][self.featNamesKey] - else: - values = self.h5[self.featureAttrsKey][self.featNamesKey] + values = self.h5[self.featureAttrsKey][self.featNamesKey] return self._replace_category_values( values, self.featNamesKey, self.featureAttrsKey ).astype(object) From f15a57aa2667bf48ea8760844a407d2e6a971c8a Mon Sep 17 00:00:00 2001 From: Yi Su <90744702+suu-yi@users.noreply.github.com> Date: Wed, 19 Nov 2025 17:15:23 +0100 Subject: [PATCH 4/4] fix typing --- scarf/readers.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scarf/readers.py b/scarf/readers.py index 7120aef..e1618c7 100644 --- a/scarf/readers.py +++ b/scarf/readers.py @@ -12,7 +12,7 @@ import math import os from abc import ABC, abstractmethod -from typing import IO, Dict, Generator, List, Optional, Tuple +from typing import IO, Dict, Generator, List, Optional, Tuple, Union import h5py import numpy as np @@ -778,7 +778,9 @@ def feat_names(self) -> np.ndarray: ) return self.feat_ids() - def _replace_category_values(self, v: np.ndarray, key: str, group: str): + def _replace_category_values( + self, v: Union[np.ndarray, h5py.Group, h5py.Dataset], key: str, group: str + ) -> np.ndarray: # check if v is a Group with codes + categories structure if isinstance(v, h5py.Group): if "codes" in v and "categories" in v: