# VigilCare Clinical Simulator -- User Guide Welcome! The VigilCare Simulator lets you replay realistic hospital patient scenarios against the VigilCare Clinical API. You can watch a patient's vitals change over time, see alerts fire (NEWS2, SIRS/qSOFA, sepsis bundles), and observe how the system detects clinical deterioration -- all without real patients. Think of it as a flight simulator, but for clinical decision support. --- ## Table of Contents 1. [Prerequisites](#1-prerequisites) 2. [Quick Start](#2-quick-start) 3. [Available Commands](#3-available-commands) 4. [Understanding Scenarios](#4-understanding-scenarios) 5. [Available Scenarios](#5-available-scenarios) 6. [Controlling Replay Speed](#6-controlling-replay-speed) 7. [Reading the Output](#7-reading-the-output) 8. [Creating Your Own Scenarios](#8-creating-your-own-scenarios) 9. [Troubleshooting](#9-troubleshooting) --- ## 1. Prerequisites You need two things installed: - **.NET 8 SDK** -- Download from [dotnet.microsoft.com](https://dotnet.microsoft.com/download/dotnet/8.0) - **The VigilCare API running locally** -- The simulator sends data to the API, so it must be up first ### Starting the API From the project root directory, run: ```bash docker compose up -d dotnet run --project VigilCare.Api ``` The API starts on `http://localhost:5270` by default. > See [docker-compose-usage-and-troubleshooting.md](docker-compose-usage-and-troubleshooting.md) if you have trouble with Docker. --- ## 2. Quick Start Open a terminal in the project root and run: ```bash dotnet run --project VigilCare.Simulator -- replay \ VigilCare.Simulator/Scenarios/List/uti-sepsis-elderly-01.json \ --speed 60 --poll ``` This replays a 4-hour UTI-to-sepsis progression in about 4 seconds, showing alerts as they fire. That's it! Read on for more detail. --- ## 3. Available Commands The simulator has four commands. All are run with `dotnet run --project VigilCare.Simulator -- `. ### replay -- Run a scenario against the API ```bash dotnet run --project VigilCare.Simulator -- replay [options] ``` **Options:** | Option | Default | Description | |--------|---------|-------------| | `--speed ` | 60 | How fast to run (see [Speed](#6-controlling-replay-speed)) | | `--base-url ` | `http://localhost:5270` | API address (change if your API runs elsewhere) | | `--poll` | off | Show alerts and scores after each set of vitals | | `--poll-interval ` | 5 | How often to check for alerts when polling | **Example -- run the stable baseline scenario in real-time with polling:** ```bash dotnet run --project VigilCare.Simulator -- replay \ VigilCare.Simulator/Scenarios/List/stable-baseline-01.json \ --speed 1 --poll ``` ### replay-all -- Run every scenario in a folder ```bash dotnet run --project VigilCare.Simulator -- replay-all [options] ``` Runs all `.json` scenario files in the given directory, one after another. Accepts `--speed` and `--base-url`. **Example:** ```bash dotnet run --project VigilCare.Simulator -- replay-all \ VigilCare.Simulator/Scenarios/List --speed 60 ``` ### validate -- Check a scenario file for errors ```bash dotnet run --project VigilCare.Simulator -- validate ``` Checks that the JSON is well-formed and all fields are valid. Does **not** contact the API. **Example:** ```bash dotnet run --project VigilCare.Simulator -- validate \ VigilCare.Simulator/Scenarios/List/stable-baseline-01.json ``` ### dry-run -- Preview the timeline without touching the API ```bash dotnet run --project VigilCare.Simulator -- dry-run ``` Prints exactly what *would* happen (every vital sign, medication, and order) without sending anything. **Example:** ```bash dotnet run --project VigilCare.Simulator -- dry-run \ VigilCare.Simulator/Scenarios/List/cardiac-arrest-post-mi-01.json ``` --- ## 4. Understanding Scenarios Each scenario is a JSON file that tells a clinical story. It contains: - **Patient** -- Name, date of birth, gender - **Encounter** -- Department, encounter type, attending physician, room/bed - **Events** -- A timeline of observations (vitals, labs), medications, and orders Here is what a simplified scenario looks like: ```json { "scenario": { "id": "stable-baseline-01", "name": "Stable Baseline -- Routine Inpatient Monitoring", "description": "52-year-old female admitted for elective cholecystectomy...", "durationMinutes": 480, "tags": ["stable", "baseline", "control", "surgery"] }, "patient": { "firstName": "Linda", "lastName": "Weston", "dateOfBirth": "1974-02-18", "gender": "Female" }, "encounter": { "department": "Surgery", "encounterType": "Inpatient", "attendingPhysician": "Dr. James Nakamura", "roomBed": "SURG-204B", "admissionReason": "Elective laparoscopic cholecystectomy" }, "events": [ { "offsetMinutes": 0, "type": "observation", "data": { "code": "HEART_RATE", "value": 72, "unit": "bpm" }, "note": "Post-op arrival, patient alert and comfortable" }, { "offsetMinutes": 60, "type": "medication", "data": { "drugName": "acetaminophen", "dose": 1000, "doseUnit": "mg", "route": "PO", "administeredBy": "RN Davis" } } ] } ``` The key concept is **offsetMinutes** -- each event happens at a certain number of minutes after the scenario starts. The simulator waits the appropriate amount of time (adjusted by your speed setting) before sending each event. ### Event Types | Type | What It Represents | Example | |------|--------------------|---------| | `observation` | A vital sign or lab result | Heart rate 110 bpm, Temperature 39.2 C | | `medication` | A drug being administered | Ceftriaxone 1g IV | | `order` | A clinical order being placed | "Blood cultures", "Chest X-ray" | | `order_result` | Result of a prior order | "Positive for E. coli" | ### Vital Sign Codes These are the observation codes used in scenarios: | Code | What It Measures | Unit | Normal Range | |------|-----------------|------|-------------| | `HEART_RATE` | Heart rate | bpm | 51--90 | | `RESP_RATE` | Respiratory rate | /min | 12--20 | | `SYSTOLIC_BP` | Systolic blood pressure | mmHg | 111--219 | | `DIASTOLIC_BP` | Diastolic blood pressure | mmHg | 60--90 | | `TEMP_C` | Temperature | C | 36.1--38.0 | | `SPO2` | Oxygen saturation | % | 96--100 | | `AVPU` | Consciousness level | score | 0 = Alert | | `SUPPLEMENTAL_O2` | On supplemental oxygen? | flag | 0 = No | | `WBC_K_UL` | White blood cell count | x10^3/uL | 4.5--11.0 | | `LACTATE_MMOL_L` | Serum lactate | mmol/L | 0.5--1.5 | | `POTASSIUM_MEQ_L` | Potassium | mEq/L | 3.5--5.0 | | `GLUCOSE_MG_DL` | Blood glucose | mg/dL | 70--140 | --- ## 5. Available Scenarios The simulator ships with 8 scenarios covering different clinical situations: | Scenario | Clinical Story | Duration | |----------|---------------|----------| | **stable-baseline-01** | Post-op cholecystectomy, all vitals normal. Control case -- no alerts should fire. | 8 hours | | **uti-sepsis-elderly-01** | 78-year-old with UTI progressing to sepsis. SIRS criteria met, sepsis bundle triggered. | 4 hours | | **cardiac-arrest-post-mi-01** | Post-MI patient deteriorating into cardiogenic shock. Rapid HR/BP changes. | Varies | | **post-op-hemorrhage-01** | Surgical patient with internal bleeding. Rising HR, falling BP and SpO2. | Varies | | **respiratory-failure-asthma-01** | Asthma exacerbation progressing to respiratory failure. Falling SpO2, rising RR. | Varies | | **dka-electrolyte-01** | Diabetic ketoacidosis with potassium and glucose derangement. | Varies | | **hypothermia-elderly-01** | Elderly patient with severe hypothermia. Slow HR, dropping temperature. | Varies | | **medication-false-alarm-01** | Beta-blocker causing bradycardia. Tests whether the system correctly handles medication-induced vital changes. | 3 hours | All scenario files are in: `VigilCare.Simulator/Scenarios/List/` --- ## 6. Controlling Replay Speed The `--speed` option controls how fast simulated time passes: | Speed | Meaning | A 4-hour scenario takes... | |-------|---------|---------------------------| | `0` | Instant -- no waiting, all events fire immediately | < 1 second | | `1` | Real-time -- 1 simulated minute = 1 real minute | 4 hours | | `10` | 10x -- 1 simulated minute = 6 real seconds | 24 minutes | | `60` | 60x (default) -- 1 simulated minute = 1 real second | 4 minutes | | `120` | 120x -- 1 simulated minute = 0.5 real seconds | 2 minutes | **Recommendations:** - **For demos / presentations:** Use `--speed 10` with `--poll` so people can follow along - **For quick testing:** Use `--speed 60` or `--speed 0` - **For the most realistic experience:** Use `--speed 1` (real-time, a 4-hour scenario takes 4 hours) --- ## 7. Reading the Output When you run a `replay`, the simulator prints a colored timeline. Here's what to look for: ``` ────────────────── Stable Baseline -- Routine Inpatient Monitoring ────────────────── 52-year-old female admitted for elective cholecystectomy... Patient registered: 3fa85f64-... (MRN-12345) Encounter opened: 7c9e6679-... (active) [00:00] HEART_RATE 72 bpm [00:00] RESP_RATE 14 /min [00:00] SYSTOLIC_BP 124 mmHg [00:00] SPO2 98 % ... waiting 60m simulated (1.0s real) ... [01:00] HEART_RATE 74 bpm [01:00] medication: acetaminophen 1000 mg PO ``` **With `--poll` enabled, you also see clinical scoring:** ``` [01:30] NEWS2 = 5 (Medium) [01:30] ALERT SEPSIS_WARNING (Critical) [01:30] SEPSIS BUNDLE InProgress (2/4 completed) ``` **At the end, a summary table appears:** ``` Metric Value ----------------------------------- Scenario uti-sepsis-elderly-01 Observations sent 42 Medications sent 2 Orders placed 3 Wall-clock time 12.3s ``` ### What the Alerts Mean | Alert | Meaning | |-------|---------| | `NEWS2_LOW` | NEWS2 score 1--4: Low risk, routine monitoring | | `NEWS2_MEDIUM` | NEWS2 score 5--6 or single parameter score of 3: Urgent review needed | | `NEWS2_HIGH` | NEWS2 score 7+: Emergency response needed | | `SEPSIS_WARNING` | SIRS criteria met (2+ of: temp, HR, RR, WBC abnormal) | | `QSOFA_WARNING` | qSOFA criteria met (2+ of: altered mentation, RR >= 22, SBP <= 100) | | `RAPID_DETERIORATION` | Sudden significant change in vital signs | --- ## 8. Creating Your Own Scenarios You can create new clinical scenarios by writing a JSON file. There are two ways: ### Option A: Write it manually 1. Copy an existing scenario from `VigilCare.Simulator/Scenarios/List/` as a template 2. Modify the patient, encounter, and events to match your clinical story 3. Make sure `offsetMinutes` values are in ascending order 4. Validate it: ```bash dotnet run --project VigilCare.Simulator -- validate ./my-scenario.json ``` ### Option B: Use AI to generate it There is a generation prompt file at `VigilCare.Simulator/Scenarios/GENERATE_PROMPT.md`. You can paste its contents into ChatGPT, Claude, or another AI assistant, describe the clinical case you want, and it will generate a valid scenario JSON file for you. ### Validation Rules The simulator enforces these rules on scenario files: - **scenario.id** and **scenario.name** are required - **encounter.department** must be one of: `Icu`, `GeneralMedicine`, `Emergency`, `Cardiology`, `Surgery`, `Pediatrics` - **encounter.encounterType** must be one of: `Inpatient`, `Outpatient`, `Emergency` - **events** must be non-empty, with `offsetMinutes` in ascending order - **observation codes** must match one of the 12 valid codes listed above - Maximum **10 observations per time point** (API batch limit) - **order_result** events must reference a matching prior order (or a sepsis bundle auto-order) ### Sepsis Bundle Auto-Orders When the system detects sepsis (SIRS or qSOFA criteria met), it automatically creates four orders: - `SEP-1: Blood cultures` - `SEP-1: Serum lactate` - `SEP-1: Broad-spectrum antibiotics` - `SEP-1: IV fluid bolus` You do **not** need to create `order` events for these. Just add `order_result` events referencing them to simulate bundle completion. --- ## 9. Troubleshooting ### "Connection refused" error The API is not running. Start it first: ```bash docker compose up -d dotnet run --project VigilCare.Api ``` ### "scenario.json has N error(s)" Run `validate` to see what's wrong: ```bash dotnet run --project VigilCare.Simulator -- validate ./your-scenario.json ``` Common issues: - Invalid department name (must match exact casing: `Icu`, not `ICU`) - `offsetMinutes` out of order - Missing required fields (`scenario.id`, `scenario.name`, `encounter.attendingPhysician`) ### Medications show "skipped" The medication tracking endpoint may not be available. This is non-fatal -- the scenario continues. ### "dotnet" command not found Install .NET 8 SDK from [dotnet.microsoft.com](https://dotnet.microsoft.com/download/dotnet/8.0). ### I want to point the simulator at a different API Use `--base-url`: ```bash dotnet run --project VigilCare.Simulator -- replay scenario.json \ --base-url http://192.168.1.50:5270 ```