Skip to content

Commit c8b0120

Browse files
NickAkhmetov/Add support for obs_labels_names and obs_labels_paths arrays (#272)
* Add support for `obs_labels_names` and `obs_labels_paths` arrays * deprecate old `obs_labels_path`, fix some markdown * fix ambiguous variable name error * Apply suggestions from code review Co-authored-by: Mark Keller <[email protected]> --------- Co-authored-by: Mark Keller <[email protected]>
1 parent 0ca6319 commit c8b0120

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

tests/create_test_data.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,11 @@ def create_test_anndata_file(h5ad_path):
139139
'exPFC2',
140140
'GABA2'
141141
]
142+
obs_cell_label_arr = [f'{obs_label}-label' for obs_label in obs_celltype_arr]
142143
obs_df = pd.DataFrame(
143144
data=[
144-
{'index': i, 'CellType': ct}
145-
for i, ct in zip(obs_index_arr, obs_celltype_arr)
145+
{'index': i, 'CellType': ct, 'CellLabel': cl}
146+
for i, ct, cl in zip(obs_index_arr, obs_celltype_arr, obs_cell_label_arr)
146147
]
147148
)
148149
obsm = {"X_umap": np.array([[0, 1] for c in obs_index_arr])}

tests/test_wrappers.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,19 @@ def test_ome_zarr_with_base_dir(self):
141141

142142
def test_anndata(self):
143143
adata_path = data_path / 'test.h5ad.zarr'
144-
w = AnnDataWrapper(adata_path, obs_set_paths=['obs/CellType'], obs_set_names=['Cell Type'], obs_embedding_paths=[
145-
'obsm/X_umap'], obs_embedding_names=['UMAP'])
144+
w = AnnDataWrapper(adata_path,
145+
obs_set_paths=['obs/CellType'], obs_set_names=['Cell Type'],
146+
obs_labels_names=['Cell Label'], obs_labels_paths=['obs/CellLabel'],
147+
obs_embedding_paths=['obsm/X_umap'], obs_embedding_names=['UMAP'])
146148
w.local_dir_uid = 'anndata.zarr'
147149

148150
file_def_creator = w.make_file_def_creator('A', 0)
149151
file_def = file_def_creator('http://localhost:8000')
150152
self.assertEqual(file_def, {'fileType': 'anndata.zarr', 'url': 'http://localhost:8000/A/0/anndata.zarr',
151153
'options': {
152154
'obsEmbedding': [{'path': 'obsm/X_umap', 'embeddingType': 'UMAP', 'dims': [0, 1]}],
153-
'obsSets': [{'path': 'obs/CellType', 'name': 'Cell Type'}]
155+
'obsSets': [{'path': 'obs/CellType', 'name': 'Cell Type'}],
156+
'obsLabels': [{'path': 'obs/CellLabel', 'obsLabelsType': 'Cell Label'}]
154157
}})
155158

156159
def test_anndata_with_base_dir(self):

vitessce/wrappers.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ def create_image_json(self, img_url):
506506

507507

