Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
"runtimeArgs": ["start", "--prefix", "/Volumes/Samsung-Ext/dev/DeepPhe-Visualizer-v2"],
"port": 3000,
"autoPort": true
},
{
"name": "viz2-docs",
"runtimeExecutable": "npm",
"runtimeArgs": ["--prefix", "docs-site", "run", "serve"],
"port": 3002,
"autoPort": true
}
]
}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ npm run eject # Eject from react-scripts (one-way operation)

### User documentation

The published user guide is at <https://deepphe.github.io/DeepPhe-Visualizer-v2/>.

The task-oriented user guide is built with Docusaurus in an isolated
`docs-site/` package. Node.js 20 or later is required for documentation builds.

Expand Down
8 changes: 7 additions & 1 deletion docs-site/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ const sidebars: SidebarsConfig = {
type: 'category',
label: 'Getting Started',
collapsed: false,
items: ['getting-started/overview', 'getting-started/first-cohort'],
items: [
'getting-started/overview',
'getting-started/first-cohort',
'getting-started/guided-exercise',
'getting-started/exercise-targeted-therapy',
'getting-started/exercise-compare-outcomes',
],
},
{
type: 'category',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions docs/contributors/screenshot-capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,29 @@ Useful environment variables:
- `VIZ2_SCREENSHOT_DIR` — where source captures are written (default `../Viz2_screenshots`).
- `DOC_PATIENT_ID` — the synthetic patient used for the standalone-patient and Document Viewer captures (default `fake_patient3`).
- `COLLAPSED_DATE_PATIENT_ID` — a synthetic patient whose notes collapse to one date, used for the timeline's episode-dropdown fallback capture (optional).
- `CAPTURE_ONLY` — a comma-separated list of file-name fragments. When set, only matching captures are written, so one data-dependent series can be re-taken without re-shooting the whole set. See [Re-take a single series](#re-take-a-single-series).

The capture script forces the **Standard** theme so images are consistent, disables animations, and waits for content to load before each shot.

### Guided-exercise captures

The [guided exercise](../getting-started/guided-exercise.md) needs specific records: one patient whose structure and source notes agree, and one carrying contradictory extractions. Those captures are all optional, and each has an override:

- `EXERCISE_CORROBORATED_PATIENT_ID` — the patient with a metastatic second cancer confirmed by a later pathology report (default `fake_patient125`).
- `EXERCISE_CONFLICTED_PATIENT_ID` — the patient whose TNM value disagrees with their stage, and whose radiology report both asserts and negates metastatic disease (default `fake_patient460`).
- `EXERCISE_STAGE_VALUE` — the Stage card value the exercise filters on (default `Stage IV`).
- `EXERCISE_AGE_BAND` — the Age at Dx band that, combined with the stage value, narrows the cohort far enough for the conflicted patient to render as a clickable [patient dot](../cohort-explorer/patient-dots.md) (default `30-39`).

If you change any of these, re-read the exercise page: it quotes cohort counts and findings that come from these specific records.

### Re-take a single series

```bash
CAPTURE_ONLY=exercise npm run capture:screenshots
```

Captures whose file name contains the fragment are written; every other tracked image is left untouched. Useful when one series is flaky or data-dependent and a full re-run would churn — or degrade — images that are already good.

## Required vs. optional captures

`scripts/capture-screenshots.mjs` splits its targets into two sets:
Expand Down
126 changes: 126 additions & 0 deletions docs/getting-started/exercise-compare-outcomes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
title: "Guided exercise: compare treatment outcomes"
sidebar_label: "Exercise: compare outcomes"
description: A worked cohort-comparison exercise that contrasts complete responders with progressors and reads the difference off the filter cards — including a whole stage value going dark.
---

# Guided exercise: compare treatment outcomes

Comparing subgroups is a core reason researchers reach for a tool like this. The [targeted-therapy exercise](exercise-targeted-therapy.md) built one cohort; this one builds two and holds them up against each other:

> **Some tumors responded completely to treatment. Others kept growing. What separates the two groups?**

You will define each group in turn and read the difference directly off the cards — no export, no statistics package, just the repaint. Allow about 10 minutes.

## Before you start

Written against the bundled **synthetic demonstration dataset** of 500 breast cancer patients. Counts below come from that dataset; they will differ on other data but the method is the same — see [Adapt this to your own data](#adapt-this-to-your-own-data).

:::caution Synthetic data

These records are generated. Study how the Visualizer **represents** the groups, not the specific fabricated values.

:::

Start unfiltered — **Reset filters** so the toolbar reads **All 500 patients**.

---

## Step 1 — Define the responders

Scroll to the **Clinical Course of Disease** card and select **`Pathologic Complete Response`** — patients whose tumor was gone at surgery after treatment, the best outcome on offer.

The cohort settles at **33 patients**. Open the **Stage** card's Details dialog.

![The Stage dialog for complete responders, with Stage IV dimmed at 0 of 34](../assets/screenshots/end-user/outcome-responders-stage.png)

**What you see.** Stage I `5/196`, Stage II `12/121`, Stage III `9/48` — and **Stage IV dimmed at `0/34`**. The Stage IV row is greyed and cannot be selected.

**Why this matters.** That dimmed row is the Visualizer telling you something with an absence. A value goes disabled when **no patient in the current cohort carries it** — selecting it could only ever produce zero, so the interface takes it off the table (see [Values that can't add anyone are disabled](../cohort-explorer/selecting-filters.md#values-that-cant-add-anyone-are-disabled)). Here it means the clinical headline outright: **not one complete responder was stage IV**. You did not have to run a query to learn that — a whole stage simply went dark.

---

## Step 2 — Read the rest of the responders' profile

Without changing the selection, look at the **Metastatic Behavior** card.

![The Metastatic Behavior card for complete responders, with Metastatic at 1 of 30](../assets/screenshots/end-user/outcome-responders-behavior.png)

**What you see.** `Metastatic` reads **1/30** — a single responder shows metastatic behavior. The Grade card, meanwhile, is spread evenly across `G1` (6), `G2` (8), and `G3` (8).

**Why this matters.** The picture is internally consistent: the group that responded completely is early-stage and almost never metastatic. Note what you are *not* doing — you are not cross-tabulating outcome against stage, then outcome against metastasis, then outcome against grade as three separate queries. You defined the group once and every card now describes it at a glance. That is the cohort-comparison workflow: characterize a group by reading its repaint, not by asking one question at a time.

---

## Step 3 — Define the progressors

**Reset filters**, then, on the same **Clinical Course of Disease** card, select **`Progressive Disease`** — patients whose disease advanced despite treatment.

This cohort settles at **29 patients**. Open the **Stage** dialog again.

![The Stage dialog for progressors, with Stage III dimmed and Stage IV present at 11 of 34](../assets/screenshots/end-user/outcome-progressors-stage.png)

**What you see.** A different shape entirely. **Stage IV is present and solid at `11/34`** — the largest single stage in this group. This time it is **Stage III** that is dimmed at `0/48`.

**Why this matters.** Set this dialog beside the one from Step 1 and the contrast is the whole exercise. For responders, stage IV was the impossible value; for progressors, it is the dominant one. The same disabled-value mechanism now points the opposite way, and eleven of twenty-nine progressors carry the stage that not one responder did. The interface has drawn the line between good and bad outcomes for you, in the position of a single dimmed bar.

---

## Step 4 — Confirm the pattern holds

Look at the progressors' **Metastatic Behavior** card.

![The Metastatic Behavior card for progressors, with Metastatic at 10 of 30](../assets/screenshots/end-user/outcome-progressors-behavior.png)

**What you see.** `Metastatic` reads **10/30**, against the responders' `1/30`. And the Grade card has shifted toward the high end — `G3` (12) now outweighs `G1` (3).

**Why this matters.** Every card tells the same story the stage dialog did: the group that progressed is later-stage, far more often metastatic, and higher-grade. When independent variables all move together like this, you are looking at a real signal in the cohort rather than an artifact of one facet. Reading three cards took you seconds, and you never left the screen.

:::note Counts on the bar vs. the cohort

The `Pathologic Complete Response` bar reads **36** but the cohort settled at **33**; `Progressive Disease` reads **30** but gives **29**. The number on a facet bar counts extracted *mentions* of the concept, and one patient can carry a concept in more than one place. The drawer and the toolbar count **distinct patients**. When you cite a cohort size, use the toolbar's count. See [Understand cohort results](../cohort-explorer/understanding-results.md).

:::

---

## What this exercise demonstrated

| Step | Capability | The reason it matters |
| --- | --- | --- |
| 1 | A disabled value marks an empty intersection | A whole stage going dark states a finding without a query |
| 2 | One selection characterizes a group across every card | Compare subgroups by reading the repaint, not one cross-tab at a time |
| 3 | The disabled value points the other way for the other group | The contrast between two cohorts is legible in a single dimmed bar |
| 4 | Independent facets move together | Concordant shifts across cards signal a real pattern, not a facet artifact |
| 4 | Bar count (mentions) ≠ cohort count (patients) | Cite the toolbar's distinct-patient count when you report a cohort size |

---

## Adapt this to your own data

The comparison method transfers to any pair of contrasting groups:

1. **Pick two opposing values** of the same clinical axis — responders vs. progressors, recurrent vs. disease-free, one biomarker status vs. another.
2. **Select the first, read three or four cards, then reset and select the second.** Keep the same cards in view both times so the differences are easy to spot.
3. **Watch for disabled values.** A value that is available for one group and dimmed for the other is a difference the interface has already found for you.
4. **Trust concordance, distrust a lone signal.** When stage, grade, and metastatic behavior all shift the same way, the pattern is robust; a difference on a single facet may be an extraction artifact. Confirm anything decision-relevant against the source records.

## Presenting this as a demonstration

The exercise compresses to about four minutes:

| Time | Section |
| --- | --- |
| 0:00–0:30 | Premise and the synthetic-data caveat |
| 0:30–1:45 | Step 1–2 — responders: Stage IV dimmed, metastatic 1/30 |
| 1:45–3:15 | Step 3–4 — progressors: Stage IV 11/34, metastatic 10/30 |
| 3:15–4:00 | Put the two Stage dialogs side by side and close on the contrast |

The single strongest beat is opening the two Stage dialogs back to back — the dimmed bar jumps from Stage IV to Stage III between them. Keep **Reset filters** in reach for the switch.

## Next steps

- [Guided exercise: build a targeted-therapy cohort](exercise-targeted-therapy.md) — the companion cohort-building exercise
- [Select and combine filters](../cohort-explorer/selecting-filters.md) — how and why values become disabled
- [Understand cohort results](../cohort-explorer/understanding-results.md) — counts, mentions vs. patients, and empty results
- [Filter Details dialog](../cohort-explorer/filter-details.md) — the full value list behind each card
Loading