mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-27 06:48:12 +08:00
Apply yapf to python files
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
"""
|
||||
Code to decode, for testing purposes, the flatbuffer encoded blobs.
|
||||
This code will need to be updated if fbs/matrix.fbs changes.
|
||||
@@ -18,18 +17,23 @@ import server.app.util.fbs.NetEncoding.JSONEncodedArray as JSONEncodedArray
|
||||
|
||||
def decode_typed_array(tarr):
|
||||
type_map = {
|
||||
TypedArray.TypedArray.Uint32Array: Uint32Array.Uint32Array,
|
||||
TypedArray.TypedArray.Int32Array: Int32Array.Int32Array,
|
||||
TypedArray.TypedArray.Float32Array: Float32Array.Float32Array,
|
||||
TypedArray.TypedArray.Float64Array: Float64Array.Float64Array,
|
||||
TypedArray.TypedArray.JSONEncodedArray: JSONEncodedArray.JSONEncodedArray
|
||||
TypedArray.TypedArray.Uint32Array:
|
||||
Uint32Array.Uint32Array,
|
||||
TypedArray.TypedArray.Int32Array:
|
||||
Int32Array.Int32Array,
|
||||
TypedArray.TypedArray.Float32Array:
|
||||
Float32Array.Float32Array,
|
||||
TypedArray.TypedArray.Float64Array:
|
||||
Float64Array.Float64Array,
|
||||
TypedArray.TypedArray.JSONEncodedArray:
|
||||
JSONEncodedArray.JSONEncodedArray
|
||||
}
|
||||
(u_type, u) = tarr
|
||||
if u_type == TypedArray.TypedArray.NONE:
|
||||
return None
|
||||
|
||||
TarType = type_map.get(u_type, None)
|
||||
assert(TarType is not None)
|
||||
assert (TarType is not None)
|
||||
|
||||
arr = TarType()
|
||||
arr.Init(u.Bytes, u.Pos)
|
||||
|
||||
+80
-28
@@ -19,7 +19,10 @@ class EndPoints(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.ps = Popen(["cellxgene", "launch", "../example-dataset/pbmc3k.h5ad", "--verbose", "--port", "5005"])
|
||||
cls.ps = Popen([
|
||||
"cellxgene", "launch", "../example-dataset/pbmc3k.h5ad",
|
||||
"--verbose", "--port", "5005"
|
||||
])
|
||||
session = requests.Session()
|
||||
for i in range(90):
|
||||
try:
|
||||
@@ -47,7 +50,8 @@ class EndPoints(unittest.TestCase):
|
||||
result_data = result.json()
|
||||
self.assertEqual(result_data["schema"]["dataframe"]["nObs"], 2638)
|
||||
self.assertEqual(len(result_data["schema"]["annotations"]["obs"]), 2)
|
||||
self.assertEqual(len(result_data["schema"]["annotations"]["obs"]["columns"]), 5)
|
||||
self.assertEqual(
|
||||
len(result_data["schema"]["annotations"]["obs"]["columns"]), 5)
|
||||
|
||||
def test_config(self):
|
||||
endpoint = "config"
|
||||
@@ -57,7 +61,8 @@ class EndPoints(unittest.TestCase):
|
||||
self.assertEqual(result.headers["Content-Type"], "application/json")
|
||||
result_data = result.json()
|
||||
self.assertIn("library_versions", result_data["config"])
|
||||
self.assertEqual(result_data["config"]["displayNames"]["dataset"], "pbmc3k")
|
||||
self.assertEqual(result_data["config"]["displayNames"]["dataset"],
|
||||
"pbmc3k")
|
||||
self.assertEqual(len(result_data["config"]["features"]), 4)
|
||||
|
||||
def test_get_layout_fbs(self):
|
||||
@@ -66,13 +71,15 @@ class EndPoints(unittest.TestCase):
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
result = self.session.get(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df['n_rows'], 2638)
|
||||
self.assertEqual(df['n_cols'], 8)
|
||||
self.assertIsNotNone(df['columns'])
|
||||
self.assertListEqual(df['col_idx'], [
|
||||
'pca_0', 'pca_1', 'tsne_0', 'tsne_1', 'umap_0', 'umap_1', 'draw_graph_fr_0', 'draw_graph_fr_1'
|
||||
'pca_0', 'pca_1', 'tsne_0', 'tsne_1', 'umap_0', 'umap_1',
|
||||
'draw_graph_fr_0', 'draw_graph_fr_1'
|
||||
])
|
||||
self.assertIsNone(df['row_idx'])
|
||||
self.assertEqual(len(df['columns']), df['n_cols'])
|
||||
@@ -89,7 +96,8 @@ class EndPoints(unittest.TestCase):
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
result = self.session.get(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df['n_rows'], 2638)
|
||||
self.assertEqual(df['n_cols'], 5)
|
||||
@@ -97,8 +105,11 @@ class EndPoints(unittest.TestCase):
|
||||
self.assertIsNotNone(df['col_idx'])
|
||||
self.assertIsNone(df['row_idx'])
|
||||
self.assertEqual(len(df['columns']), df['n_cols'])
|
||||
obs_index_col_name = self.schema["schema"]["annotations"]["obs"]["index"]
|
||||
self.assertListEqual(df['col_idx'], [obs_index_col_name, 'n_genes', 'percent_mito', 'n_counts', 'louvain'])
|
||||
obs_index_col_name = self.schema["schema"]["annotations"]["obs"][
|
||||
"index"]
|
||||
self.assertListEqual(df['col_idx'], [
|
||||
obs_index_col_name, 'n_genes', 'percent_mito', 'n_counts', 'louvain'
|
||||
])
|
||||
|
||||
def test_get_annotations_obs_keys_fbs(self):
|
||||
endpoint = "annotations/obs"
|
||||
@@ -107,7 +118,8 @@ class EndPoints(unittest.TestCase):
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
result = self.session.get(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df['n_rows'], 2638)
|
||||
self.assertEqual(df['n_cols'], 2)
|
||||
@@ -129,8 +141,26 @@ class EndPoints(unittest.TestCase):
|
||||
url = f"{URL_BASE}{endpoint}"
|
||||
params = {
|
||||
"mode": "topN",
|
||||
"set1": {"filter": {"obs": {"annotation_value": [{"name": "louvain", "values": ["NK cells"]}]}}},
|
||||
"set2": {"filter": {"obs": {"annotation_value": [{"name": "louvain", "values": ["CD8 T cells"]}]}}},
|
||||
"set1": {
|
||||
"filter": {
|
||||
"obs": {
|
||||
"annotation_value": [{
|
||||
"name": "louvain",
|
||||
"values": ["NK cells"]
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
"set2": {
|
||||
"filter": {
|
||||
"obs": {
|
||||
"annotation_value": [{
|
||||
"name": "louvain",
|
||||
"values": ["CD8 T cells"]
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
"count": 7,
|
||||
}
|
||||
result = self.session.post(url, json=params)
|
||||
@@ -145,8 +175,20 @@ class EndPoints(unittest.TestCase):
|
||||
params = {
|
||||
"mode": "topN",
|
||||
"count": 10,
|
||||
"set1": {"filter": {"obs": {"index": [[0, 500]]}}},
|
||||
"set2": {"filter": {"obs": {"index": [[500, 1000]]}}},
|
||||
"set1": {
|
||||
"filter": {
|
||||
"obs": {
|
||||
"index": [[0, 500]]
|
||||
}
|
||||
}
|
||||
},
|
||||
"set2": {
|
||||
"filter": {
|
||||
"obs": {
|
||||
"index": [[500, 1000]]
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
result = self.session.post(url, json=params)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
@@ -160,7 +202,8 @@ class EndPoints(unittest.TestCase):
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
result = self.session.get(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df['n_rows'], 1838)
|
||||
self.assertEqual(df['n_cols'], 2)
|
||||
@@ -168,7 +211,8 @@ class EndPoints(unittest.TestCase):
|
||||
self.assertIsNotNone(df['col_idx'])
|
||||
self.assertIsNone(df['row_idx'])
|
||||
self.assertEqual(len(df['columns']), df['n_cols'])
|
||||
var_index_col_name = self.schema["schema"]["annotations"]["var"]["index"]
|
||||
var_index_col_name = self.schema["schema"]["annotations"]["var"][
|
||||
"index"]
|
||||
self.assertListEqual(df['col_idx'], [var_index_col_name, 'n_cells'])
|
||||
|
||||
def test_get_annotations_var_keys_fbs(self):
|
||||
@@ -178,7 +222,8 @@ class EndPoints(unittest.TestCase):
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
result = self.session.get(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df['n_rows'], 1838)
|
||||
self.assertEqual(df['n_cols'], 1)
|
||||
@@ -207,7 +252,8 @@ class EndPoints(unittest.TestCase):
|
||||
url = f"{URL_BASE}{endpoint}"
|
||||
result = self.session.put(url)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
|
||||
def test_data_put_fbs(self):
|
||||
endpoint = f"data/var"
|
||||
@@ -215,7 +261,8 @@ class EndPoints(unittest.TestCase):
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
result = self.session.put(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df['n_rows'], 2638)
|
||||
self.assertEqual(df['n_cols'], 1838)
|
||||
@@ -228,16 +275,11 @@ class EndPoints(unittest.TestCase):
|
||||
endpoint = f"data/var"
|
||||
url = f"{URL_BASE}{endpoint}"
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
filter = {
|
||||
"filter": {
|
||||
"var": {
|
||||
"index": [0, 1, 4]
|
||||
}
|
||||
}
|
||||
}
|
||||
filter = {"filter": {"var": {"index": [0, 1, 4]}}}
|
||||
result = self.session.put(url, headers=header, json=filter)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df['n_rows'], 2638)
|
||||
self.assertEqual(df['n_cols'], 3)
|
||||
@@ -252,10 +294,20 @@ class EndPoints(unittest.TestCase):
|
||||
url = f"{URL_BASE}{endpoint}"
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
index_col_name = self.schema["schema"]["annotations"]["var"]["index"]
|
||||
var_filter = {"filter": {"var": {"annotation_value": [{"name": index_col_name, "values": ["RER1"]}]}}}
|
||||
var_filter = {
|
||||
"filter": {
|
||||
"var": {
|
||||
"annotation_value": [{
|
||||
"name": index_col_name,
|
||||
"values": ["RER1"]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
result = self.session.put(url, headers=header, json=var_filter)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df["n_rows"], 2638)
|
||||
self.assertEqual(df["n_cols"], 1)
|
||||
|
||||
+28
-25
@@ -40,49 +40,52 @@ class FbsTests(unittest.TestCase):
|
||||
def test_encode_DataFrame(self):
|
||||
df = pd.DataFrame(
|
||||
data={
|
||||
'a': np.zeros((10,), dtype=np.float32),
|
||||
'b': np.ones((10,), dtype=np.int64),
|
||||
'c': np.array([i for i in range(0, 10)], dtype=np.uint16),
|
||||
'd': pd.Series(['x', 'y', 'z', 'x', 'y', 'z', 'a', 'x', 'y', 'z'], dtype='category')
|
||||
'a':
|
||||
np.zeros((10,), dtype=np.float32),
|
||||
'b':
|
||||
np.ones((10,), dtype=np.int64),
|
||||
'c':
|
||||
np.array([i for i in range(0, 10)], dtype=np.uint16),
|
||||
'd':
|
||||
pd.Series(
|
||||
['x', 'y', 'z', 'x', 'y', 'z', 'a', 'x', 'y', 'z'],
|
||||
dtype='category')
|
||||
})
|
||||
expected_types = (
|
||||
(np.ndarray, np.float32),
|
||||
(np.ndarray, np.int32),
|
||||
(np.ndarray, np.uint32),
|
||||
(list, None)
|
||||
)
|
||||
expected_types = ((np.ndarray, np.float32), (np.ndarray, np.int32),
|
||||
(np.ndarray, np.uint32), (list, None))
|
||||
fbs = encode_matrix_fbs(matrix=df, row_idx=None, col_idx=df.columns)
|
||||
self.fbs_checks(fbs, (10, 4), expected_types, ['a', 'b', 'c', 'd'])
|
||||
|
||||
def test_encode_ndarray(self):
|
||||
arr = np.zeros((3, 2), dtype=np.float32)
|
||||
expected_types = (
|
||||
(np.ndarray, np.float32),
|
||||
(np.ndarray, np.float32),
|
||||
(np.ndarray, np.float32)
|
||||
)
|
||||
expected_types = ((np.ndarray, np.float32), (np.ndarray, np.float32),
|
||||
(np.ndarray, np.float32))
|
||||
fbs = encode_matrix_fbs(matrix=arr, row_idx=None, col_idx=None)
|
||||
self.fbs_checks(fbs, (3, 2), expected_types, None)
|
||||
|
||||
def test_encode_sparse(self):
|
||||
csc = sparse.csc_matrix(np.array([[0, 1, 2], [3, 0, 4]]))
|
||||
expected_types = (
|
||||
(np.ndarray, np.int32),
|
||||
(np.ndarray, np.int32),
|
||||
(np.ndarray, np.int32)
|
||||
)
|
||||
expected_types = ((np.ndarray, np.int32), (np.ndarray, np.int32),
|
||||
(np.ndarray, np.int32))
|
||||
fbs = encode_matrix_fbs(matrix=csc, row_idx=None, col_idx=None)
|
||||
self.fbs_checks(fbs, (2, 3), expected_types, None)
|
||||
|
||||
def test_roundtrip(self):
|
||||
dfSrc = pd.DataFrame(
|
||||
data={
|
||||
'a': np.zeros((10,), dtype=np.float32),
|
||||
'b': np.ones((10,), dtype=np.int64),
|
||||
'c': np.array([i for i in range(0, 10)], dtype=np.uint16),
|
||||
'd': pd.Series(['x', 'y', 'z', 'x', 'y', 'z', 'a', 'x', 'y', 'z'], dtype='category')
|
||||
'a':
|
||||
np.zeros((10,), dtype=np.float32),
|
||||
'b':
|
||||
np.ones((10,), dtype=np.int64),
|
||||
'c':
|
||||
np.array([i for i in range(0, 10)], dtype=np.uint16),
|
||||
'd':
|
||||
pd.Series(
|
||||
['x', 'y', 'z', 'x', 'y', 'z', 'a', 'x', 'y', 'z'],
|
||||
dtype='category')
|
||||
})
|
||||
dfDst = decode_matrix_fbs(encode_matrix_fbs(matrix=dfSrc, col_idx=dfSrc.columns))
|
||||
dfDst = decode_matrix_fbs(
|
||||
encode_matrix_fbs(matrix=dfSrc, col_idx=dfSrc.columns))
|
||||
self.assertEqual(dfSrc.shape, dfDst.shape)
|
||||
self.assertEqual(set(dfSrc.columns), set(dfDst.columns))
|
||||
for c in dfSrc.columns:
|
||||
|
||||
@@ -7,12 +7,14 @@ class NdArrayProxyView(MatrixProxyView):
|
||||
"""
|
||||
Fake test class for matrix proxy - wraps ndarray
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def __supports__(cls):
|
||||
return ('numpy.ndarray', )
|
||||
return ('numpy.ndarray',)
|
||||
|
||||
|
||||
class MatrixProxyViewTest(unittest.TestCase):
|
||||
|
||||
def test_ismatrixproxy(self):
|
||||
n = np.zeros((2, 4))
|
||||
mp = MatrixProxy.create(n)
|
||||
@@ -41,18 +43,13 @@ class MatrixProxyViewTest(unittest.TestCase):
|
||||
def test_toarray(self):
|
||||
n = np.arange(15, dtype=np.float32).reshape((3, 5))
|
||||
mp = MatrixProxy.create(n)
|
||||
self.assertTrue(np.all(mp.toarray() == [
|
||||
[0., 1., 2., 3., 4.],
|
||||
[5., 6., 7., 8., 9.],
|
||||
[10., 11., 12., 13., 14.]
|
||||
]))
|
||||
self.assertTrue(np.all(mp.T.toarray() == [
|
||||
[0., 5., 10.],
|
||||
[1., 6., 11.],
|
||||
[2., 7., 12.],
|
||||
[3., 8., 13.],
|
||||
[4., 9., 14.]
|
||||
]))
|
||||
self.assertTrue(
|
||||
np.all(mp.toarray() == [[0., 1., 2., 3., 4.], [5., 6., 7., 8., 9.],
|
||||
[10., 11., 12., 13., 14.]]))
|
||||
self.assertTrue(
|
||||
np.all(
|
||||
mp.T.toarray() == [[0., 5., 10.], [1., 6., 11.], [2., 7., 12.],
|
||||
[3., 8., 13.], [4., 9., 14.]]))
|
||||
|
||||
def test_indexing(self):
|
||||
"""
|
||||
@@ -95,47 +92,25 @@ class MatrixProxyViewTest(unittest.TestCase):
|
||||
|
||||
# slice, slice
|
||||
|
||||
self.assertTrue(np.all(mp[1:3, 2:4].toarray() == [
|
||||
[7, 8],
|
||||
[12, 13]
|
||||
]))
|
||||
self.assertTrue(np.all(mp[:3, :4].toarray() == [
|
||||
[0., 1., 2., 3.],
|
||||
[5., 6., 7., 8.],
|
||||
[10., 11., 12., 13.]
|
||||
]))
|
||||
self.assertTrue(np.all(mp[::-1, ::-1].toarray() == [
|
||||
[14, 13, 12, 11, 10],
|
||||
[9, 8, 7, 6, 5],
|
||||
[4, 3, 2, 1, 0]
|
||||
]))
|
||||
self.assertTrue(np.all(mp[::-2, ::-2].toarray() == [
|
||||
[14, 12, 10],
|
||||
[4, 2, 0]
|
||||
]))
|
||||
self.assertTrue(np.all(mp[1:3, 2:4].toarray() == [[7, 8], [12, 13]]))
|
||||
self.assertTrue(
|
||||
np.all(mp[:3, :4].toarray() == [[0., 1., 2., 3.], [5., 6., 7., 8.],
|
||||
[10., 11., 12., 13.]]))
|
||||
self.assertTrue(
|
||||
np.all(mp[::-1, ::-1].toarray() ==
|
||||
[[14, 13, 12, 11, 10], [9, 8, 7, 6, 5], [4, 3, 2, 1, 0]]))
|
||||
self.assertTrue(
|
||||
np.all(mp[::-2, ::-2].toarray() == [[14, 12, 10], [4, 2, 0]]))
|
||||
|
||||
self.assertTrue(np.all(mp.T[2:4, 1:3].toarray() == [
|
||||
[7, 12],
|
||||
[8, 13]
|
||||
]))
|
||||
self.assertTrue(np.all(mp.T[:4, :3].toarray() == [
|
||||
[0, 5, 10],
|
||||
[1, 6, 11],
|
||||
[2, 7, 12],
|
||||
[3, 8, 13]
|
||||
]))
|
||||
self.assertTrue(np.all(mp.T[::-1, ::-1].toarray() == [
|
||||
[14, 9, 4],
|
||||
[13, 8, 3],
|
||||
[12, 7, 2],
|
||||
[11, 6, 1],
|
||||
[10, 5, 0]
|
||||
]))
|
||||
self.assertTrue(np.all(mp.T[::-2, ::-2].toarray() == [
|
||||
[14, 4],
|
||||
[12, 2],
|
||||
[10, 0]
|
||||
]))
|
||||
self.assertTrue(np.all(mp.T[2:4, 1:3].toarray() == [[7, 12], [8, 13]]))
|
||||
self.assertTrue(
|
||||
np.all(mp.T[:4, :3].toarray() == [[0, 5, 10], [1, 6, 11],
|
||||
[2, 7, 12], [3, 8, 13]]))
|
||||
self.assertTrue(
|
||||
np.all(mp.T[::-1, ::-1].toarray(
|
||||
) == [[14, 9, 4], [13, 8, 3], [12, 7, 2], [11, 6, 1], [10, 5, 0]]))
|
||||
self.assertTrue(
|
||||
np.all(mp.T[::-2, ::-2].toarray() == [[14, 4], [12, 2], [10, 0]]))
|
||||
|
||||
def test_repeated_indexing(self):
|
||||
"""
|
||||
@@ -149,31 +124,16 @@ class MatrixProxyViewTest(unittest.TestCase):
|
||||
self.assertEqual(mp[0][1], 1)
|
||||
self.assertEqual(mp.T[0][1], 5)
|
||||
|
||||
self.assertTrue(np.all(mp[0::-1, ::-1][0, 2:4].toarray() == [
|
||||
2, 1
|
||||
]))
|
||||
self.assertTrue(np.all(mp[0::-1, 1:5:1][0, 1:3:1].toarray() == [
|
||||
2, 3
|
||||
]))
|
||||
self.assertTrue(np.all(mp[0::-1, 1:5:1][0, 2:0:-1].toarray() == [
|
||||
3, 2
|
||||
]))
|
||||
self.assertTrue(np.all(mp[0::-1, 5:1:-1][0, 1:3:1].toarray() == [
|
||||
3, 2
|
||||
]))
|
||||
self.assertTrue(np.all(mp[0::-1, 5:1:-1][0, 2:0:-1].toarray() == [
|
||||
2, 3
|
||||
]))
|
||||
self.assertTrue(np.all(mp[0::-1, ::-1][0, 2:4].toarray() == [2, 1]))
|
||||
self.assertTrue(np.all(mp[0::-1, 1:5:1][0, 1:3:1].toarray() == [2, 3]))
|
||||
self.assertTrue(np.all(mp[0::-1, 1:5:1][0, 2:0:-1].toarray() == [3, 2]))
|
||||
self.assertTrue(np.all(mp[0::-1, 5:1:-1][0, 1:3:1].toarray() == [3, 2]))
|
||||
self.assertTrue(np.all(mp[0::-1, 5:1:-1][0,
|
||||
2:0:-1].toarray() == [2, 3]))
|
||||
|
||||
self.assertTrue(np.all(mp.T[::-1, 0::-1][2:4, 0].toarray() == [
|
||||
2, 1
|
||||
]))
|
||||
self.assertTrue(np.all(mp.T[0::-1, 1:5:1][0, 1:3:1].toarray() == [
|
||||
10
|
||||
]))
|
||||
self.assertTrue(np.all(mp.T[0::-1, 1:5:1][0, 2:0:-1].toarray() == [
|
||||
10
|
||||
]))
|
||||
self.assertTrue(np.all(mp.T[::-1, 0::-1][2:4, 0].toarray() == [2, 1]))
|
||||
self.assertTrue(np.all(mp.T[0::-1, 1:5:1][0, 1:3:1].toarray() == [10]))
|
||||
self.assertTrue(np.all(mp.T[0::-1, 1:5:1][0, 2:0:-1].toarray() == [10]))
|
||||
self.assertTrue(np.all(mp.T[0::-1, 5:1:-1][0, 1:3:1].toarray() == []))
|
||||
self.assertTrue(np.all(mp.T[0::-1, 5:1:-1][0, 2:0:-1].toarray() == []))
|
||||
|
||||
@@ -190,20 +150,12 @@ class MatrixProxyViewTest(unittest.TestCase):
|
||||
self.assertEqual(mp[0, 0], 0)
|
||||
|
||||
# drop 1 dimension, to an array
|
||||
self.assertTrue(np.all(mp[0, :].toarray() == [
|
||||
0, 1, 2, 3, 4
|
||||
]))
|
||||
self.assertTrue(np.all(mp[:, 0].toarray() == [
|
||||
0, 5, 10
|
||||
]))
|
||||
self.assertTrue(np.all(mp[0, :].toarray() == [0, 1, 2, 3, 4]))
|
||||
self.assertTrue(np.all(mp[:, 0].toarray() == [0, 5, 10]))
|
||||
|
||||
# with .T
|
||||
self.assertTrue(np.all(mp[0:2].T[-1:].toarray() == [
|
||||
[4, 9]
|
||||
]))
|
||||
self.assertTrue(np.all(mp[0:2].T[-1].toarray() == [
|
||||
4, 9
|
||||
]))
|
||||
self.assertTrue(np.all(mp[0:2].T[-1:].toarray() == [[4, 9]]))
|
||||
self.assertTrue(np.all(mp[0:2].T[-1].toarray() == [4, 9]))
|
||||
|
||||
def test_iter(self):
|
||||
"""
|
||||
@@ -214,17 +166,13 @@ class MatrixProxyViewTest(unittest.TestCase):
|
||||
|
||||
rows = [r for r in mp]
|
||||
self.assertEqual(len(rows), 3)
|
||||
self.assertTrue(np.all(rows[0].toarray() == [
|
||||
0, 1, 2, 3, 4
|
||||
]))
|
||||
self.assertTrue(np.all(rows[0].toarray() == [0, 1, 2, 3, 4]))
|
||||
for i, r in enumerate(rows):
|
||||
self.assertTrue(np.all(mp[i].toarray() == r.toarray()))
|
||||
|
||||
cols = [c for c in mp.T]
|
||||
self.assertEqual(len(cols), 5)
|
||||
self.assertTrue(np.all(cols[0].toarray() == [
|
||||
0, 5, 10
|
||||
]))
|
||||
self.assertTrue(np.all(cols[0].toarray() == [0, 5, 10]))
|
||||
for i, c in enumerate(cols):
|
||||
self.assertTrue(np.all(mp.T[i].toarray() == c.toarray()))
|
||||
|
||||
|
||||
@@ -20,9 +20,10 @@ class WithNaNs(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.ps = Popen(
|
||||
["cellxgene", "launch", "test/test_datasets/nan.h5ad", "--verbose", "--port", "5006"]
|
||||
)
|
||||
cls.ps = Popen([
|
||||
"cellxgene", "launch", "test/test_datasets/nan.h5ad", "--verbose",
|
||||
"--port", "5006"
|
||||
])
|
||||
session = requests.Session()
|
||||
for i in range(90):
|
||||
try:
|
||||
@@ -51,7 +52,8 @@ class WithNaNs(unittest.TestCase):
|
||||
url = f"{URL_BASE}{endpoint}"
|
||||
result = self.session.put(url)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertTrue(math.isnan(df["columns"][3][3]))
|
||||
|
||||
@@ -60,7 +62,8 @@ class WithNaNs(unittest.TestCase):
|
||||
url = f"{URL_BASE}{endpoint}"
|
||||
result = self.session.get(url)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertTrue(math.isnan(df["columns"][2][0]))
|
||||
|
||||
@@ -69,6 +72,7 @@ class WithNaNs(unittest.TestCase):
|
||||
url = f"{URL_BASE}{endpoint}"
|
||||
result = self.session.get(url)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
self.assertEqual(result.headers["Content-Type"],
|
||||
"application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertTrue(math.isnan(df["columns"][2][0]))
|
||||
|
||||
@@ -11,6 +11,7 @@ from server.app.util.data_locator import DataLocator
|
||||
|
||||
|
||||
class NaNTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.args = {
|
||||
"layout": ["umap"],
|
||||
@@ -21,7 +22,8 @@ class NaNTest(unittest.TestCase):
|
||||
}
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", category=UserWarning)
|
||||
self.data = ScanpyEngine(DataLocator("test/test_datasets/nan.h5ad"), self.args)
|
||||
self.data = ScanpyEngine(DataLocator("test/test_datasets/nan.h5ad"),
|
||||
self.args)
|
||||
self.data._create_schema()
|
||||
|
||||
def test_load(self):
|
||||
@@ -35,7 +37,8 @@ class NaNTest(unittest.TestCase):
|
||||
self.assertTrue(self.data.data.X[0, 0] - -0.171_469_51 < epsilon)
|
||||
|
||||
def test_dataframe(self):
|
||||
data_frame_var = decode_fbs.decode_matrix_FBS(self.data.data_frame_to_fbs_matrix(None, "var"))
|
||||
data_frame_var = decode_fbs.decode_matrix_FBS(
|
||||
self.data.data_frame_to_fbs_matrix(None, "var"))
|
||||
self.assertIsNotNone(data_frame_var)
|
||||
self.assertEqual(data_frame_var["n_rows"], 100)
|
||||
self.assertEqual(data_frame_var["n_cols"], 100)
|
||||
@@ -44,30 +47,29 @@ class NaNTest(unittest.TestCase):
|
||||
with pytest.raises(FilterError):
|
||||
self.data.data_frame_to_fbs_matrix("an erroneous filter", "var")
|
||||
with pytest.raises(FilterError):
|
||||
filter_ = {
|
||||
"filter": {
|
||||
"obs": {"index": [1, 99, [200, 300]]}
|
||||
}
|
||||
}
|
||||
filter_ = {"filter": {"obs": {"index": [1, 99, [200, 300]]}}}
|
||||
self.data.data_frame_to_fbs_matrix(filter_["filter"], "var")
|
||||
|
||||
def test_dataframe_obs_not_implemented(self):
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
decode_fbs.decode_matrix_FBS(self.data.data_frame_to_fbs_matrix(None, "obs"))
|
||||
decode_fbs.decode_matrix_FBS(
|
||||
self.data.data_frame_to_fbs_matrix(None, "obs"))
|
||||
self.assertIsNotNone(cm.exception)
|
||||
|
||||
def test_annotation(self):
|
||||
annotations = decode_fbs.decode_matrix_FBS(self.data.annotation_to_fbs_matrix("obs"))
|
||||
annotations = decode_fbs.decode_matrix_FBS(
|
||||
self.data.annotation_to_fbs_matrix("obs"))
|
||||
obs_index_col_name = self.data.schema["annotations"]["obs"]["index"]
|
||||
self.assertEqual(
|
||||
annotations["col_idx"],
|
||||
[obs_index_col_name, "n_genes", "percent_mito", "n_counts", "louvain"]
|
||||
)
|
||||
self.assertEqual(annotations["col_idx"], [
|
||||
obs_index_col_name, "n_genes", "percent_mito", "n_counts", "louvain"
|
||||
])
|
||||
self.assertEqual(annotations["n_rows"], 100)
|
||||
self.assertTrue(math.isnan(annotations["columns"][2][0]))
|
||||
|
||||
annotations = decode_fbs.decode_matrix_FBS(self.data.annotation_to_fbs_matrix("var"))
|
||||
annotations = decode_fbs.decode_matrix_FBS(
|
||||
self.data.annotation_to_fbs_matrix("var"))
|
||||
var_index_col_name = self.data.schema["annotations"]["var"]["index"]
|
||||
self.assertEqual(annotations["col_idx"], [var_index_col_name, "n_cells", "var_with_nans"])
|
||||
self.assertEqual(annotations["col_idx"],
|
||||
[var_index_col_name, "n_cells", "var_with_nans"])
|
||||
self.assertEqual(annotations["n_rows"], 100)
|
||||
self.assertTrue(math.isnan(annotations["columns"][2][0]))
|
||||
|
||||
@@ -12,7 +12,6 @@ import pandas as pd
|
||||
from server.app.scanpy_engine.scanpy_engine import ScanpyEngine
|
||||
from server.app.util.errors import FilterError, DisabledFeatureError
|
||||
from server.app.util.data_locator import DataLocator
|
||||
|
||||
"""
|
||||
Test the scanpy engine using the pbmc3k data set.
|
||||
"""
|
||||
@@ -22,12 +21,12 @@ Test the scanpy engine using the pbmc3k data set.
|
||||
("../example-dataset/pbmc3k.h5ad", False),
|
||||
("test/test_datasets/pbmc3k-CSC-gz.h5ad", False),
|
||||
("test/test_datasets/pbmc3k-CSR-gz.h5ad", False),
|
||||
|
||||
("../example-dataset/pbmc3k.h5ad", True),
|
||||
("test/test_datasets/pbmc3k-CSC-gz.h5ad", True),
|
||||
("test/test_datasets/pbmc3k-CSR-gz.h5ad", True),
|
||||
])
|
||||
class EngineTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
args = {
|
||||
"layout": ["umap"],
|
||||
@@ -47,10 +46,12 @@ class EngineTest(unittest.TestCase):
|
||||
self.assertTrue(self.data.data.X[0, 0] - -0.171_469_51 < epsilon)
|
||||
|
||||
def test_mandatory_annotations(self):
|
||||
obs_index_col_name = self.data.get_schema()["annotations"]["obs"]["index"]
|
||||
obs_index_col_name = self.data.get_schema(
|
||||
)["annotations"]["obs"]["index"]
|
||||
self.assertIn(obs_index_col_name, self.data.data.obs)
|
||||
self.assertEqual(list(self.data.data.obs.index), list(range(2638)))
|
||||
var_index_col_name = self.data.get_schema()["annotations"]["var"]["index"]
|
||||
var_index_col_name = self.data.get_schema(
|
||||
)["annotations"]["var"]["index"]
|
||||
self.assertIn(var_index_col_name, self.data.data.var)
|
||||
self.assertEqual(list(self.data.data.var.index), list(range(1838)))
|
||||
|
||||
@@ -64,11 +65,7 @@ class EngineTest(unittest.TestCase):
|
||||
self.data._validate_data_types()
|
||||
|
||||
def test_filter_idx(self):
|
||||
filter_ = {
|
||||
"filter": {
|
||||
"var": {"index": [1, 99, [200, 300]]}
|
||||
}
|
||||
}
|
||||
filter_ = {"filter": {"var": {"index": [1, 99, [200, 300]]}}}
|
||||
fbs = self.data.data_frame_to_fbs_matrix(filter_["filter"], "var")
|
||||
data = decode_fbs.decode_matrix_FBS(fbs)
|
||||
self.assertEqual(data["n_rows"], 2638)
|
||||
@@ -78,9 +75,10 @@ class EngineTest(unittest.TestCase):
|
||||
filter_ = {
|
||||
"filter": {
|
||||
"var": {
|
||||
"annotation_value": [
|
||||
{"name": "n_cells", "min": 10}
|
||||
],
|
||||
"annotation_value": [{
|
||||
"name": "n_cells",
|
||||
"min": 10
|
||||
}],
|
||||
"index": [1, 99, [200, 300]]
|
||||
}
|
||||
}
|
||||
@@ -91,8 +89,12 @@ class EngineTest(unittest.TestCase):
|
||||
self.assertEqual(data["n_cols"], 91)
|
||||
|
||||
def test_obs_and_var_names(self):
|
||||
self.assertEqual(np.sum(self.data.data.var[self.data.get_schema()["annotations"]["var"]["index"]].isna()), 0)
|
||||
self.assertEqual(np.sum(self.data.data.obs[self.data.get_schema()["annotations"]["obs"]["index"]].isna()), 0)
|
||||
self.assertEqual(
|
||||
np.sum(self.data.data.var[self.data.get_schema()["annotations"]
|
||||
["var"]["index"]].isna()), 0)
|
||||
self.assertEqual(
|
||||
np.sum(self.data.data.obs[self.data.get_schema()["annotations"]
|
||||
["obs"]["index"]].isna()), 0)
|
||||
|
||||
def test_get_schema(self):
|
||||
with open(path.join(path.dirname(__file__), "schema.json")) as fh:
|
||||
@@ -110,7 +112,10 @@ class EngineTest(unittest.TestCase):
|
||||
def test_config(self):
|
||||
self.assertEqual(
|
||||
self.data.features["layout"]["obs"],
|
||||
{"available": True, "interactiveLimit": 50000},
|
||||
{
|
||||
"available": True,
|
||||
"interactiveLimit": 50000
|
||||
},
|
||||
)
|
||||
|
||||
def test_layout(self):
|
||||
@@ -129,18 +134,24 @@ class EngineTest(unittest.TestCase):
|
||||
annotations = decode_fbs.decode_matrix_FBS(fbs)
|
||||
self.assertEqual(annotations["n_rows"], 2638)
|
||||
self.assertEqual(annotations["n_cols"], 5)
|
||||
obs_index_col_name = self.data.get_schema()["annotations"]["obs"]["index"]
|
||||
obs_index_col_name = self.data.get_schema(
|
||||
)["annotations"]["obs"]["index"]
|
||||
self.assertEqual(
|
||||
annotations["col_idx"],
|
||||
[obs_index_col_name, "n_genes", "percent_mito", "n_counts", "louvain"],
|
||||
[
|
||||
obs_index_col_name, "n_genes", "percent_mito", "n_counts",
|
||||
"louvain"
|
||||
],
|
||||
)
|
||||
|
||||
fbs = self.data.annotation_to_fbs_matrix("var")
|
||||
annotations = decode_fbs.decode_matrix_FBS(fbs)
|
||||
self.assertEqual(annotations['n_rows'], 1838)
|
||||
self.assertEqual(annotations['n_cols'], 2)
|
||||
var_index_col_name = self.data.get_schema()["annotations"]["var"]["index"]
|
||||
self.assertEqual(annotations["col_idx"], [var_index_col_name, "n_cells"])
|
||||
var_index_col_name = self.data.get_schema(
|
||||
)["annotations"]["var"]["index"]
|
||||
self.assertEqual(annotations["col_idx"],
|
||||
[var_index_col_name, "n_cells"])
|
||||
|
||||
def test_annotation_fields(self):
|
||||
fbs = self.data.annotation_to_fbs_matrix("obs", ["n_genes", "n_counts"])
|
||||
@@ -148,7 +159,8 @@ class EngineTest(unittest.TestCase):
|
||||
self.assertEqual(annotations["n_rows"], 2638)
|
||||
self.assertEqual(annotations['n_cols'], 2)
|
||||
|
||||
var_index_col_name = self.data.get_schema()["annotations"]["var"]["index"]
|
||||
var_index_col_name = self.data.get_schema(
|
||||
)["annotations"]["var"]["index"]
|
||||
fbs = self.data.annotation_to_fbs_matrix("var", [var_index_col_name])
|
||||
annotations = decode_fbs.decode_matrix_FBS(fbs)
|
||||
self.assertEqual(annotations['n_rows'], 1838)
|
||||
@@ -163,7 +175,8 @@ class EngineTest(unittest.TestCase):
|
||||
f2 = {"filter": {"obs": {"index": [[500, 1000]]}}}
|
||||
result = json.loads(self.data.diffexp_topN(f1["filter"], f2["filter"]))
|
||||
self.assertEqual(len(result), 10)
|
||||
result = json.loads(self.data.diffexp_topN(f1["filter"], f2["filter"], 20))
|
||||
result = json.loads(
|
||||
self.data.diffexp_topN(f1["filter"], f2["filter"], 20))
|
||||
self.assertEqual(len(result), 20)
|
||||
|
||||
def test_data_frame(self):
|
||||
@@ -178,7 +191,14 @@ class EngineTest(unittest.TestCase):
|
||||
|
||||
def test_filtered_data_frame(self):
|
||||
filter_ = {
|
||||
"filter": {"var": {"annotation_value": [{"name": "n_cells", "min": 100}]}}
|
||||
"filter": {
|
||||
"var": {
|
||||
"annotation_value": [{
|
||||
"name": "n_cells",
|
||||
"min": 100
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
fbs = self.data.data_frame_to_fbs_matrix(filter_["filter"], "var")
|
||||
data = decode_fbs.decode_matrix_FBS(fbs)
|
||||
@@ -186,16 +206,29 @@ class EngineTest(unittest.TestCase):
|
||||
self.assertEqual(data["n_cols"], 1040)
|
||||
|
||||
filter_ = {
|
||||
"filter": {"obs": {"annotation_value": [{"name": "n_counts", "min": 3000}]}}
|
||||
"filter": {
|
||||
"obs": {
|
||||
"annotation_value": [{
|
||||
"name": "n_counts",
|
||||
"min": 3000
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
with self.assertRaises(FilterError):
|
||||
self.data.data_frame_to_fbs_matrix(filter_["filter"], "var")
|
||||
|
||||
def test_data_named_gene(self):
|
||||
var_index_col_name = self.data.get_schema()["annotations"]["var"]["index"]
|
||||
var_index_col_name = self.data.get_schema(
|
||||
)["annotations"]["var"]["index"]
|
||||
filter_ = {
|
||||
"filter": {
|
||||
"var": {"annotation_value": [{"name": var_index_col_name, "values": ["RER1"]}]}
|
||||
"var": {
|
||||
"annotation_value": [{
|
||||
"name": var_index_col_name,
|
||||
"values": ["RER1"]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
fbs = self.data.data_frame_to_fbs_matrix(filter_["filter"], "var")
|
||||
@@ -206,7 +239,12 @@ class EngineTest(unittest.TestCase):
|
||||
|
||||
filter_ = {
|
||||
"filter": {
|
||||
"var": {"annotation_value": [{"name": var_index_col_name, "values": ["SPEN", "TYMP", "PRMT2"]}]}
|
||||
"var": {
|
||||
"annotation_value": [{
|
||||
"name": var_index_col_name,
|
||||
"values": ["SPEN", "TYMP", "PRMT2"]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
fbs = self.data.data_frame_to_fbs_matrix(filter_["filter"], "var")
|
||||
|
||||
@@ -10,6 +10,7 @@ class DataLoadEngineTest(unittest.TestCase):
|
||||
"""
|
||||
Test file loading, including deferred loading/update.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.data_file = DataLocator("../example-dataset/pbmc3k.h5ad")
|
||||
self.data = ScanpyEngine()
|
||||
@@ -52,7 +53,8 @@ class DataLoadEngineTest(unittest.TestCase):
|
||||
f2 = {"filter": {"obs": {"index": [[500, 1000]]}}}
|
||||
result = json.loads(self.data.diffexp_topN(f1["filter"], f2["filter"]))
|
||||
self.assertEqual(len(result), 10)
|
||||
result = json.loads(self.data.diffexp_topN(f1["filter"], f2["filter"], 20))
|
||||
result = json.loads(
|
||||
self.data.diffexp_topN(f1["filter"], f2["filter"], 20))
|
||||
self.assertEqual(len(result), 20)
|
||||
|
||||
|
||||
@@ -60,6 +62,7 @@ class DataLocatorEngineTest(unittest.TestCase):
|
||||
"""
|
||||
Test various types of data locators we expect to consume
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.args = {
|
||||
"layout": ["umap"],
|
||||
|
||||
@@ -14,6 +14,7 @@ from server.app.util.data_locator import DataLocator
|
||||
|
||||
|
||||
class WritableAnnotationTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.tmpDir = tempfile.mkdtemp()
|
||||
self.annotations_file = path.join(self.tmpDir, "test_annotations.csv")
|
||||
@@ -27,7 +28,8 @@ class WritableAnnotationTest(unittest.TestCase):
|
||||
"annotations_file": self.annotations_file,
|
||||
"annotations_output_dir": None
|
||||
}
|
||||
self.data = ScanpyEngine(DataLocator("../example-dataset/pbmc3k.h5ad"), args)
|
||||
self.data = ScanpyEngine(DataLocator("../example-dataset/pbmc3k.h5ad"),
|
||||
args)
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmpDir)
|
||||
@@ -41,7 +43,9 @@ class WritableAnnotationTest(unittest.TestCase):
|
||||
|
||||
n_rows = self.data.data.obs.shape[0]
|
||||
fbs_bad = self.make_fbs({
|
||||
'louvain': pd.Series(['undefined' for l in range(0, n_rows)], dtype='category')
|
||||
'louvain':
|
||||
pd.Series(['undefined' for l in range(0, n_rows)],
|
||||
dtype='category')
|
||||
})
|
||||
|
||||
# ensure attempt to change VAR annotation
|
||||
@@ -56,31 +60,49 @@ class WritableAnnotationTest(unittest.TestCase):
|
||||
# verify the file is written as expected
|
||||
n_rows = self.data.data.obs.shape[0]
|
||||
fbs = self.make_fbs({
|
||||
'cat_A': pd.Series(['label_A' for l in range(0, n_rows)], dtype='category'),
|
||||
'cat_B': pd.Series(['label_B' for l in range(0, n_rows)], dtype='category')
|
||||
'cat_A':
|
||||
pd.Series(['label_A' for l in range(0, n_rows)],
|
||||
dtype='category'),
|
||||
'cat_B':
|
||||
pd.Series(['label_B' for l in range(0, n_rows)],
|
||||
dtype='category')
|
||||
})
|
||||
res = self.data.annotation_put_fbs("obs", fbs)
|
||||
self.assertEqual(res, json.dumps({"status": "OK"}))
|
||||
self.assertTrue(path.exists(self.annotations_file))
|
||||
df = pd.read_csv(self.annotations_file, index_col=0, header=0, comment='#')
|
||||
df = pd.read_csv(self.annotations_file,
|
||||
index_col=0,
|
||||
header=0,
|
||||
comment='#')
|
||||
self.assertEqual(df.shape, (n_rows, 2))
|
||||
self.assertEqual(set(df.columns), set(['cat_A', 'cat_B']))
|
||||
self.assertTrue(self.data.original_obs_index.equals(df.index))
|
||||
self.assertTrue(np.all(df['cat_A'] == ['label_A' for l in range(0, n_rows)]))
|
||||
self.assertTrue(np.all(df['cat_B'] == ['label_B' for l in range(0, n_rows)]))
|
||||
self.assertTrue(
|
||||
np.all(df['cat_A'] == ['label_A' for l in range(0, n_rows)]))
|
||||
self.assertTrue(
|
||||
np.all(df['cat_B'] == ['label_B' for l in range(0, n_rows)]))
|
||||
|
||||
# verify complete overwrite on second attempt, AND rotation occurs
|
||||
fbs = self.make_fbs({
|
||||
'cat_A': pd.Series(['label_A1' for l in range(0, n_rows)], dtype='category'),
|
||||
'cat_C': pd.Series(['label_C' for l in range(0, n_rows)], dtype='category')
|
||||
'cat_A':
|
||||
pd.Series(['label_A1' for l in range(0, n_rows)],
|
||||
dtype='category'),
|
||||
'cat_C':
|
||||
pd.Series(['label_C' for l in range(0, n_rows)],
|
||||
dtype='category')
|
||||
})
|
||||
res = self.data.annotation_put_fbs("obs", fbs)
|
||||
self.assertEqual(res, json.dumps({"status": "OK"}))
|
||||
self.assertTrue(path.exists(self.annotations_file))
|
||||
df = pd.read_csv(self.annotations_file, index_col=0, header=0, comment='#')
|
||||
df = pd.read_csv(self.annotations_file,
|
||||
index_col=0,
|
||||
header=0,
|
||||
comment='#')
|
||||
self.assertEqual(set(df.columns), set(['cat_A', 'cat_C']))
|
||||
self.assertTrue(np.all(df['cat_A'] == ['label_A1' for l in range(0, n_rows)]))
|
||||
self.assertTrue(np.all(df['cat_C'] == ['label_C' for l in range(0, n_rows)]))
|
||||
self.assertTrue(
|
||||
np.all(df['cat_A'] == ['label_A1' for l in range(0, n_rows)]))
|
||||
self.assertTrue(
|
||||
np.all(df['cat_C'] == ['label_C' for l in range(0, n_rows)]))
|
||||
|
||||
# rotation
|
||||
name, ext = path.splitext(self.annotations_file)
|
||||
@@ -93,8 +115,12 @@ class WritableAnnotationTest(unittest.TestCase):
|
||||
# verify we stop rotation at 9
|
||||
n_rows = self.data.data.obs.shape[0]
|
||||
fbs = self.make_fbs({
|
||||
'cat_A': pd.Series(['label_A' for l in range(0, n_rows)], dtype='category'),
|
||||
'cat_B': pd.Series(['label_B' for l in range(0, n_rows)], dtype='category')
|
||||
'cat_A':
|
||||
pd.Series(['label_A' for l in range(0, n_rows)],
|
||||
dtype='category'),
|
||||
'cat_B':
|
||||
pd.Series(['label_B' for l in range(0, n_rows)],
|
||||
dtype='category')
|
||||
})
|
||||
for i in range(0, 11):
|
||||
res = self.data.annotation_put_fbs("obs", fbs)
|
||||
@@ -112,8 +138,12 @@ class WritableAnnotationTest(unittest.TestCase):
|
||||
|
||||
n_rows = self.data.data.obs.shape[0]
|
||||
fbs = self.make_fbs({
|
||||
'cat_A': pd.Series(['label_A' for l in range(0, n_rows)], dtype='category'),
|
||||
'cat_B': pd.Series(['label_B' for l in range(0, n_rows)], dtype='category')
|
||||
'cat_A':
|
||||
pd.Series(['label_A' for l in range(0, n_rows)],
|
||||
dtype='category'),
|
||||
'cat_B':
|
||||
pd.Series(['label_B' for l in range(0, n_rows)],
|
||||
dtype='category')
|
||||
})
|
||||
|
||||
# put
|
||||
@@ -129,27 +159,30 @@ class WritableAnnotationTest(unittest.TestCase):
|
||||
self.assertEqual(annotations["n_cols"], 7)
|
||||
self.assertIsNone(annotations["row_idx"])
|
||||
self.assertEqual(annotations["col_idx"], [
|
||||
obs_index_col_name, "n_genes", "percent_mito", "n_counts", "louvain", "cat_A", "cat_B"
|
||||
obs_index_col_name, "n_genes", "percent_mito", "n_counts",
|
||||
"louvain", "cat_A", "cat_B"
|
||||
])
|
||||
col_idx = annotations["col_idx"]
|
||||
self.assertEqual(annotations["columns"][col_idx.index('cat_A')], [
|
||||
'label_A' for l in range(0, n_rows)
|
||||
])
|
||||
self.assertEqual(annotations["columns"][col_idx.index('cat_B')], [
|
||||
'label_B' for l in range(0, n_rows)
|
||||
])
|
||||
self.assertEqual(annotations["columns"][col_idx.index('cat_A')],
|
||||
['label_A' for l in range(0, n_rows)])
|
||||
self.assertEqual(annotations["columns"][col_idx.index('cat_B')],
|
||||
['label_B' for l in range(0, n_rows)])
|
||||
|
||||
# verify the schema was updated
|
||||
all_col_schema = {c["name"]: c for c in schema["annotations"]["obs"]["columns"]}
|
||||
self.assertEqual(all_col_schema["cat_A"], {
|
||||
"name": "cat_A",
|
||||
"type": "categorical",
|
||||
"categories": ["label_A"],
|
||||
"writable": True
|
||||
})
|
||||
self.assertEqual(all_col_schema["cat_B"], {
|
||||
"name": "cat_B",
|
||||
"type": "categorical",
|
||||
"categories": ["label_B"],
|
||||
"writable": True
|
||||
})
|
||||
all_col_schema = {
|
||||
c["name"]: c for c in schema["annotations"]["obs"]["columns"]
|
||||
}
|
||||
self.assertEqual(
|
||||
all_col_schema["cat_A"], {
|
||||
"name": "cat_A",
|
||||
"type": "categorical",
|
||||
"categories": ["label_A"],
|
||||
"writable": True
|
||||
})
|
||||
self.assertEqual(
|
||||
all_col_schema["cat_B"], {
|
||||
"name": "cat_B",
|
||||
"type": "categorical",
|
||||
"categories": ["label_B"],
|
||||
"writable": True
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user