diff --git a/client/Makefile b/client/Makefile index d6c5ef03..946df296 100644 --- a/client/Makefile +++ b/client/Makefile @@ -44,13 +44,9 @@ start-server: backend-dev: server-requirements source ../venv/bin/activate && $(MAKE) start-server -.PHONY: backend-dev-anno -backend-dev-anno: server-requirements - CXG_OPTIONS='--experimental-annotations' $(MAKE) backend-dev - .PHONY: backend-dev-anno-ontology backend-dev-anno-ontology: server-requirements - CXG_OPTIONS='--experimental-annotations --experimental-annotations-ontology' \ + CXG_OPTIONS='--experimental-annotations-ontology' \ $(MAKE) backend-dev .PHONY: test @@ -73,7 +69,10 @@ e2e-annotations: .PHONY: smoke-test smoke-test: - start_server_and_test '$(MAKE) start-server' $(CXG_SERVER_PORT) '$(MAKE) e2e' + start_server_and_test \ + 'CXG_OPTIONS="--disable-annotations" $(MAKE) start-server' \ + $(CXG_SERVER_PORT) \ + '$(MAKE) e2e' .PHONY: smoke-test-annotations @@ -81,7 +80,7 @@ smoke-test-annotations: $(eval TMP_DIR := $(shell mktemp -d /tmp/cellxgene_XXXXXX)) cp $(ANNOTATIONS) $(TMP_DIR)/ && \ start_server_and_test \ - 'CXG_OPTIONS="--experimental-annotations --experimental-annotations-file $(TMP_DIR)/$(ANNOTATIONS_FILENAME)" $(MAKE) start-server' \ + 'CXG_OPTIONS="--annotations-file $(TMP_DIR)/$(ANNOTATIONS_FILENAME)" $(MAKE) start-server' \ $(CXG_SERVER_PORT) \ '$(MAKE) e2e-annotations' rm -rf $(TMP_DIR) diff --git a/docs/posts/annotations.md b/docs/posts/annotations.md index 5b215bee..99e97c8a 100644 --- a/docs/posts/annotations.md +++ b/docs/posts/annotations.md @@ -13,7 +13,7 @@ We are _piloting_ a new feature in cellxgene that enables users to create and ed To get started, run: ``` -cellxgene launch mydata.h5ad --experimental-annotations +cellxgene launch mydata.h5ad ``` To preserve data provenance, **`cellxgene` does not alter the input h5ad file**. Rather, newly-created annotations are saved in a specified CSV file: @@ -21,8 +21,7 @@ To preserve data provenance, **`cellxgene` does not alter the input h5ad file**. annotations-directory/name-########.csv ``` -- The default `annotations-directory` is your current working directory (i.e., the directory you were in when you started cellxgene). - +- The default `annotations-directory` is your current working directory (i.e., the directory you were in when you started cellxgene). - You will be prompted to enter a name for your annotations the first time you create a new category. - We also assign a unique identifier in the form of an 8-character suffix, `########`; this helps cellxgene identify your file to avoid overwriting your work. @@ -36,10 +35,7 @@ There are two options for updating draft annotations. ### Autodetect annotations csv -Cellxgene can automatically find and reload your draft annotations in editable mode like so: -``` -annotations-directory$ cellxgene launch mydata.h5ad --experimental-annotations -``` +Cellxgene will automatically find and reload your draft annotations in editable mode. This assumes that: 1 - The h5ad filename is the same @@ -52,7 +48,7 @@ This assumes that: If you'd like to specify the complete file path for your annotations, you can do so by running: ``` -cellxgene launch mydata.h5ad --experimental-annotations --experimental-annotations-file path/to/myfile.csv +cellxgene launch mydata.h5ad --annotations-file path/to/myfile.csv ``` Any changes you make will be reflected in the original CSV. If the file does not exist, it will be created. @@ -83,7 +79,7 @@ Specifying a single file name for multiple contributors will result in data over To specify an output directory, run: ``` -cellxgene launch mydata.h5ad --experimental-annotations --experimental-annotations-output-dir path/to/annotations-directory/ +cellxgene launch mydata.h5ad --annotations-dir path/to/annotations-directory/ ``` For each user, annotations will be saved as follows: @@ -93,8 +89,6 @@ For each user, annotations will be saved as follows: - - ## FAQ ### How do I know my annotations are saved? @@ -113,4 +107,4 @@ This is most likely because the h5ad file you are working with is not the origin We place a small cookie (file) in your browser that identifies where your draft annotations are saved. This file never leaves your machine, and is never sent to the cellxgene team or anyone else. ### I have feedback and ideas for you! -Wonderful! This is a very new and complex feature; we would _love_ to [hear your feedback](contact) :) +Wonderful! This is a relatively new feature; we would _love_ to [hear your feedback](contact) :) diff --git a/docs/posts/hosted.md b/docs/posts/hosted.md index 6882abd0..3fde580e 100644 --- a/docs/posts/hosted.md +++ b/docs/posts/hosted.md @@ -23,9 +23,9 @@ The following configuration options require special consideration in any multi-u `--disable-diffexp`: the differential expression computation can be resource intensive, in particular for large datasets. If many differential expression calculation requests are made in rapid sequence, it may cause the server CPU or memory resources to be exhausted, and impact the ability of other users to access data. This command line option will disable the differential expression feature, including the removal of the `Differential expression` button. -`--experimental-annotations`: this feature, which is disabled by default, may not be appropriate for hosted environments. It will write to the local file system, and in extreme cases could be used to abuse (or exceed) file system capacity on the hosting server. +`--disable-annotations`: annotations, which is enabled by default, may not be appropriate for hosted environments. It will write to the local file system, and in extreme cases could be used to abuse (or exceed) file system capacity on the hosting server. We recommend disabling this with this flag. -`--experimental-annotations-file`: this specifies a single file for all end-user annotations, and is incompatible with hosted or multi-user use of cellxgene. Using it will cause loss of user annotation data (ie, the CSV file will be overwritten). If you wish to explore using the _experimental_ annotations feature in a multi-user environment, please refer to the [annotations documentation](annotations). +`--annotations-file`: this specifies a single file for all end-user annotations, and is incompatible with hosted or multi-user use of cellxgene. Using it will cause loss of user annotation data (ie, the CSV file will be overwritten). If you wish to explore using the annotations feature in a multi-user environment, please refer to the [annotations documentation](annotations). ## Community software projects diff --git a/docs/posts/launch.md b/docs/posts/launch.md index 0aeadc9c..826945e5 100644 --- a/docs/posts/launch.md +++ b/docs/posts/launch.md @@ -46,7 +46,7 @@ cellxgene launch s3://mybucket.s3-us-west-2.amazonaws.com/mydata.h5ad `--open` automatically opens the web browser after launching (caveat: only works on some operating systems). -`--experimental-annotations`, `--experimental-annotations-file` & `--experimental-annotations-output-dir` all have to do with an experimental feature to allow users to create new categorical annotations in the application. We have a [whole separate page](annotations) about their usage! :) +`--disable-annotations`, `--annotations-file` & `--annotations-dir` all have to do with creating new categorical annotations in the application. We have a [whole separate page](annotations) about their usage! :) `--diffexp-lfc-cutoff` as explained [in the methods](methods), genes are only returned in differential expression if the effect size is above the specified threshold for log fold change. Defaults to 0.01. diff --git a/server/cli/launch.py b/server/cli/launch.py index 75bf5ae6..bc5661f8 100644 --- a/server/cli/launch.py +++ b/server/cli/launch.py @@ -26,29 +26,29 @@ DEFAULT_SERVER_PORT = int(environ.get("CXG_SERVER_PORT", "5005")) def annotation_args(func): @click.option( - "--experimental-annotations", + "--disable-annotations", is_flag=True, default=False, show_default=True, - help="Enable user annotation of data.", + help="Disable user annotation of data.", ) @click.option( - "--experimental-annotations-file", + "--annotations-file", default=None, show_default=True, multiple=False, metavar="", help="CSV file to initialize editing of existing annotations; will be altered in-place. " - "Incompatible with --annotations-output-dir.", + "Incompatible with --annotations-dir.", ) @click.option( - "--experimental-annotations-output-dir", + "--annotations-dir", default=None, show_default=False, multiple=False, metavar="", help="Directory of where to save output annotations; filename will be specified in the application. " - "Incompatible with --annotations-input-file.", + "Incompatible with --annotations-file.", ) @click.option( "--experimental-annotations-ontology", @@ -279,9 +279,9 @@ def launch( title, scripts, about, - experimental_annotations, - experimental_annotations_file, - experimental_annotations_output_dir, + disable_annotations, + annotations_file, + annotations_dir, backed, disable_diffexp, experimental_annotations_ontology, @@ -359,32 +359,32 @@ def launch( else: port = find_available_port(host, DEFAULT_SERVER_PORT) - if not experimental_annotations: - if experimental_annotations_file is not None: - click.echo("Warning: --experimental-annotations-file ignored as --annotations not enabled.") - if experimental_annotations_output_dir is not None: - click.echo("Warning: --experimental-annotations-output-dir ignored as --annotations not enabled.") + if disable_annotations: + if annotations_file is not None: + click.echo("Warning: --annotations-file ignored as annotations are disabled.") + if annotations_dir is not None: + click.echo("Warning: --annotations-dir ignored as annotations are disabled.") if experimental_annotations_ontology: - click.echo("Warning: --experimental-annotations-ontology ignored as --annotations not enabled.") + click.echo("Warning: --experimental-annotations-ontology ignored as annotations are disabled.") if experimental_annotations_ontology_obo is not None: - click.echo("Warning: --experimental-annotations-ontology-obo ignored as --annotations not enabled.") + click.echo("Warning: --experimental-annotations-ontology-obo ignored as annotations are disabled.") else: - if experimental_annotations_file is not None and experimental_annotations_output_dir is not None: + if annotations_file is not None and annotations_dir is not None: raise click.ClickException( - "--experimental-annotations-file and --experimental-annotations-output-dir " "may not be used together." + "--annotations-file and --annotations-dir " "may not be used together." ) - if experimental_annotations_file is not None: - lf_name, lf_ext = splitext(experimental_annotations_file) + if annotations_file is not None: + lf_name, lf_ext = splitext(annotations_file) if lf_ext and lf_ext != ".csv": - raise click.FileError(basename(experimental_annotations_file), hint="annotation file type must be .csv") + raise click.FileError(basename(annotations_file), hint="annotation file type must be .csv") - if experimental_annotations_output_dir is not None and not isdir(experimental_annotations_output_dir): + if annotations_dir is not None and not isdir(annotations_dir): try: - mkdir(experimental_annotations_output_dir) + mkdir(annotations_dir) except OSError: raise click.ClickException( - "Unable to create directory specified by " "--experimental-annotations-output-dir" + "Unable to create directory specified by " "--annotations-dir" ) if about: @@ -438,13 +438,13 @@ def launch( # create an annotations object. Only AnnotationsLocalFile is used (for now) annotations = None - if experimental_annotations: - annotations = AnnotationsLocalFile(experimental_annotations_output_dir, experimental_annotations_file) + if not disable_annotations: + annotations = AnnotationsLocalFile(annotations_dir, annotations_file) # if the user has specified a fixed label file, go ahead and validate it # so that we can remove errors early in the process. - if experimental_annotations_file and data_adaptor: + if annotations_file and data_adaptor: data_adaptor.check_new_labels(annotations.read_labels(data_adaptor)) if experimental_annotations_ontology or bool(experimental_annotations_ontology_obo): diff --git a/server/common/app_config.py b/server/common/app_config.py index faa2eccd..f2b54811 100644 --- a/server/common/app_config.py +++ b/server/common/app_config.py @@ -110,7 +110,7 @@ class AppConfig(object): "enable-reembedding": self.enable_reembedding, "annotations": False, "annotations_file": None, - "annotations_output_dir": None, + "annotations_dir": None, "annotations_cell_ontology_enabled": False, "annotations_cell_ontology_obopath": None, "annotations_cell_ontology_terms": None, diff --git a/server/test/test_api.py b/server/test/test_api.py index c6e1948e..14ca30a5 100644 --- a/server/test/test_api.py +++ b/server/test/test_api.py @@ -17,7 +17,7 @@ BAD_FILTER = {"filter": {"obs": {"annotation_value": [{"name": "xyz"}]}}} class EndPoints(object): - ANNOTATIONS_ENABLED = False + ANNOTATIONS_ENABLED = True def setUp(self): self.session = requests.Session() @@ -324,6 +324,7 @@ class EndPointsAnndata(unittest.TestCase, EndPoints): LOCAL_URL = f"http://127.0.0.1:{PORT}/" VERSION = "v0.2" URL_BASE = f"{LOCAL_URL}api/{VERSION}/" + ANNOTATIONS_ENABLED = False @classmethod def setUpClass(cls): @@ -334,6 +335,7 @@ class EndPointsAnndata(unittest.TestCase, EndPoints): "--no-upgrade-check", "launch", "../example-dataset/pbmc3k.h5ad", + "--disable-annotations", "--verbose", "--port", str(cls.PORT), @@ -356,6 +358,7 @@ class EndPointsCxg(unittest.TestCase, EndPoints): LOCAL_URL = f"http://127.0.0.1:{PORT}/" VERSION = "v0.2" URL_BASE = f"{LOCAL_URL}api/{VERSION}/" + ANNOTATIONS_ENABLED = False @classmethod def setUpClass(cls): @@ -366,6 +369,7 @@ class EndPointsCxg(unittest.TestCase, EndPoints): "--no-upgrade-check", "launch", "test/test_datasets/pbmc3k.cxg", + "--disable-annotations", "--verbose", "--port", str(cls.PORT), @@ -398,8 +402,7 @@ class EndPointsAnndataAnnotations(unittest.TestCase, EndPointsAnnotations): "cellxgene", "--no-upgrade-check", "launch", - "--experimental-annotations", - "--experimental-annotations-file", + "--annotations-file", cls.annotations.output_file, "--verbose", "--port", @@ -433,8 +436,7 @@ class EndPointsCxgAnnotations(unittest.TestCase, EndPointsAnnotations): "cellxgene", "--no-upgrade-check", "launch", - "--experimental-annotations", - "--experimental-annotations-file", + "--annotations-file", cls.annotations.output_file, "--verbose", "--port",