diff --git a/README.md b/README.md
index 14faafb..23f7ec4 100644
--- a/README.md
+++ b/README.md
@@ -13,26 +13,71 @@ Original H&E | Heatmap of Tumor Probability
See https://wsinfer.readthedocs.io for documentation.
+The main feature of WSInfer is a minimal command-line interface for running deep learning inference
+on whole slide images. Here is an example:
+
+```
+wsinfer run \
+ --wsi-dir slides/ \
+ --results-dir results/ \
+ --model breast-tumor-resnet34.tcga-brca
+```
+
# Installation
-## Pip
+WSInfer can be installed using `pip` or `conda`. WSInfer will install PyTorch automatically
+if it is not installed, but this may not install GPU-enabled PyTorch even if a GPU is available.
+For this reason, _install PyTorch before installing WSInfer_.
+
+## Install PyTorch first
+
+Please see [PyTorch's installation instructions](https://pytorch.org/get-started/locally/)
+for help installing PyTorch. The installation instructions differ based on your operating system
+and choice of `pip` or `conda`. Thankfully, the instructions provided
+by PyTorch also install the appropriate version of CUDA. We refrain from including code
+examples of installation commands because these commands can change over time. Please
+refer to [PyTorch's installation instructions](https://pytorch.org/get-started/locally/)
+for the most up-to-date instructions.
-WSInfer will install PyTorch automatically if it is not installed, but this may not
-install GPU-enabled PyTorch even if a GPU is available. For this reason, install PyTorch
-before installing WSInfer. Please see [PyTorch's installation instructions](https://pytorch.org/get-started/locally/)
-for help install PyTorch.
+You will need a new-enough driver for your NVIDIA GPU. Please see
+[this version compatibility table](https://docs.nvidia.com/deploy/cuda-compatibility/#minor-version-compatibility)
+for the minimum versions required for different CUDA versions.
+
+To test whether PyTorch can detect your GPU, check that this code snippet prints `True`.
+
+```
+python -c 'import torch; print(torch.cuda.is_available())'
+```
+
+## Install WSInfer
+
+WSInfer can be installed with `pip` or `conda` (from `conda-forge`).
+
+### Pip
+
+To install the latest stable version, use
```
python -m pip install wsinfer
```
-To use the _bleeding edge_, use
+To install the _bleeding edge_ (which may have breaking changes), use
```
python -m pip install git+https://github.com/SBU-BMI/wsinfer.git
```
-## Developers
+### Conda
+
+To install the latest stable version, use
+
+```
+conda install -c conda-forge wsinfer
+```
+
+If you use `mamba`, simply replace `conda install` with `mamba install`.
+
+### Developers
Clone this GitHub repository and install the package (in editable mode with the `dev` extras).
@@ -42,21 +87,17 @@ cd wsinfer
python -m pip install --editable .[dev]
```
-# Cutting a release
-
-When ready to cut a new release, follow these steps:
+# Citation
-1. Update the base image versions Dockerfiles in `dockerfiles/`. Update the version to
-the version you will release.
-2. Commit this change.
-3. Create a tag, where VERSION is a string like `v0.3.6`:
+If you find our work useful, please cite [our preprint](https://arxiv.org/abs/2309.04631)!
- ```
- git tag -a -m 'wsinfer version VERSION' VERSION
- ```
-
-4. Build wheel: `python -m build`
-5. Create a fresh virtual environment and install the wheel. Make sure `wsinfer --help` works.
-6. Push code to GitHub: `git push --tags`
-6. Build and push docker images: `bash scripts/build_docker_images.sh 0.3.6 1`
-7. Push wheel to PyPI: `twine upload dist/*`
+```bibtex
+@misc{kaczmarzyk2023open,
+ title={Open and reusable deep learning for pathology with WSInfer and QuPath},
+ author={Jakub R. Kaczmarzyk and Alan O'Callaghan and Fiona Inglis and Tahsin Kurc and Rajarsi Gupta and Erich Bremer and Peter Bankhead and Joel H. Saltz},
+ year={2023},
+ eprint={2309.04631},
+ archivePrefix={arXiv},
+ primaryClass={q-bio.TO}
+}
+```
diff --git a/docs/installing.rst b/docs/installing.rst
index f86dbdc..43f43a1 100644
--- a/docs/installing.rst
+++ b/docs/installing.rst
@@ -8,34 +8,86 @@ Prerequisites
WSInfer supports Python 3.8+ and has been tested on Windows, macOS, and Linux.
-WSInfer will install PyTorch automatically if it is not installed, but this may not
-install GPU-enabled PyTorch even if a GPU is available. For this reason, install PyTorch
-before installing WSInfer. Please see
-`PyTorch's installation instructions `_.
+WSInfer can be installed using :code:`pip` or :code:`conda`. WSInfer will install PyTorch automatically
+if it is not installed, but this may not install GPU-enabled PyTorch even if a GPU is available.
+For this reason, *install PyTorch before installing WSInfer*.
+Install PyTorch first
+^^^^^^^^^^^^^^^^^^^^^
-.. note::
+Please see `PyTorch's installation instructions `_
+for help installing PyTorch. The installation instructions differ based on your operating system
+and choice of :code:`pip` or :code:`conda`. Thankfully, the instructions provided
+by PyTorch also install the appropriate version of CUDA. We refrain from including code
+examples of installation commands because these commands can change over time. Please
+refer to `PyTorch's installation instructions `_
+for the most up-to-date instructions.
- Install PyTorch before installing WSInfer.
+You will need a new-enough driver for your NVIDIA GPU. Please see
+`this version compatibility table `_
+for the minimum versions required for different CUDA versions.
+To test whether PyTorch can detect your GPU, check that this code snippet prints :code:`True` ::
-Install with pip
+ python -c 'import torch; print(torch.cuda.is_available())'
+
+If your GPU is not available but you have a GPU, you can test if you installed a GPU-enabled PyTorch ::
+
+ python -c 'import torch; print(torch.version.cuda)'
+
+If that command does not print a version string (e.g., 11.7, 12.1), then you probably installed a CPU-only PyTorch.
+Re-install PyTorch with CUDA support.
+
+Another thing to test is that the environment variable :code:`CUDA_VISIBLE_DEVICES` is set. I (Jakub) have mine set to "0"
+because I have one GPU on my machine. If it is set to something other than "0", then PyTorch will not be able to
+detect the GPU.
+
+Install WSInfer
----------------
-After having installed PyTorch, install the latest release of WSInfer from `PyPI `_. ::
+WSInfer can be installed with :code:`pip` or :code:`conda` (from :code:`conda-forge`). In both cases, you get
+the :code:`wsinfer` command line tool and Python package.
+
+Pip
+^^^
- pip install wsinfer
+To install the latest stable version of WSInfer, use ::
-This installs the :code:`wsinfer` Python package and the :code:`wsinfer` command line program. ::
+ python -m pip install wsinfer
+
+To check the installation, type ::
wsinfer --help
-To install the latest unstable version of WSInfer, use ::
+To install the latest *unstable* version of WSInfer, use ::
+
+ python -m pip install git+https://github.com/SBU-BMI/wsinfer
+
+Conda
+^^^^^
+
+To install the latest stable version of WSInfer with :code:`conda`, use ::
+
+ conda install -c conda-forge wsinfer
+
+If you use :code:`mamba`, replace :code:`conda install` with :code:`mamba install`.
+
+To check the installation, type ::
+
+ wsinfer --help
+
+Developers
+^^^^^^^^^^
+
+Clone the GitHub repository and install the package in editable mode with the :code:`dev` extras ::
+
+ git clone https://github.com/SBU-BMI/wsinfer.git
+ cd wsinfer
+ python -m pip install --editable .[dev]
- pip install git+https://github.com/SBU-BMI/wsinfer
-Supported backends
-------------------
+Supported slide backends
+------------------------
WSInfer supports two backends for reading whole slide images: `OpenSlide `_
and `TiffSlide `_. When you install WSInfer, TiffSlide is also
diff --git a/docs/qupath_ext.rst b/docs/qupath_ext.rst
index 96f70f7..83af085 100644
--- a/docs/qupath_ext.rst
+++ b/docs/qupath_ext.rst
@@ -3,5 +3,5 @@
QuPath extension
================
-WSInfer has a QuPath extension for interactive model inference.
-See `the documentation on QuPath's website `_.
+WSInfer has a QuPath extension for interactive model inference. The documentation is part of QuPath's website.
+Please `see here `_.
diff --git a/docs/user_guide.rst b/docs/user_guide.rst
index b602dd9..d6d876f 100644
--- a/docs/user_guide.rst
+++ b/docs/user_guide.rst
@@ -3,15 +3,42 @@
User Guide
==========
-This guide assumes that you have a directory with at least one whole slide image.
+This guide assumes that you have installed WSInfer. If you have not, please see :ref:`installing`.
+
+It also assumes that you have a directory with at least one whole slide image.
If you do not, you can download a sample image from
https://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/.
-We assume the slides are saved to the directory :code:`slides`.
+The rest of this page assumes that slides are saved to the directory :code:`slides`.
+
+Getting help
+------------
+
+If you read the documentation but still have questions, need help, have feedback, found a bug,
+or just want to chat, please
+`submit a new issue `_ on our GitHub repo!
+
+Get help on the command line
+----------------------------
+
+Most command line tools in macOS and Linux can help you with the :code:`--help` flag.
+For example ::
+
+ wsinfer --help
+
+and ::
+
+ wsinfer run --help
+
+That will show you different subcommands, options, and expected inputs.
List available models
---------------------
+WSInfer includes a Zoo of pretrained models. List them with the :code:`wsinfer-zoo` command line tool,
+which is installed automatically with WSInfer. Please not the difference in the names :code:`wsinfer-zoo`
+and :code:`wsinfer`.
+
::
wsinfer-zoo ls
@@ -43,6 +70,42 @@ The option :code:`--wsi-dir` is a directory containing only whole slide images.
is the name of a model available in WSInfer. The model weights and configuration are
downloaded from HuggingFace Hub. If you would like to use your own model, see :ref:`Use your own model`.
+Outputs of model inference
+--------------------------
+
+The results directory will have several directories in it. We'll go over them now. ::
+
+ results
+ ├── masks
+ │ ├── TCGA-3C-AALI-01Z-00-DX1.F6E9A5DF-D8FB-45CF-B4BD-C6B76294C291.jpg
+ │ └── TCGA-3L-AA1B-01Z-00-DX1.8923A151-A690-40B7-9E5A-FCBEDFC2394F.jpg
+ ├── model-outputs-csv
+ │ ├── TCGA-3C-AALI-01Z-00-DX1.F6E9A5DF-D8FB-45CF-B4BD-C6B76294C291.csv
+ │ └── TCGA-3L-AA1B-01Z-00-DX1.8923A151-A690-40B7-9E5A-FCBEDFC2394F.csv
+ ├── model-outputs-geojson
+ │ ├── TCGA-3C-AALI-01Z-00-DX1.F6E9A5DF-D8FB-45CF-B4BD-C6B76294C291.json
+ │ └── TCGA-3L-AA1B-01Z-00-DX1.8923A151-A690-40B7-9E5A-FCBEDFC2394F.json
+ ├── patches
+ │ ├── TCGA-3C-AALI-01Z-00-DX1.F6E9A5DF-D8FB-45CF-B4BD-C6B76294C291.h5
+ │ └── TCGA-3L-AA1B-01Z-00-DX1.8923A151-A690-40B7-9E5A-FCBEDFC2394F.h5
+ └── run_metadata_20231110T235210.json
+
+This hierarchy is inspired by CLAM's outputs. The :code:`masks` directory contains JPEG images
+with thumbnails of the images and contours of the tissue and holes. The directory :code:`model-outputs-csv`
+contains one CSV per slide, and each CSV contains the patchwise model outputs. Each row is a different patch.
+Here are the feirst few rows of a sample CSV ::
+
+ minx,miny,width,height,prob_Tumor
+ 4200,27300,2100,2100,6.4415544e-05
+ 4200,29400,2100,2100,9.763688e-05
+ 4200,31500,2100,2100,0.03654445
+
+The directory :code:`model-outputs-geojson` contains the same information as the CSVs but in GeoJSON format.
+GeoJSON is well-suited for spatial data, and QuPath can read it! Just drag and drop the GeoJSON file into the
+QuPath window, and all of the patches and their model outputs will be appear. The directory :code:`patches`
+contains HDF5 files of the patch coordinates. Last, there is a JSON file containing metadata about this run.
+This has a timestamp in the filename in case you run inference multiple times to the same directory.
+
Run model inference in containers
---------------------------------
@@ -142,19 +205,6 @@ Once you create the configuration file, use the config with `wsinfer run`: ::
wsinfer run --wsi-dir slides/ --results-dir results/ --model-path path/to/torchscript.pt --config config.json
-
-Convert model outputs to GeoJSON (QuPath)
------------------------------------------
-
-GeoJSON is a JSON format compatible with whole slide image viewers like QuPath.
-
-::
-
- wsinfer togeojson results/ geojson-results/
-
-If you open one of your slides in QuPath, you can drag and drop the corresponding
-JSON file into the QuPath window to load the model outputs.
-
Convert model outputs to Stony Brook format (QuIP)
--------------------------------------------------