
Initial Release
OncoRAG extracts structured clinical features from oncology notes using local
language models and patient-specific knowledge graphs.
Define your variables and provide dated notes to build a graph per patient and
extract features. Notes stay local with the supplied settings.
OncoRAG workflow and the paper’s downstream progression-free-survival analysis.
Requires Python 3.10 or newer and a local Ollama server.
To install and run OncoRAG:
git clone --branch main --single-branch https://github.com/pgsalome/oncorag.git cd oncorag python -m venv .venv source .venv/bin/activate pip install -e . pip install https://s3-us-west-2.amazonaws.com/ai2-s2-scispacy/releases/v0.5.4/en_ner_bc5cdr_md-0.5.4.tar.gz ollama pull phi3:mini
oncorag --config configs/oncorag_synthetic_english.json --stage validate oncorag --config configs/oncorag_synthetic_english.json
Check spaCy model compatibility with python -m spacy validate. The default NER
and embedding models are English-oriented.
To run the English or German examples with Python:
# English python scripts/run_oncorag.py --config configs/oncorag_synthetic_english.jsonGerman
python scripts/run_oncorag.py --config configs/oncorag_synthetic_german.json
The repository includes two synthetic cohorts:
| Dataset | Patients | Notes |
|---|---|---|
| oncorag-e (English) | 489 | 2,930 |
| oncorag-d (German) | 489 | 2,930 |
To run a full cohort:
python scripts/run_oncorag.py --config configs/oncorag-e.json
python scripts/run_oncorag.py --config configs/oncorag-d.json
Each cohort includes a feature list. Quick Start uses the small test datasets in
examples/datasets/demo/english and examples/datasets/demo/german.
The paper’s clinical cohorts are separate. See dataset formats
and sources and annotations.
To run the tests:
pip install -e '.[dev,chat]'
python -m pytest tests -q
python scripts/run_synthetic_smoke.py --ollama-host http://127.0.0.1:11434
python scripts/run_chat_smoke.py --ollama-host http://127.0.0.1:11434
To evaluate the English test results:
python scripts/evaluate_synthetic.py \
--config configs/oncorag_synthetic_english.json \
--results outputs/synthetic_smoke/english/structured_features.json \
--output outputs/synthetic_smoke/english/evaluation.json
The extraction and chat smoke tests require Ollama. For the IRIS integration test,
set ONCORAG_TEST_IRIS=1 and provide database credentials.
Define variables in YAML or JSON:
features:
- name: latest_hemoglobin
type: numeric
expected_range: [0, 30]
unit: g/dL
description: Hemoglobin in g/dL from the most recent dated report.
- name: treatment
type: categorical
expected_range: [chemotherapy, radiotherapy]
description: Cancer treatment documented as started.
Supported types: integer, numeric, boolean, date, categorical, ordinal
and string. Numeric bounds are inclusive; categorical values must match an
allowed label. Dates use YYYY-MM-DD, and missing values use JSON null.
Include units and which report date to use in the description.
Set features.specifications to your variable file and choose
features.configuration_mode:
automatic: generates synonyms and ontology mappings with create_config.py.manual: uses your definitions and optional synonyms (used by the examples).Automatic mode requires internet access, UMLS_API_KEY and WordNet
(python -m nltk.downloader wordnet omw-1.4). BIOPORTAL_API_KEY is optional.
Keep patient information out of feature definitions sent to ontology services.
To generate feature configurations:
oncorag --config configs/oncorag_synthetic_english.json --stage config
To configure a variable file directly:
python oncorag/create_config.py --mode manual \
--features-file examples/features.synthetic.yaml \
--output-dir generated/custom --language english
The pipeline writes to features.generated_config_dir; create_config.py uses
--output-dir. Review the configurations before extraction.
Use a folder or a registry. For folders, set inputs.notes_root and arrange notes as:
notes/
patient-001/
oncology/2024-01-12.txt
radiology/2024-02-03__report-02.txt
For multiple reports of the same type and date, use YYYY-MM-DD__unique-note-id.txt.
For a registry, set inputs.registry_path to a CSV, JSONL or JSON file:
[
{"patient_id":"patient-001","note_id":"report-02","report_type":"radiology","date":"2024-02-03","language":"de","path":"notes/report-02.txt"}
]
Set either inputs.notes_root or inputs.registry_path. Dates and report types come
from folder names or registry fields. Note paths are relative to the registry;
configuration paths are relative to the JSON configuration file.
To select patients, set inputs.patient_ids_file to a file with one ID per line.
Preserve leading zeros.
Copy the configuration example and
set your input, feature and output paths.
To choose an Ollama host and model for one run:
python scripts/run_oncorag.py --config configs/oncorag_synthetic_english.json \
--ollama-host http://127.0.0.1:11435 --ollama-model phi3:mini
Host and model settings use this priority: command-line arguments, OLLAMA_HOST /
OLLAMA_MODEL, then JSON configuration.
| Setting | Controls |
|---|---|
runtime.ollama |
Model, temperature, context window, timeout, output limit and validation retries |
runtime.random_seed |
Generation seed |
retrieval |
Top-k, scoring weights, graph depth and graph-diffusion reranking |
graph |
NER models, context filters, deduplication and sentence nodes |
temporal_anchoring |
Temporal instructions for extraction |
Keep runtime.workers at 1. Set graph.include_report_sentences: false for
entity-only graphs.
Use --stage validate to check inputs, --stage config to generate configurations,
or --stage graph to build patient graphs. The default runs through extraction.
Use --force-rebuild to rebuild cached graphs.
Results are saved under outputs.root: structured_features.json, patient graphs,
per-patient results, parameters, prompts and source evidence. Keep outputs
containing patient information private.
ChromaDB is the default vector store. To use InterSystems IRIS:
pip install -e '.[iris]'
export IRIS_USERNAME=your_database_user
export IRIS_PASSWORD=your_database_password
Copy vector_store from the IRIS example
into your configuration. Set backend: iris and your server details.
The default SapBERT embeddings have 768 dimensions. Keep credentials in environment
variables. Use --vector-backend iris to select IRIS for one run.
runtime.local_processing_only: true requires localhost or loopback IP addresses
for Ollama and IRIS. A remote server requires setting it to false.
To use the chatbot in a terminal:
oncorag-chat --config configs/oncorag_synthetic_english.json --list-patients
oncorag-chat --config configs/oncorag_synthetic_english.json \
--patient-id SYN-DEMO-001 --loop
oncorag-chat --config configs/oncorag_synthetic_english.json \
--patient-id SYN-DEMO-001 --question "What treatment actually started?" --json
Use /clear to clear the conversation and /quit to exit.
python run_chatbot.py accepts the same arguments.
To use the chatbot in a browser:
pip install -e '.[chat]'
python -m streamlit run streamlit_app.py --server.address 127.0.0.1 -- \
--config configs/oncorag_synthetic_english.json
Open http://127.0.0.1:8501 and select a patient. Review answers against the cited
notes. Keep the app on localhost; network deployment needs separate authentication.
To cite OncoRAG:
@article{salome2026oncorag,
title = {{OncoRAG}: graph-based retrieval enabling clinical phenotyping from oncology notes using local mid-size language models},
author = {Salome, Patrick and Knoll, Maximilian and Walz, David and
Cogno, Nicol{\`o} and Dedeoglu, Aylin S. and Qi, Aimee Letong and
Isakoff, Steven J. and Abdollahi, Amir and Jimenez, Rachel B. and
Bitterman, Danielle S. and Paganetti, Harald and Chamseddine, Ibrahim},
journal = {npj Digital Medicine},
year = {2026},
doi = {10.1038/s41746-026-03170-8},
url = {https://doi.org/10.1038/s41746-026-03170-8}
}
PolyForm Noncommercial License 1.0.0. Commercial use requires a separate
written agreement. Dataset and model licenses apply separately.
For research use.