508508
class AnnDataWrapper(AbstractWrapper):
509-
def __init__(self, adata_path=None, adata_url=None, obs_feature_matrix_path=None, feature_filter_path=None, initial_feature_filter_path=None, obs_set_paths=None, obs_set_names=None, obs_locations_path=None, obs_segmentations_path=None, obs_embedding_paths=None, obs_embedding_names=None, obs_embedding_dims=None, request_init=None, feature_labels_path=None, obs_labels_path=None, convert_to_dense=True, coordination_values=None, **kwargs):
509+
def __init__(self, adata_path=None, adata_url=None, obs_feature_matrix_path=None, feature_filter_path=None, initial_feature_filter_path=None, obs_set_paths=None, obs_set_names=None, obs_locations_path=None, obs_segmentations_path=None, obs_embedding_paths=None, obs_embedding_names=None, obs_embedding_dims=None, request_init=None, feature_labels_path=None, obs_labels_path=None, convert_to_dense=True, coordination_values=None, obs_labels_paths=None, obs_labels_names=None, **kwargs):
510510
"""
511511
Wrap an AnnData object by creating an instance of the ``AnnDataWrapper`` class.
512512
@@ -516,15 +516,17 @@ def __init__(self, adata_path=None, adata_url=None, obs_feature_matrix_path=None
516516
:param str feature_filter_path: A string like `var/highly_variable` used in conjunction with `obs_feature_matrix_path` if obs_feature_matrix_path points to a subset of `X` of the full `var` list.
517517
:param str initial_feature_filter_path: A string like `var/highly_variable` used in conjunction with `obs_feature_matrix_path` if obs_feature_matrix_path points to a subset of `X` of the full `var` list.
518518
:param list[str] obs_set_paths: Column names like `['obs/louvain', 'obs/cellType']` for showing cell sets
519-
:param list[str] obs_set_names: Names to display in place of those in `obs_set_paths`, like `['Louvain', 'Cell Type']
519+
:param list[str] obs_set_names: Names to display in place of those in `obs_set_paths`, like `['Louvain', 'Cell Type']`
520520
:param str obs_locations_path: Column name in `obsm` that contains centroid coordinates for displaying centroids in the spatial viewer
521521
:param str obs_segmentations_path: Column name in `obsm` that contains polygonal coordinates for displaying outlines in the spatial viewer
522522
:param list[str] obs_embedding_paths: Column names like `['obsm/X_umap', 'obsm/X_pca']` for showing scatterplots
523-
:param list[str] obs_embedding_names: Overriding names like `['UMAP', 'PCA'] for displaying above scatterplots
524-
:param list[str] obs_embedding_dims: Dimensions along which to get data for the scatterplot, like [[0, 1], [4, 5]] where [0, 1] is just the normal x and y but [4, 5] could be comparing the third and fourth principal components, for example.
525-
:param dict request_init: options to be passed along with every fetch request from the browser, like { "header": { "Authorization": "Bearer dsfjalsdfa1431" } }
523+
:param list[str] obs_embedding_names: Overriding names like `['UMAP', 'PCA']` for displaying above scatterplots
524+
:param list[str] obs_embedding_dims: Dimensions along which to get data for the scatterplot, like `[[0, 1], [4, 5]]` where `[0, 1]` is just the normal x and y but `[4, 5]` could be comparing the third and fourth principal components, for example.
525+
:param dict request_init: options to be passed along with every fetch request from the browser, like `{ "header": { "Authorization": "Bearer dsfjalsdfa1431" } }`
526526
:param str feature_labels_path: The name of a column containing feature labels (e.g., alternate gene symbols), instead of the default index in `var` of the AnnData store.
527-
:param str obs_labels_path: The name of a column containing observation labels (e.g., alternate cell IDs), instead of the default index in `obs` of the AnnData store.
527+
:param str obs_labels_path: (DEPRECATED) The name of a column containing observation labels (e.g., alternate cell IDs), instead of the default index in `obs` of the AnnData store. Use `obs_labels_paths` and `obs_labels_names` instead. This arg will be removed in a future release.
528+
:param list[str] obs_labels_paths: The names of columns containing observation labels (e.g., alternate cell IDs), instead of the default index in `obs` of the AnnData store.
529+
:param list[str] obs_labels_names: The optional display names of columns containing observation labels (e.g., alternate cell IDs), instead of the default index in `obs` of the AnnData store.
528530
:param bool convert_to_dense: Whether or not to convert `X` to dense the zarr store (dense is faster but takes more disk space).
529531
:param coordination_values: Coordination values for the file definition.
530532
:type coordination_values: dict or None
@@ -559,7 +561,13 @@ def __init__(self, adata_path=None, adata_url=None, obs_feature_matrix_path=None
559561
self._mappings_obsm_dims = obs_embedding_dims
560562
self._request_init = request_init
561563
self._gene_alias = feature_labels_path
562-
self._obs_labels_path = obs_labels_path
564+
# Support legacy provision of single obs labels path
565+
if (obs_labels_path is not None):
566+
self._obs_labels_paths = [obs_labels_path]
567+
self._obs_labels_names = [obs_labels_path.split('/')[-1]]
568+
else:
569+
self._obs_labels_paths = obs_labels_paths
570+
self._obs_labels_names = obs_labels_names
563571
self._convert_to_dense = convert_to_dense
564572
self._coordination_values = coordination_values
565573

@@ -642,10 +650,18 @@ def get_anndata_zarr(base_url):
642650
options["featureLabels"] = {
643651
"path": self._gene_alias
644652
}
645-
if self._obs_labels_path is not None:
646-
options["obsLabels"] = {
647-
"path": self._obs_labels_path
648-
}
653+
if self._obs_labels_paths is not None:
654+
if self._obs_labels_names is not None and len(self._obs_labels_paths) == len(self._obs_labels_names):
655+
# A name was provided for each path element, so use those values.
656+
names = self._obs_labels_names
657+
else:
658+
# Names were not provided for each path element,
659+
# so fall back to using the final part of each path for the names.
660+
names = [labels_path.split('/')[-1] for labels_path in self._obs_labels_paths]
661+
obs_labels = []
662+
for path, name in zip(self._obs_labels_paths, names):
663+
obs_labels.append({"path": path, "obsLabelsType": name})
664+
options["obsLabels"] = obs_labels
649665
if len(options.keys()) > 0:
650666
obj_file_def = {
651667
"fileType": ft.ANNDATA_ZARR.value,

0 commit comments

Comments
 (0)