diff --git a/.github/ISSUE_TEMPLATE/README.md b/.github/ISSUE_TEMPLATE/README.md
new file mode 100644
index 000000000..0ae02773e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/README.md
@@ -0,0 +1,10 @@
+## 'ISSUE_TEMPLATE' Directory Contents
+
+### Files
+
+bug_report.yml
+
+feature_request.yaml
+
+voxl.yml
+
diff --git a/.github/workflows/README.md b/.github/workflows/README.md
new file mode 100644
index 000000000..7a4b38642
--- /dev/null
+++ b/.github/workflows/README.md
@@ -0,0 +1,6 @@
+## 'workflows' Directory Contents
+
+### Files
+
+main.yml
+
diff --git a/README.md b/README.md
index e9a30860d..bf779e8d8 100644
--- a/README.md
+++ b/README.md
@@ -6,13 +6,19 @@
PIXL Image eXtraction Laboratory
`PIXL` is a system for extracting, linking and de-identifying DICOM imaging data, structured EHR data and free-text data from radiology reports at UCLH.
-Please see the [rolling-skeleton]([https://github.com/SAFEHR-data/the-rolling-skeleton=](https://github.com/SAFEHR-data/the-rolling-skeleton/blob/main/docs/design/100-day-design.md)) for more details.
-PIXL is intended run on one of the [GAE (General Application Environments)](https://github.com/SAFEHR-data/Book-of-FlowEHR/blob/main/glossary.md#gaes)s and comprises
-several services orchestrated by [Docker Compose](https://docs.docker.com/compose/).
+It comprises several services orchestrated by [Docker Compose](https://docs.docker.com/compose/).
+
+UCLH SPECIFIC
+
+PIXL is intended run on one of the [GAE (General Application Environments)](https://github.com/SAFEHR-data/Book-of-FlowEHR/blob/main/glossary.md#gaes)s.
To get access to the GAE, [see the documentation on Slab](https://uclh.slab.com/posts/gae-access-7hkddxap).
-Please request access to Slab and add further details in a [new blank issue](https://github.com/SAFEHR-data/PIXL/issues/new).
+
+Please request access to Slab and add further details in a [new blank issue](https://github.com/SAFEHR-data/PIXL/issues/new).
+
+
+
## Installation
@@ -67,7 +73,7 @@ destination.
Provides helper functions for de-identifying DICOM data
-### PostgreSQL
+### [PostgreSQL](.postgres/README.md)
RDBMS which stores DICOM metadata, application data and anonymised patient record data.
@@ -79,7 +85,7 @@ HTTP API to export files (parquet and DICOM) from UCLH to endpoints.
HTTP API to process messages from the `imaging` queue and populate the raw orthanc instance with images from PACS/VNA.
-## Setup `PIXL` in GAE
+## Setup `PIXL`
Click here to expand steps and configurations
@@ -202,7 +208,7 @@ These variables can be set in the `.env` file.
For testing, they can be set in the `test/.secrets.env` file.
For dev purposes find the `pixl-dev-secrets.env` note on LastPass for the necessary values.
-If an Azure Keyvault hasn't been set up yet, follow [these instructions](./docs/setup/azure-keyvault.md).
+At UCLH if an Azure Keyvault hasn't been set up yet, follow [these instructions](./docs/setup/azure-keyvault.md).
A second Azure Keyvault is used to store hashing keys and salts for the `hasher` service.
This kevyault is configured with the following environment variables:
@@ -218,7 +224,7 @@ See the [hasher documentation](./hasher/README.md) for more information.
-## Run `PIXL` in GAE
+## Run `PIXL`
Click here to view detailed steps
@@ -278,6 +284,9 @@ test/resources/omop/public /*.parquet
### OMOP ES extract dir (input to PIXL)
+>[!NOTE]
+> OMOP ES is the tool used to extract Electronic Health Records that may be linked to images.
+
EXTRACT_DIR is the directory passed to `pixl populate` as the input `PARQUET_PATH` argument.
```
@@ -288,8 +297,8 @@ EXTRACT_DIR/public /*.parquet
### PIXL Export dir (PIXL intermediate)
-The directory where PIXL will copy the public OMOP extract files (which now contain
-the radiology reports) to.
+The directory where PIXL will copy the public OMOP extract files and the radiology reports.
+
These files will subsequently be uploaded to the `parquet` destination specified in the
[project config](#3-configure-a-new-project).
@@ -310,10 +319,63 @@ FTPROOT/PROJECT_SLUG/EXTRACT_DATETIME/parquet/radiology/radiology.parquet
..............................................omop/public/*.parquet
```
-## :octocat: Cloning repository
-* Generate your SSH keys as suggested [here](https://docs.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
-* Clone the repository by typing (or copying) the following lines in a terminal
-```
-git clone git@github.com:SAFEHR-data/PIXL.git
-```
+## 'PIXL' Directory Contents
+
+
+
+
+ Subdirectories with links to the relevant README
+
+
+
+
+[bin](./bin/README.md)
+
+[cli](./cli/README.md)
+
+[docker](./docker/README.md)
+
+[docs](./docs/README.md)
+
+[hasher](./hasher/README.md)
+
+[orthanc](./orthanc/README.md)
+
+[pixl_core](./pixl_core/README.md)
+
+[pixl_dcmd](./pixl_dcmd/README.md)
+
+[pixl_export](./pixl_export/README.md)
+
+[pixl_imaging](./pixl_imaging/README.md)
+
+[postgres](./postgres/README.md)
+
+[projects](./projects/README.md)
+
+[pytest-pixl](./pytest-pixl/README.md)
+
+[schemas](./schemas/README.md)
+
+[scripts](./scripts/README.md)
+
+[test](./test/README.md)
+
+
+
+
+### Files
+
+
+
+| **Configuration** | **User docs** | **Housekeeping** |
+| :--- | :--- | :--- |
+| .env.sample | CODE_OF_CONDUCT.md | .renovaterc.json5 |
+| .pre-commit-config.yaml | CONTRIBUTING.md | codecov.yml |
+| docker-compose.yml | LICENSE | |
+| mypy.ini | NOTICE | |
+| pytest.ini | README.md | |
+| ruff.toml | | |
+| template_config.yaml | | |
+
\ No newline at end of file
diff --git a/bin/README.md b/bin/README.md
new file mode 100644
index 000000000..eedf89797
--- /dev/null
+++ b/bin/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/bin' Directory Contents
+
+### Subdirectories
+
+[linters](./linters/README.md)
+
diff --git a/bin/linters/README.md b/bin/linters/README.md
new file mode 100644
index 000000000..a03874a75
--- /dev/null
+++ b/bin/linters/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/bin/linters' Directory Contents
+
+### Files
+
+check_headers_exist.sh
+
diff --git a/cli/README.md b/cli/README.md
index 374c358bd..bbbddeef6 100644
--- a/cli/README.md
+++ b/cli/README.md
@@ -142,3 +142,18 @@ The CLI tests require a running instance of the `rabbitmq` service, for which we
pytest -vs tests #for all tests
pytest -vs tests/test_docker_commands.py #e.g., for particular tests
```
+
+## 'PIXL/cli' Directory Contents
+
+### Subdirectories
+
+[src](./src/README.md)
+
+[tests](./tests/README.md)
+
+### Files
+
+pyproject.toml
+
+README.md
+
diff --git a/cli/src/README.md b/cli/src/README.md
new file mode 100644
index 000000000..807a572b5
--- /dev/null
+++ b/cli/src/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/cli/src' Directory Contents
+
+### Subdirectories
+
+[pixl_cli](./pixl_cli/README.md)
+
diff --git a/cli/src/pixl_cli/README.md b/cli/src/pixl_cli/README.md
new file mode 100644
index 000000000..11f286869
--- /dev/null
+++ b/cli/src/pixl_cli/README.md
@@ -0,0 +1,18 @@
+## 'PIXL/cli/src/pixl_cli' Directory Contents
+
+### Files
+
+main.py
+
+_config.py
+
+_database.py
+
+_docker_commands.py
+
+_io.py
+
+_message_processing.py
+
+__init__.py
+
diff --git a/cli/tests/README.md b/cli/tests/README.md
index 280d3bf6b..85977d651 100644
--- a/cli/tests/README.md
+++ b/cli/tests/README.md
@@ -5,3 +5,25 @@ Remove the db container and associated data
docker container rm pixl-test-db -v -f
```
+## 'PIXL/cli/tests' Directory Contents
+
+### Files
+
+conftest.py
+
+README.md
+
+test_check_env.py
+
+test_database.py
+
+test_docker_commands.py
+
+test_io.py
+
+test_messages_from_files.py
+
+test_message_processing.py
+
+test_populate.py
+
diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 000000000..d423d8cb6
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,22 @@
+## 'PIXL/docker' Directory Contents
+
+### Subdirectories
+
+[export-api](./export-api/README.md)
+
+[hasher-api](./hasher-api/README.md)
+
+[imaging-api](./imaging-api/README.md)
+
+[orthanc-anon](./orthanc-anon/README.md)
+
+[orthanc-raw](./orthanc-raw/README.md)
+
+[postgres](./postgres/README.md)
+
+### Files
+
+.dockerignore
+
+common.env
+
diff --git a/docker/hasher-api/README.md b/docker/hasher-api/README.md
new file mode 100644
index 000000000..f54e14972
--- /dev/null
+++ b/docker/hasher-api/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/docker/hasher-api' Directory Contents
+
+### Files
+
+Dockerfile
+
diff --git a/docker/imaging-api/README.md b/docker/imaging-api/README.md
new file mode 100644
index 000000000..400bee965
--- /dev/null
+++ b/docker/imaging-api/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/docker/imaging-api' Directory Contents
+
+### Files
+
+Dockerfile
+
diff --git a/docker/orthanc-anon/README.md b/docker/orthanc-anon/README.md
new file mode 100644
index 000000000..b1f2a60bc
--- /dev/null
+++ b/docker/orthanc-anon/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/docker/orthanc-anon' Directory Contents
+
+### Files
+
+Dockerfile
+
diff --git a/docker/orthanc/README.md b/docker/orthanc/README.md
new file mode 100644
index 000000000..a137fb98a
--- /dev/null
+++ b/docker/orthanc/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/docker/orthanc-raw' Directory Contents
+
+### Files
+
+Dockerfile
+
diff --git a/docker/pixl-python/README.md b/docker/pixl-python/README.md
new file mode 100644
index 000000000..f12d22846
--- /dev/null
+++ b/docker/pixl-python/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/docker/export-api' Directory Contents
+
+### Files
+
+Dockerfile
+
diff --git a/docker/postgres/README.md b/docker/postgres/README.md
new file mode 100644
index 000000000..f43084e01
--- /dev/null
+++ b/docker/postgres/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/docker/postgres' Directory Contents
+
+### Files
+
+Dockerfile
+
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 000000000..26ff7826b
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,14 @@
+## 'PIXL/docs' Directory Contents
+
+### Subdirectories
+
+[design](./design/README.md)
+
+[file_types](./file_types/README.md)
+
+[joss-publication](./joss-publication/README.md)
+
+[services](./services/README.md)
+
+[setup](./setup/README.md)
+
diff --git a/docs/design/README.md b/docs/design/README.md
new file mode 100644
index 000000000..f2b57d6bd
--- /dev/null
+++ b/docs/design/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/docs/design' Directory Contents
+
+### Subdirectories
+
+[diagrams](./diagrams/README.md)
+
+### Files
+
+bigger_picture.md
+
diff --git a/docs/design/diagrams/README.md b/docs/design/diagrams/README.md
new file mode 100644
index 000000000..7da298bcc
--- /dev/null
+++ b/docs/design/diagrams/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/docs/design/diagrams' Directory Contents
+
+### Files
+
+pixl-multi-project-config.drawio
+
+pixl-multi-project-config.png
+
diff --git a/docs/file_types/README.md b/docs/file_types/README.md
new file mode 100644
index 000000000..a24a35216
--- /dev/null
+++ b/docs/file_types/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/docs/file_types' Directory Contents
+
+### Files
+
+parquet_files.md
+
diff --git a/docs/joss-publication/README.md b/docs/joss-publication/README.md
new file mode 100644
index 000000000..83800df8e
--- /dev/null
+++ b/docs/joss-publication/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/docs/joss-publication' Directory Contents
+
+### Subdirectories
+
+[figures](./figures/README.md)
+
+### Files
+
+paper.bib
+
+paper.md
+
diff --git a/docs/joss-publication/figures/README.md b/docs/joss-publication/figures/README.md
new file mode 100644
index 000000000..c6147e300
--- /dev/null
+++ b/docs/joss-publication/figures/README.md
@@ -0,0 +1,2 @@
+## 'PIXL/docs/joss-publication/figures' Directory Contents
+
diff --git a/docs/joss-publication/paper.bib b/docs/joss-publication/paper.bib
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/joss-publication/paper.md b/docs/joss-publication/paper.md
new file mode 100644
index 000000000..c6c0206c8
--- /dev/null
+++ b/docs/joss-publication/paper.md
@@ -0,0 +1 @@
+This is the file where the paper must be written
\ No newline at end of file
diff --git a/docs/services/README.md b/docs/services/README.md
new file mode 100644
index 000000000..f0337901a
--- /dev/null
+++ b/docs/services/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/docs/services' Directory Contents
+
+### Files
+
+ftp-server.md
+
+pixl_database.md
+
diff --git a/docs/setup/README.md b/docs/setup/README.md
new file mode 100644
index 000000000..fd9845552
--- /dev/null
+++ b/docs/setup/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/docs/setup' Directory Contents
+
+### Files
+
+azure-keyvault.md
+
+developer.md
+
+uclh-infrastructure-setup.md
+
diff --git a/hasher/README.md b/hasher/README.md
index 3119a298f..b9055be2c 100644
--- a/hasher/README.md
+++ b/hasher/README.md
@@ -67,3 +67,18 @@ HASHER_API_AZ_CLIENT_PASSWORD=
HASHER_API_AZ_TENANT_ID=
HASHER_API_AZ_KEY_VAULT_NAME=
```
+
+## 'PIXL/hasher' Directory Contents
+
+### Subdirectories
+
+[src](./src/README.md)
+
+[tests](./tests/README.md)
+
+### Files
+
+pyproject.toml
+
+README.md
+
diff --git a/hasher/src/README.md b/hasher/src/README.md
new file mode 100644
index 000000000..99a56a701
--- /dev/null
+++ b/hasher/src/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/hasher/src' Directory Contents
+
+### Subdirectories
+
+[hasher](./hasher/README.md)
+
diff --git a/hasher/src/hasher/README.md b/hasher/src/hasher/README.md
new file mode 100644
index 000000000..40b064a8d
--- /dev/null
+++ b/hasher/src/hasher/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/hasher/src/hasher' Directory Contents
+
+### Files
+
+endpoints.py
+
+hashing.py
+
+main.py
+
+__init__.py
+
diff --git a/hasher/tests/README.md b/hasher/tests/README.md
new file mode 100644
index 000000000..1a161940e
--- /dev/null
+++ b/hasher/tests/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/hasher/tests' Directory Contents
+
+### Files
+
+conftest.py
+
+test_endpoints.py
+
+test_hashing.py
+
+__init__.py
+
diff --git a/orthanc/README.md b/orthanc/README.md
index 1683a2e5d..674d7d272 100644
--- a/orthanc/README.md
+++ b/orthanc/README.md
@@ -9,3 +9,18 @@ PIXL defines 2 types of ORTHANC instances:
For both instances we define a plugin in `orthanc-*/plugin/pixl.py` that implements the custom
functionality .
+
+## 'PIXL/orthanc' Directory Contents
+
+### Subdirectories
+
+[assets](./assets/README.md)
+
+[orthanc-anon](./orthanc-anon/README.md)
+
+[orthanc-raw](./orthanc-raw/README.md)
+
+### Files
+
+README.md
+
diff --git a/orthanc/assets/README.md b/orthanc/assets/README.md
new file mode 100644
index 000000000..e6468fad6
--- /dev/null
+++ b/orthanc/assets/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/orthanc/assets' Directory Contents
+
+### Files
+
+orthanc-anon-az-dicom.png
+
+orthanc-anon-web.png
+
+orthanc-raw-web.png
+
diff --git a/orthanc/orthanc-anon/README.md b/orthanc/orthanc-anon/README.md
index 784084e9c..5b386ea5e 100644
--- a/orthanc/orthanc-anon/README.md
+++ b/orthanc/orthanc-anon/README.md
@@ -104,3 +104,18 @@ start.
## References
- [Cheat sheet of the REST API](https://book.orthanc-server.com/users/rest-cheatsheet.html)
+
+## 'orthanc' Directory Contents
+
+### Subdirectories
+
+[assets](./assets/README.md)
+
+[orthanc-anon](./orthanc-anon/README.md)
+
+[orthanc-raw](./orthanc-raw/README.md)
+
+### Files
+
+README.md
+
diff --git a/orthanc/orthanc-anon/config/README.md b/orthanc/orthanc-anon/config/README.md
new file mode 100644
index 000000000..ef5de4dce
--- /dev/null
+++ b/orthanc/orthanc-anon/config/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/orthanc/orthanc-anon/config' Directory Contents
+
+### Files
+
+dicom.json
+
+orthanc.json
+
diff --git a/orthanc/orthanc-anon/docs/README.md b/orthanc/orthanc-anon/docs/README.md
new file mode 100644
index 000000000..8a6fa25bf
--- /dev/null
+++ b/orthanc/orthanc-anon/docs/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/orthanc/orthanc-anon/docs' Directory Contents
+
+### Subdirectories
+
+[assets](./assets/README.md)
+
+### Files
+
+DicomServiceViaAAD.md
+
diff --git a/orthanc/orthanc-anon/docs/assets/README.md b/orthanc/orthanc-anon/docs/assets/README.md
new file mode 100644
index 000000000..484b4f3e3
--- /dev/null
+++ b/orthanc/orthanc-anon/docs/assets/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/orthanc/orthanc-anon/docs/assets' Directory Contents
+
+### Files
+
+DicomServiceAuthority.png
+
diff --git a/orthanc/orthanc-anon/plugin/README.md b/orthanc/orthanc-anon/plugin/README.md
new file mode 100644
index 000000000..6f5c0eba0
--- /dev/null
+++ b/orthanc/orthanc-anon/plugin/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/orthanc/orthanc-anon/plugin' Directory Contents
+
+### Files
+
+download_dicom_spec.py
+
+pixl.py
+
diff --git a/orthanc/orthanc-raw/README.md b/orthanc/orthanc-raw/README.md
index eec29a5a0..2e695cc3a 100644
--- a/orthanc/orthanc-raw/README.md
+++ b/orthanc/orthanc-raw/README.md
@@ -110,3 +110,16 @@ team.
## References
- [Cheat sheet of the REST API](https://book.orthanc-server.com/users/rest-cheatsheet.html)
+
+## 'PIXL/orthanc/orthanc-raw' Directory Contents
+
+### Subdirectories
+
+[config](./config/README.md)
+
+[plugin](./plugin/README.md)
+
+### Files
+
+README.md
+
diff --git a/orthanc/orthanc-raw/config/README.md b/orthanc/orthanc-raw/config/README.md
new file mode 100644
index 000000000..6d345e63e
--- /dev/null
+++ b/orthanc/orthanc-raw/config/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/orthanc/orthanc-raw/config' Directory Contents
+
+### Files
+
+dicom.json
+
+orthanc.json
+
+postgres.json
+
diff --git a/orthanc/orthanc-raw/plugin/README.md b/orthanc/orthanc-raw/plugin/README.md
new file mode 100644
index 000000000..bfebf0781
--- /dev/null
+++ b/orthanc/orthanc-raw/plugin/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/orthanc/orthanc-raw/plugin' Directory Contents
+
+### Files
+
+pixl.py
+
diff --git a/pixl_core/README.md b/pixl_core/README.md
index 8116ba49e..5b9f784fb 100644
--- a/pixl_core/README.md
+++ b/pixl_core/README.md
@@ -234,3 +234,18 @@ Note, it can take several minutes for the server to start up.
Once the server has started, you can log in by visiting `http://localhost:8080` with the username and password set
in the `XNAT_USER_NAME` and `XNAT_PASSWORD` environment variables.
+
+## 'PIXL/pixl_core' Directory Contents
+
+### Subdirectories
+
+[src](./src/README.md)
+
+[tests](./tests/README.md)
+
+### Files
+
+pyproject.toml
+
+README.md
+
diff --git a/pixl_core/src/README.md b/pixl_core/src/README.md
new file mode 100644
index 000000000..56763ccf2
--- /dev/null
+++ b/pixl_core/src/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pixl_core/src' Directory Contents
+
+### Subdirectories
+
+[core](./core/README.md)
+
diff --git a/pixl_core/src/core/README.md b/pixl_core/src/core/README.md
new file mode 100644
index 000000000..c450b32c7
--- /dev/null
+++ b/pixl_core/src/core/README.md
@@ -0,0 +1,26 @@
+## 'PIXL/pixl_core/src/core' Directory Contents
+
+### Subdirectories
+
+[db](./db/README.md)
+
+[patient_queue](./patient_queue/README.md)
+
+[project_config](./project_config/README.md)
+
+[rest_api](./rest_api/README.md)
+
+[token_buffer](./token_buffer/README.md)
+
+[uploader](./uploader/README.md)
+
+### Files
+
+dicom_tags.py
+
+exceptions.py
+
+exports.py
+
+__init__.py
+
diff --git a/pixl_core/src/core/db/README.md b/pixl_core/src/core/db/README.md
new file mode 100644
index 000000000..2b3e187dd
--- /dev/null
+++ b/pixl_core/src/core/db/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/pixl_core/src/core/db' Directory Contents
+
+### Files
+
+models.py
+
+queries.py
+
+__init__.py
+
diff --git a/pixl_core/src/core/patient_queue/README.md b/pixl_core/src/core/patient_queue/README.md
new file mode 100644
index 000000000..f53cead1f
--- /dev/null
+++ b/pixl_core/src/core/patient_queue/README.md
@@ -0,0 +1,14 @@
+## 'PIXL/pixl_core/src/core/patient_queue' Directory Contents
+
+### Files
+
+message.py
+
+producer.py
+
+subscriber.py
+
+_base.py
+
+__init__.py
+
diff --git a/pixl_core/src/core/project_config/README.md b/pixl_core/src/core/project_config/README.md
new file mode 100644
index 000000000..4a8232810
--- /dev/null
+++ b/pixl_core/src/core/project_config/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/pixl_core/src/core/project_config' Directory Contents
+
+### Files
+
+pixl_config_model.py
+
+secrets.py
+
+tag_operations.py
+
+__init__.py
+
diff --git a/pixl_core/src/core/rest_api/README.md b/pixl_core/src/core/rest_api/README.md
new file mode 100644
index 000000000..2d481757b
--- /dev/null
+++ b/pixl_core/src/core/rest_api/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/pixl_core/src/core/rest_api' Directory Contents
+
+### Files
+
+router.py
+
+__init__.py
+
diff --git a/pixl_core/src/core/token_buffer/README.md b/pixl_core/src/core/token_buffer/README.md
new file mode 100644
index 000000000..d25fd7b64
--- /dev/null
+++ b/pixl_core/src/core/token_buffer/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/pixl_core/src/core/token_buffer' Directory Contents
+
+### Files
+
+models.py
+
+tokens.py
+
+__init__.py
+
diff --git a/pixl_core/src/core/uploader/README.md b/pixl_core/src/core/uploader/README.md
new file mode 100644
index 000000000..1a0e6a444
--- /dev/null
+++ b/pixl_core/src/core/uploader/README.md
@@ -0,0 +1,16 @@
+## 'PIXL/pixl_core/src/core/uploader' Directory Contents
+
+### Files
+
+base.py
+
+_dicomweb.py
+
+_ftps.py
+
+_orthanc.py
+
+_xnat.py
+
+__init__.py
+
diff --git a/pixl_core/tests/README.md b/pixl_core/tests/README.md
new file mode 100644
index 000000000..621d1b3c7
--- /dev/null
+++ b/pixl_core/tests/README.md
@@ -0,0 +1,22 @@
+## 'PIXL/pixl_core/tests' Directory Contents
+
+### Subdirectories
+
+[data](./data/README.md)
+
+[patient_queue](./patient_queue/README.md)
+
+[project_config](./project_config/README.md)
+
+[token_buffer](./token_buffer/README.md)
+
+[uploader](./uploader/README.md)
+
+### Files
+
+conftest.py
+
+docker-compose.yml
+
+test_exports.py
+
diff --git a/pixl_core/tests/data/README.md b/pixl_core/tests/data/README.md
new file mode 100644
index 000000000..065c917e7
--- /dev/null
+++ b/pixl_core/tests/data/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/pixl_core/tests/data' Directory Contents
+
+### Files
+
+dicom_series.zip
+
+public.zip
+
+xnat_project.xml
+
diff --git a/pixl_core/tests/patient_queue/README.md b/pixl_core/tests/patient_queue/README.md
new file mode 100644
index 000000000..895a4d9fc
--- /dev/null
+++ b/pixl_core/tests/patient_queue/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/pixl_core/tests/patient_queue' Directory Contents
+
+### Files
+
+test_message.py
+
+test_producer.py
+
+test_subscriber.py
+
diff --git a/pixl_core/tests/project_config/README.md b/pixl_core/tests/project_config/README.md
new file mode 100644
index 000000000..eb889f4e8
--- /dev/null
+++ b/pixl_core/tests/project_config/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/pixl_core/tests/project_config' Directory Contents
+
+### Files
+
+test_project_config.py
+
+test_secrets.py
+
diff --git a/pixl_core/tests/token_buffer/README.md b/pixl_core/tests/token_buffer/README.md
new file mode 100644
index 000000000..259ef6888
--- /dev/null
+++ b/pixl_core/tests/token_buffer/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pixl_core/tests/token_buffer' Directory Contents
+
+### Files
+
+test_tokens.py
+
diff --git a/pixl_core/tests/uploader/README.md b/pixl_core/tests/uploader/README.md
new file mode 100644
index 000000000..e960568d5
--- /dev/null
+++ b/pixl_core/tests/uploader/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/pixl_core/tests/uploader' Directory Contents
+
+### Files
+
+test_base.py
+
+test_dicomweb.py
+
+test_ftps.py
+
+test_xnat.py
+
diff --git a/pixl_dcmd/README.md b/pixl_dcmd/README.md
index 2c8b57682..d1710c24b 100644
--- a/pixl_dcmd/README.md
+++ b/pixl_dcmd/README.md
@@ -62,3 +62,18 @@ and optionally a `manufacturer_overrides`.
If a `manufacturer_overrides` is defined, it will be used to override the `base` tags, if the
manufacturer of the DICOM file matches the manufacturer in the `manufacturer_overrides`. Any tags
in the `manufacturer_overrides` that are not in the `base` will be added to the scheme as well.
+
+## 'PIXL/pixl_dcmd' Directory Contents
+
+### Subdirectories
+
+[src](./src/README.md)
+
+[tests](./tests/README.md)
+
+### Files
+
+pyproject.toml
+
+README.md
+
diff --git a/pixl_dcmd/src/README.md b/pixl_dcmd/src/README.md
new file mode 100644
index 000000000..2ba0cd0e1
--- /dev/null
+++ b/pixl_dcmd/src/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pixl_dcmd/src' Directory Contents
+
+### Subdirectories
+
+[pixl_dcmd](./pixl_dcmd/README.md)
+
diff --git a/pixl_dcmd/src/pixl_dcmd/README.md b/pixl_dcmd/src/pixl_dcmd/README.md
new file mode 100644
index 000000000..e94fbfd07
--- /dev/null
+++ b/pixl_dcmd/src/pixl_dcmd/README.md
@@ -0,0 +1,22 @@
+## 'PIXL/pixl_dcmd/src/pixl_dcmd' Directory Contents
+
+### Subdirectories
+
+[resources](./resources/README.md)
+
+### Files
+
+main.py
+
+tagrecording.py
+
+_database.py
+
+_dicom_helpers.py
+
+_tag_schemes.py
+
+_version.py
+
+__init__.py
+
diff --git a/pixl_dcmd/src/pixl_dcmd/resources/README.md b/pixl_dcmd/src/pixl_dcmd/resources/README.md
new file mode 100644
index 000000000..b6d19ecc6
--- /dev/null
+++ b/pixl_dcmd/src/pixl_dcmd/resources/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pixl_dcmd/src/pixl_dcmd/resources' Directory Contents
+
+### Files
+
+recorded-headers.yml
+
diff --git a/pixl_dcmd/tests/README.md b/pixl_dcmd/tests/README.md
new file mode 100644
index 000000000..9f05da066
--- /dev/null
+++ b/pixl_dcmd/tests/README.md
@@ -0,0 +1,16 @@
+## 'PIXL/pixl_dcmd/tests' Directory Contents
+
+### Files
+
+conftest.py
+
+test_database.py
+
+test_dicom_validator.py
+
+test_main.py
+
+test_tagrecording.py
+
+test_tag_schemes.py
+
diff --git a/pixl_export/README.md b/pixl_export/README.md
index 9e34f283e..89481df38 100644
--- a/pixl_export/README.md
+++ b/pixl_export/README.md
@@ -43,3 +43,18 @@ Usage should be from the CLI driver, which calls the HTTP endpoints.
## Notes
- The height/weight/GCS value is extracted only within a 24 h time window
+
+## 'PIXL/pixl_export' Directory Contents
+
+### Subdirectories
+
+[src](./src/README.md)
+
+[tests](./tests/README.md)
+
+### Files
+
+pyproject.toml
+
+README.md
+
diff --git a/pixl_export/src/README.md b/pixl_export/src/README.md
new file mode 100644
index 000000000..06ab4efea
--- /dev/null
+++ b/pixl_export/src/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pixl_export/src' Directory Contents
+
+### Subdirectories
+
+[pixl_export](./pixl_export/README.md)
+
diff --git a/pixl_export/src/pixl_export/README.md b/pixl_export/src/pixl_export/README.md
new file mode 100644
index 000000000..c21da40db
--- /dev/null
+++ b/pixl_export/src/pixl_export/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/pixl_export/src/pixl_export' Directory Contents
+
+### Files
+
+main.py
+
+_databases.py
+
+_queries.py
+
+__init__.py
+
diff --git a/pixl_export/tests/README.md b/pixl_export/tests/README.md
new file mode 100644
index 000000000..607a81078
--- /dev/null
+++ b/pixl_export/tests/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/pixl_export/tests' Directory Contents
+
+### Files
+
+conftest.py
+
+docker-compose.yml
+
+test_app.py
+
diff --git a/pixl_imaging/README.md b/pixl_imaging/README.md
index 9f3419db8..26463b37c 100644
--- a/pixl_imaging/README.md
+++ b/pixl_imaging/README.md
@@ -60,3 +60,22 @@ The `SKIP_ALEMBIC` environmental variable is used to control whether migrations
- `SKIP_ALEMBIC` is set to true for tests that do not use the database (e.g. `SKIP_ALEMBIC=true`). Otherwise you probably want to run this.
- If you wanted to test out new migrations from a test/dev deployment on the GAE with data in,
then you can redeploy just the `imaging-api` container while keeping the `postgres` container up.
+
+## 'PIXL/pixl_imaging' Directory Contents
+
+### Subdirectories
+
+[alembic](./alembic/README.md)
+
+[scripts](./scripts/README.md)
+
+[src](./src/README.md)
+
+[tests](./tests/README.md)
+
+### Files
+
+pyproject.toml
+
+README.md
+
diff --git a/pixl_imaging/alembic/README.md b/pixl_imaging/alembic/README.md
index fa1a34d83..d7054661f 100644
--- a/pixl_imaging/alembic/README.md
+++ b/pixl_imaging/alembic/README.md
@@ -29,3 +29,24 @@ There's a couple of manual steps:
- Check the changes autogenerated and update to match your intention
- Commit the changes and review in a pull request as normal
+
+## 'PIXL/pixl_imaging/alembic' Directory Contents
+
+### Subdirectories
+
+[versions](./versions/README.md)
+
+### Files
+
+alembic.ini
+
+autogenerate-migration.sh
+
+env.py
+
+migrations.env
+
+README.md
+
+script.py.mako
+
diff --git a/pixl_imaging/alembic/versions/README.md b/pixl_imaging/alembic/versions/README.md
new file mode 100644
index 000000000..ea043622a
--- /dev/null
+++ b/pixl_imaging/alembic/versions/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/pixl_imaging/alembic/versions' Directory Contents
+
+### Files
+
+83dcb3812628_add_study_uid_column_to_image_table.py
+
+bcaef54e2bfe_create_extract_and_image_tables.py
+
+cb5ee12a6e20_replace_hashed_id_with_pseudo_study_uid.py
+
+d947cc715eb1_add_pseudo_patient_id_column_to_image_table.py
+
diff --git a/pixl_imaging/scripts/README.md b/pixl_imaging/scripts/README.md
new file mode 100644
index 000000000..afd8a5659
--- /dev/null
+++ b/pixl_imaging/scripts/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pixl_imaging/scripts' Directory Contents
+
+### Files
+
+migrate_and_run.sh
+
diff --git a/pixl_imaging/src/README.md b/pixl_imaging/src/README.md
new file mode 100644
index 000000000..a8f1b4ac5
--- /dev/null
+++ b/pixl_imaging/src/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pixl_imaging/src' Directory Contents
+
+### Subdirectories
+
+[pixl_imaging](./pixl_imaging/README.md)
+
diff --git a/pixl_imaging/src/pixl_imaging/README.md b/pixl_imaging/src/pixl_imaging/README.md
new file mode 100644
index 000000000..8250982db
--- /dev/null
+++ b/pixl_imaging/src/pixl_imaging/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/pixl_imaging/src/pixl_imaging' Directory Contents
+
+### Files
+
+main.py
+
+_orthanc.py
+
+_processing.py
+
+__init__.py
+
diff --git a/pixl_imaging/tests/README.md b/pixl_imaging/tests/README.md
new file mode 100644
index 000000000..8903dd81c
--- /dev/null
+++ b/pixl_imaging/tests/README.md
@@ -0,0 +1,14 @@
+## 'PIXL/pixl_imaging/tests' Directory Contents
+
+### Subdirectories
+
+[orthanc_raw_config](./orthanc_raw_config/README.md)
+
+### Files
+
+conftest.py
+
+docker-compose.yml
+
+test_imaging_processing.py
+
diff --git a/pixl_imaging/tests/orthanc_raw_config/README.md b/pixl_imaging/tests/orthanc_raw_config/README.md
new file mode 100644
index 000000000..3b95d29ca
--- /dev/null
+++ b/pixl_imaging/tests/orthanc_raw_config/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/pixl_imaging/tests/orthanc_raw_config' Directory Contents
+
+### Files
+
+dicom.json
+
+orthanc.json
+
diff --git a/postgres/README.md b/postgres/README.md
index b161ebf78..e532b9469 100644
--- a/postgres/README.md
+++ b/postgres/README.md
@@ -5,3 +5,14 @@ container and the pixl_imaging api uses [alembic](https://alembic.sqlalchemy.org
This allows a reproducible way to update (or rollback) alterations to the PIXL pipeline's database schema.
See [/pixl_imaging/alembic](../pixl_imaging/alembic) for how these are defined and how to create new migrations.
+
+## 'PIXL/postgres' Directory Contents
+
+### Files
+
+pixl-db_init.sh
+
+postgres.conf
+
+README.md
+
diff --git a/projects/README.md b/projects/README.md
new file mode 100644
index 000000000..dcfdcd654
--- /dev/null
+++ b/projects/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/projects' Directory Contents
+
+### Subdirectories
+
+[configs](./configs/README.md)
+
+[exports](./exports/README.md)
+
diff --git a/projects/configs/README.md b/projects/configs/README.md
new file mode 100644
index 000000000..351680b9b
--- /dev/null
+++ b/projects/configs/README.md
@@ -0,0 +1,22 @@
+## 'PIXL/projects/configs' Directory Contents
+
+### Subdirectories
+
+[tag-operations](./tag-operations/README.md)
+
+### Files
+
+ms-pinpoint.yaml
+
+test-external-user.yaml
+
+test-extract-uclh-omop-cdm-dicomweb.yaml
+
+test-extract-uclh-omop-cdm-xnat.yaml
+
+test-extract-uclh-omop-cdm.yaml
+
+uclh-nasogastric-tube-project-ngt-only-full-dataset.yaml
+
+uclh-prostate-mri-external-dataset.yaml
+
diff --git a/projects/configs/tag-operations/README.md b/projects/configs/tag-operations/README.md
new file mode 100644
index 000000000..83c53c681
--- /dev/null
+++ b/projects/configs/tag-operations/README.md
@@ -0,0 +1,24 @@
+## 'PIXL/projects/configs/tag-operations' Directory Contents
+
+### Subdirectories
+
+[manufacturer-overrides](./manufacturer-overrides/README.md)
+
+### Files
+
+base.yaml
+
+diffusion-weighted-mri.yaml
+
+mri.yaml
+
+ms-pinpoint.yaml
+
+test-external-user.yaml
+
+test-extract-uclh-omop-cdm.yaml
+
+uclh-nasogastric-tube-project-ngt-only-full-dataset.yaml
+
+xray.yaml
+
diff --git a/projects/configs/tag-operations/manufacturer-overrides/README.md b/projects/configs/tag-operations/manufacturer-overrides/README.md
new file mode 100644
index 000000000..b77c531e3
--- /dev/null
+++ b/projects/configs/tag-operations/manufacturer-overrides/README.md
@@ -0,0 +1,8 @@
+## 'manufacturer-overrides' Directory Contents
+
+### Files
+
+mri-diffusion.yaml
+
+mri.yaml
+
diff --git a/pytest-pixl/README.md b/pytest-pixl/README.md
index 4c4e9666e..30c8c4c21 100644
--- a/pytest-pixl/README.md
+++ b/pytest-pixl/README.md
@@ -102,3 +102,19 @@ default DICOM tag values used to generate fake DICOM data in `generate_dicom_dat
The JSON file was created by running [`scripts/create_default_dicom_tags_json.py`](./scripts/create_default_dicom_tags_json.py),
with the details implemented in [`pytest_pixl.dicom._create_default_json`](./src/pytest_pixl/dicom.py).
+## 'PIXL/pytest-pixl' Directory Contents
+
+### Subdirectories
+
+[scripts](./scripts/README.md)
+
+[src](./src/README.md)
+
+[tests](./tests/README.md)
+
+### Files
+
+pyproject.toml
+
+README.md
+
diff --git a/pytest-pixl/scripts/README.md b/pytest-pixl/scripts/README.md
new file mode 100644
index 000000000..65085443d
--- /dev/null
+++ b/pytest-pixl/scripts/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pytest-pixl/scripts' Directory Contents
+
+### Files
+
+create_default_dicom_tags_json.py
+
diff --git a/pytest-pixl/src/README.md b/pytest-pixl/src/README.md
new file mode 100644
index 000000000..138dffa26
--- /dev/null
+++ b/pytest-pixl/src/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/pytest-pixl/src' Directory Contents
+
+### Subdirectories
+
+[pytest_pixl](./pytest_pixl/README.md)
+
+[resources](./resources/README.md)
+
diff --git a/pytest-pixl/src/pytest_pixl/README.md b/pytest-pixl/src/pytest_pixl/README.md
new file mode 100644
index 000000000..98744d18c
--- /dev/null
+++ b/pytest-pixl/src/pytest_pixl/README.md
@@ -0,0 +1,18 @@
+## 'PIXL/pytest-pixl/src/pytest_pixl' Directory Contents
+
+### Subdirectories
+
+[data](./data/README.md)
+
+### Files
+
+dicom.py
+
+ftpserver.py
+
+helpers.py
+
+plugin.py
+
+__init__.py
+
diff --git a/pytest-pixl/src/pytest_pixl/data/README.md b/pytest-pixl/src/pytest_pixl/data/README.md
new file mode 100644
index 000000000..cfa58b0bb
--- /dev/null
+++ b/pytest-pixl/src/pytest_pixl/data/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/pytest-pixl/src/pytest_pixl/data' Directory Contents
+
+### Subdirectories
+
+[omop-resources](./omop-resources/README.md)
+
+### Files
+
+default_dicom_tags.json
+
+volume_dicom_variables.json
+
diff --git a/pytest-pixl/src/pytest_pixl/data/omop-resources/README.md b/pytest-pixl/src/pytest_pixl/data/omop-resources/README.md
new file mode 100644
index 000000000..7a457c566
--- /dev/null
+++ b/pytest-pixl/src/pytest_pixl/data/omop-resources/README.md
@@ -0,0 +1,18 @@
+## 'omop-resources' Directory Contents
+
+### Subdirectories
+
+[omop](./omop/README.md)
+
+### Files
+
+batch_input.csv
+
+duplicate_input.csv
+
+multiple_projects.csv
+
+participant_id.csv
+
+test.csv
+
diff --git a/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/README.md b/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/README.md
new file mode 100644
index 000000000..e5d45c492
--- /dev/null
+++ b/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/README.md
@@ -0,0 +1,12 @@
+## 'omop' Directory Contents
+
+### Subdirectories
+
+[private](./private/README.md)
+
+[public](./public/README.md)
+
+### Files
+
+extract_summary.json
+
diff --git a/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/private/README.md b/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/private/README.md
new file mode 100644
index 000000000..2e47873ed
--- /dev/null
+++ b/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/private/README.md
@@ -0,0 +1,8 @@
+## 'private' Directory Contents
+
+### Files
+
+PERSON_LINKS.parquet
+
+PROCEDURE_OCCURRENCE_LINKS.parquet
+
diff --git a/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/public/README.md b/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/public/README.md
new file mode 100644
index 000000000..d35e10141
--- /dev/null
+++ b/pytest-pixl/src/pytest_pixl/data/omop-resources/omop/public/README.md
@@ -0,0 +1,6 @@
+## 'public' Directory Contents
+
+### Files
+
+PROCEDURE_OCCURRENCE.parquet
+
diff --git a/pytest-pixl/src/resources/README.md b/pytest-pixl/src/resources/README.md
new file mode 100644
index 000000000..8c118dc40
--- /dev/null
+++ b/pytest-pixl/src/resources/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pytest-pixl/src/resources' Directory Contents
+
+### Subdirectories
+
+[ssl](./ssl/README.md)
+
diff --git a/pytest-pixl/src/resources/ssl/README.md b/pytest-pixl/src/resources/ssl/README.md
new file mode 100644
index 000000000..20c619682
--- /dev/null
+++ b/pytest-pixl/src/resources/ssl/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/pytest-pixl/src/resources/ssl' Directory Contents
+
+### Files
+
+localhost.crt
+
+localhost.key
+
diff --git a/pytest-pixl/tests/README.md b/pytest-pixl/tests/README.md
new file mode 100644
index 000000000..d7c2900b2
--- /dev/null
+++ b/pytest-pixl/tests/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/pytest-pixl/tests' Directory Contents
+
+### Subdirectories
+
+[samples_for_fixture_tests](./samples_for_fixture_tests/README.md)
+
+### Files
+
+conftest.py
+
+test_ftpserver_fixture.py
+
diff --git a/pytest-pixl/tests/samples_for_fixture_tests/README.md b/pytest-pixl/tests/samples_for_fixture_tests/README.md
new file mode 100644
index 000000000..ee9d21902
--- /dev/null
+++ b/pytest-pixl/tests/samples_for_fixture_tests/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pytest-pixl/tests/samples_for_fixture_tests' Directory Contents
+
+### Subdirectories
+
+[test_ftpserver_fixture](./test_ftpserver_fixture/README.md)
+
diff --git a/pytest-pixl/tests/samples_for_fixture_tests/test_ftpserver_fixture/README.md b/pytest-pixl/tests/samples_for_fixture_tests/test_ftpserver_fixture/README.md
new file mode 100644
index 000000000..06effc923
--- /dev/null
+++ b/pytest-pixl/tests/samples_for_fixture_tests/test_ftpserver_fixture/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/pytest-pixl/tests/samples_for_fixture_tests/test_ftpserver_fixture' Directory Contents
+
+### Files
+
+test_ftpserver_login.py
+
diff --git a/schemas/README.md b/schemas/README.md
new file mode 100644
index 000000000..432a9cc7b
--- /dev/null
+++ b/schemas/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/schemas' Directory Contents
+
+### Files
+
+github-issue-forms.json
+
diff --git a/scripts/README.md b/scripts/README.md
new file mode 100644
index 000000000..26ff995a3
--- /dev/null
+++ b/scripts/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/scripts' Directory Contents
+
+### Files
+
+cmove_all_studies.py
+
+delete_oldest_n_studies.py
+
+filter_cohort_for_those_present_in_raw.py
+
+list_newest_n_studies.py
+
diff --git a/test/README.md b/test/README.md
index 2a3723cca..b1c25278f 100644
--- a/test/README.md
+++ b/test/README.md
@@ -10,7 +10,7 @@ consumers started.
**Then** the DICOM study exists in the "anon" PIXL Orthanc instance.
-After setting up your [.secrets.env](../README.md#project-secrets)), you can run the system test with:
+After setting up your [.secrets.env](../README.md#project-secrets), you can run the system test with:
```bash
./run-system-test.sh
@@ -69,3 +69,34 @@ but configured to upload to a [DICOMweb server](#dicomweb-config)
### DICOMWeb config
`./dicomweb_config/` contains the Orthanc configuration files for the mock [DICOMweb server](../docs/services/dicomweb-server.md).
+
+## 'PIXL/test' Directory Contents
+
+### Subdirectories
+
+[dicomweb_config](./dicomweb_config/README.md)
+
+[resources](./resources/README.md)
+
+[vna_config](./vna_config/README.md)
+
+### Files
+
+.env
+
+.secrets.env.sample
+
+conftest.py
+
+docker-compose.yml
+
+README.md
+
+run-system-test.sh
+
+system_test.py
+
+test_parquet_exports.py
+
+utils.py
+
diff --git a/test/dicomweb_config/README.md b/test/dicomweb_config/README.md
new file mode 100644
index 000000000..41729879a
--- /dev/null
+++ b/test/dicomweb_config/README.md
@@ -0,0 +1,10 @@
+## 'PIXL/test/dicomweb_config' Directory Contents
+
+### Files
+
+.env
+
+dicom.json
+
+orthanc.json
+
diff --git a/test/resources/README.md b/test/resources/README.md
new file mode 100644
index 000000000..132dcb141
--- /dev/null
+++ b/test/resources/README.md
@@ -0,0 +1,14 @@
+## 'PIXL/test/resources' Directory Contents
+
+### Subdirectories
+
+[omop](./omop/README.md)
+
+[omop-dicomweb](./omop-dicomweb/README.md)
+
+### Files
+
+Dicom1.dcm
+
+Dicom2.dcm
+
diff --git a/test/resources/omop-dicomweb/README.md b/test/resources/omop-dicomweb/README.md
new file mode 100644
index 000000000..0847fb646
--- /dev/null
+++ b/test/resources/omop-dicomweb/README.md
@@ -0,0 +1,12 @@
+## 'omop-dicomweb' Directory Contents
+
+### Subdirectories
+
+[private](./private/README.md)
+
+[public](./public/README.md)
+
+### Files
+
+extract_summary.json
+
diff --git a/test/resources/omop-dicomweb/private/README.md b/test/resources/omop-dicomweb/private/README.md
new file mode 100644
index 000000000..2e47873ed
--- /dev/null
+++ b/test/resources/omop-dicomweb/private/README.md
@@ -0,0 +1,8 @@
+## 'private' Directory Contents
+
+### Files
+
+PERSON_LINKS.parquet
+
+PROCEDURE_OCCURRENCE_LINKS.parquet
+
diff --git a/test/resources/omop-dicomweb/public/README.md b/test/resources/omop-dicomweb/public/README.md
new file mode 100644
index 000000000..d35e10141
--- /dev/null
+++ b/test/resources/omop-dicomweb/public/README.md
@@ -0,0 +1,6 @@
+## 'public' Directory Contents
+
+### Files
+
+PROCEDURE_OCCURRENCE.parquet
+
diff --git a/test/resources/omop/README.md b/test/resources/omop/README.md
new file mode 100644
index 000000000..f8f0010b4
--- /dev/null
+++ b/test/resources/omop/README.md
@@ -0,0 +1,12 @@
+## 'PIXL/test/resources/omop' Directory Contents
+
+### Subdirectories
+
+[private](./private/README.md)
+
+[public](./public/README.md)
+
+### Files
+
+extract_summary.json
+
diff --git a/test/resources/omop/private/README.md b/test/resources/omop/private/README.md
new file mode 100644
index 000000000..d0082ec64
--- /dev/null
+++ b/test/resources/omop/private/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/test/resources/omop/private' Directory Contents
+
+### Files
+
+PERSON_LINKS.parquet
+
+PROCEDURE_OCCURRENCE_LINKS.parquet
+
diff --git a/test/resources/omop/public/README.md b/test/resources/omop/public/README.md
new file mode 100644
index 000000000..be9075cd4
--- /dev/null
+++ b/test/resources/omop/public/README.md
@@ -0,0 +1,6 @@
+## 'PIXL/test/resources/omop/public' Directory Contents
+
+### Files
+
+PROCEDURE_OCCURRENCE.parquet
+
diff --git a/test/vna_config/README.md b/test/vna_config/README.md
new file mode 100644
index 000000000..ee4cd9d44
--- /dev/null
+++ b/test/vna_config/README.md
@@ -0,0 +1,8 @@
+## 'PIXL/test/vna_config' Directory Contents
+
+### Files
+
+dicom.json
+
+orthanc.json
+