From 46876e2fb181dca3410f75edba7dd361bba1fe23 Mon Sep 17 00:00:00 2001 From: bmccandless Date: Mon, 24 Feb 2020 18:19:39 -0800 Subject: [PATCH] Fix various bugs with CXG format at annotations (#1173) - Enable testing for this path - Fixes #1166 - Fixes #1167 - Fixes #1168 --- server/data_common/data_adaptor.py | 2 ++ server/data_cxg/cxg_adaptor.py | 18 ++++++++---------- server/test/test_api.py | 9 +-------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/server/data_common/data_adaptor.py b/server/data_common/data_adaptor.py index 229e7601..1c4ffcf4 100644 --- a/server/data_common/data_adaptor.py +++ b/server/data_common/data_adaptor.py @@ -213,6 +213,8 @@ class DataAdaptor(metaclass=ABCMeta): return labels_df.index = self.get_obs_index() + if labels_df.index.name is None: + labels_df.index.name = "index" # all labels must have a name, which must be unique and not used in obs column names if not labels_df.columns.is_unique: diff --git a/server/data_cxg/cxg_adaptor.py b/server/data_cxg/cxg_adaptor.py index 12610254..a9fea0ff 100644 --- a/server/data_cxg/cxg_adaptor.py +++ b/server/data_cxg/cxg_adaptor.py @@ -292,19 +292,17 @@ class CxgAdaptor(DataAdaptor): def annotation_to_fbs_matrix(self, axis, fields=None, labels=None): with ServerTiming.time(f"annotations.{axis}.query"): A = self.open_array(str(axis)) - if fields is not None and len(fields) > 0: - try: - df = pd.DataFrame(A.query(attrs=fields)[:]) - except tiledb.libtiledb.TileDBError: - raise KeyError("bad field {fields}") - + if axis == Axis.OBS: + if labels is not None and not labels.empty: + df = pd.DataFrame.from_dict(A[:]) + df = df.join(labels, self.get_obs_names()) + else: + df = pd.DataFrame.from_dict(A[:]) else: df = pd.DataFrame.from_dict(A[:]) - if axis == Axis.OBS: - if labels is not None and not labels.empty: - obs_names = self.get_obs_names() - df = df.join(labels, obs_names) + if fields is not None and len(fields) > 0: + df = df[fields] with ServerTiming.time(f"annotations.{axis}.encode"): fbs = encode_matrix_fbs(df, col_idx=df.columns) diff --git a/server/test/test_api.py b/server/test/test_api.py index fd39bd55..4d42350f 100644 --- a/server/test/test_api.py +++ b/server/test/test_api.py @@ -8,13 +8,12 @@ import pandas as pd import requests import server.test.decode_fbs as decode_fbs -from server.test import skip_if, data_with_tmp_annotations, make_fbs +from server.test import data_with_tmp_annotations, make_fbs from server.data_common.matrix_loader import MatrixDataType BAD_FILTER = {"filter": {"obs": {"annotation_value": [{"name": "xyz"}]}}} # TODO (mweiden): remove ANNOTATIONS_ENABLED and Annotation subclasses when annotations are no longer experimental -# TODO (mweiden): remove MATRIX_DATA_TYPE and skip_if when user annotations for the CXG format is complete class EndPoints(object): @@ -91,10 +90,6 @@ class EndPoints(object): + (["cluster-test"] if self.ANNOTATIONS_ENABLED else []), ) - @skip_if( - lambda slf: hasattr(slf, "MATRIX_DATA_TYPE") and slf.MATRIX_DATA_TYPE == MatrixDataType.CXG, - "CXG file annotations are not feature-complete!", - ) def test_get_annotations_obs_keys_fbs(self): endpoint = "annotations/obs" query = "annotation-name=n_genes&annotation-name=percent_mito" @@ -275,13 +270,11 @@ class EndPointsAnnotations(EndPoints): def test_get_schema_existing_writable(self): self._test_get_schema_writable("cluster-test") - @skip_if(lambda slf: slf.MATRIX_DATA_TYPE == MatrixDataType.CXG, "CXG file annotations are not feature-complete!") def test_get_user_annotations_existing_obs_keys_fbs(self): self._test_get_user_annotations_obs_keys_fbs( "cluster-test", {"unassigned", "one", "two", "three", "four", "five"}, ) - @skip_if(lambda slf: slf.MATRIX_DATA_TYPE == MatrixDataType.CXG, "CXG file annotations are not feature-complete!") def test_put_user_annotations_obs_fbs(self): endpoint = "annotations/obs" query = "annotation-collection-name=test_annotations"