add support for corpora default_embedding field (#1696)

* fix mispelling

* re-implement re-embedding

* always load base embedding to fetch counts

* format

* lint

* fix tests

* lint

* fix accept handling

* test log

* more debug

* more

* more

* more

* more

* remove logging

* logging

* jsonify

* remove debugging logs

* lint

* clean up errors a bit

* fix issue found in PR review

* add support for corpora default_embedding

* fix botched merge

* PR review

* PR review
This commit is contained in:
Bruce Martin
2020-07-31 07:36:48 -07:00
committed by GitHub
parent 055511fe60
commit f2fbeff511
3 changed files with 91 additions and 3 deletions

View File

@@ -58,7 +58,7 @@ const doInitialDataLoad = () =>
dispatch({ type: "initial data load start" });
try {
const [, schema] = await Promise.all([
const [config, schema] = await Promise.all([
configFetch(dispatch),
schemaFetch(dispatch),
userColorsFetchAndLoad(dispatch),
@@ -75,6 +75,15 @@ const doInitialDataLoad = () =>
obsCrossfilter,
});
dispatch({ type: "initial data load complete" });
const defaultEmbedding = config?.parameters?.["default_embedding"];
const layoutSchema = schema?.schema?.layout?.obs ?? [];
if (
defaultEmbedding &&
layoutSchema.some((s) => s.name === defaultEmbedding)
) {
dispatch(embActions.layoutChoiceAction(defaultEmbedding));
}
} catch (error) {
dispatch({ type: "initial data load error", error });
}

View File

@@ -242,11 +242,17 @@ class AppConfig(object):
"about_legal_privacy": dataset_config.app__about_legal_privacy,
}
# dataset_props
# corpora dataset_props
# TODO/Note: putting info from the dataset into the /config is not ideal.
# However, it is definitely not part of /schema, and we do not have a top-level
# route for data properties. Consider creating one at some point.
corpora_props = data_adaptor.get_corpora_props()
if corpora_props and "default_embedding" in corpora_props:
default_embedding = corpora_props["default_embedding"]
if isinstance(default_embedding, str) and default_embedding.startswith("X_"):
default_embedding = default_embedding[2:] # drop X_ prefix
if default_embedding in data_adaptor.get_embedding_names():
parameters["default_embedding"] = default_embedding
data_adaptor.update_parameters(parameters)
if annotation:

View File

@@ -1,13 +1,19 @@
import unittest
import anndata
import json
import tempfile
import shutil
from http import HTTPStatus
import requests
from server.common.corpora import (
corpora_get_versions_from_anndata,
corpora_is_version_supported,
corpora_get_props_from_anndata,
)
from server.test import PROJECT_ROOT
from server.test import PROJECT_ROOT, start_test_server, stop_test_server
VERSION = "v0.2"
class CorporaAPITest(unittest.TestCase):
@@ -71,3 +77,70 @@ class CorporaAPITest(unittest.TestCase):
def _get_h5ad(self):
return anndata.read_h5ad(f"{PROJECT_ROOT}/example-dataset/pbmc3k.h5ad")
class CorporaRESTAPITest(unittest.TestCase):
""" Confirm endpoints reflect Corpora-specific features """
@classmethod
def setCorporaFields(cls, path):
adata = anndata.read_h5ad(path)
corpora_props = {
"version": {
"corpora_schema_version": "1.0.0",
"corpora_encoding_version": "0.1.0"
},
"title": "PBMC3K",
"contributors": json.dumps([
{"name": "name"}
]),
"layer_descriptions": {
"X": "raw counts"
},
"organism": "human",
"organism_ontology_term_id": "unknown",
"project_name": "test project",
"project_description": "test description",
"project_links": json.dumps([
{"link_name": "test link", "link_type": "SUMMARY", "link_url": "https://a.u.r.l/"}
]),
"default_embedding": "X_tsne"
}
adata.uns.update(corpora_props)
adata.write(path)
@classmethod
def setUpClass(cls):
cls.tmp_dir = tempfile.TemporaryDirectory()
src = f"{PROJECT_ROOT}/example-dataset/pbmc3k.h5ad"
dst = f"{cls.tmp_dir.name}/pbmc3k.h5ad"
shutil.copyfile(src, dst)
cls.setCorporaFields(dst)
cls.ps, cls.server = start_test_server([dst])
@classmethod
def tearDownClass(cls):
stop_test_server(cls.ps)
cls.tmp_dir.cleanup()
def setUp(self):
self.session = requests.Session()
self.url_base = f"{self.server}/api/{VERSION}/"
def test_config(self):
endpoint = "config"
url = f"{self.url_base}{endpoint}"
result = self.session.get(url)
self.assertEqual(result.status_code, HTTPStatus.OK)
self.assertEqual(result.headers["Content-Type"], "application/json")
result_data = result.json()
self.assertIsInstance(result_data["config"]["corpora_props"], dict)
self.assertIsInstance(result_data["config"]["parameters"], dict)
corpora_props = result_data["config"]["corpora_props"]
parameters = result_data["config"]["parameters"]
self.assertEqual(corpora_props["version"]["corpora_schema_version"], "1.0.0")
self.assertEqual(corpora_props["organism"], "human")
self.assertEqual(parameters["default_embedding"], "tsne")