Apply yapf to python files

This commit is contained in:
Matt Weiden
2019-12-19 15:20:41 -08:00
parent 42a8d45bd7
commit cdca128a01
43 changed files with 1143 additions and 678 deletions
+11 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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:
+43 -95
View File
@@ -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()))
+10 -6
View File
@@ -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]))
+17 -15
View File
@@ -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]))
+64 -26
View File
@@ -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")
+4 -1
View File
@@ -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"],
+69 -36
View File
@@ -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
})