Patient Scenario Definition Language - Reference Implementation
Project description
PSDL
Patient Scenario Definition Language
An Open Standard for Clinical Logic, Real-Time Monitoring & AI Integration
What SQL became for data queries, ONNX for ML models, and GraphQL for APIs โ
PSDL is becoming the semantic layer for clinical AI.
๐ Read the Whitepaper: English ยท ็ฎไฝไธญๆ ยท Espaรฑol ยท Franรงais ยท ๆฅๆฌ่ช
Try It Now (No Setup Required)
Run PSDL in your browser with Google Colab - zero installation, real clinical data:
| Notebook | Data | Description |
|---|---|---|
| Synthetic | Quick demo with generated patient data (2 min) | |
| MIMIC-IV Demo | 100 real ICU patients, ICD diagnoses | |
| PhysioNet Sepsis | 40,000+ patients with labeled sepsis |
The Problem
Despite significant advances in clinical AI and machine learning, real-time decision support in healthcare remains fragmented, non-portable, non-reproducible, and exceptionally difficult to audit or regulate.
PSDL fills the missing semantic layer in the healthcare AI stack
What is PSDL?
PSDL (Patient Scenario Definition Language) is a declarative, vendor-neutral language for expressing clinical scenarios. It provides a structured way to define:
| Component | Description |
|---|---|
| Signals | Time-series clinical data bindings (labs, vitals, etc.) |
| Trends | Temporal computations over signals (deltas, slopes, averages) |
| Logic | Boolean algebra combining trends into clinical states |
| Population | Criteria for which patients a scenario applies to |
| Triggers | Event-condition-action rules (v0.2) |
Syntax vs Semantics vs Runtime - How PSDL Works
Quick Example
# Detect early kidney injury
scenario: AKI_Early_Detection
version: "0.1.0"
signals:
Cr:
source: creatinine
concept_id: 3016723 # OMOP concept
unit: mg/dL
trends:
cr_rising:
expr: delta(Cr, 6h) > 0.3
description: "Creatinine rise > 0.3 mg/dL in 6 hours"
cr_high:
expr: last(Cr) > 1.5
description: "Current creatinine elevated"
logic:
aki_risk:
expr: cr_rising AND cr_high
severity: high
description: "Early AKI - rising and elevated creatinine"
Why PSDL?
| Challenge | Without PSDL | With PSDL |
|---|---|---|
| Portability | Logic tied to specific hospital systems | Same scenario runs anywhere with mapping |
| Auditability | Scattered across Python, SQL, configs | Single structured, version-controlled file |
| Reproducibility | Hidden state, implicit dependencies | Deterministic execution, explicit semantics |
| Regulatory Compliance | Manual documentation | Built-in audit primitives |
| Research Sharing | Cannot validate published scenarios | Portable, executable definitions |
Installation
# Clone the repository
git clone https://github.com/Chesterguan/PSDL.git
cd psdl
# Install dependencies
pip install -r requirements.txt
Usage
Parse a Scenario
from psdl import PSDLParser
parser = PSDLParser()
scenario = parser.parse_file("examples/aki_detection.yaml")
print(f"Scenario: {scenario.name}")
print(f"Signals: {list(scenario.signals.keys())}")
print(f"Logic rules: {list(scenario.logic.keys())}")
Evaluate Against Patient Data
from psdl import PSDLParser, PSDLEvaluator, InMemoryBackend
from psdl.operators import DataPoint
from datetime import datetime, timedelta
# Parse scenario
parser = PSDLParser()
scenario = parser.parse_file("examples/aki_detection.yaml")
# Set up data backend
backend = InMemoryBackend()
now = datetime.now()
# Add patient data
backend.add_data(
patient_id=123,
signal_name="Cr",
data=[
DataPoint(now - timedelta(hours=6), 1.0),
DataPoint(now - timedelta(hours=3), 1.3),
DataPoint(now, 1.8),
]
)
# Evaluate
evaluator = PSDLEvaluator(scenario, backend)
result = evaluator.evaluate_patient(patient_id=123, reference_time=now)
if result.is_triggered:
print(f"Patient triggered: {result.triggered_logic}")
print(f"Trend values: {result.trend_values}")
Temporal Operators
| Operator | Syntax | Description |
|---|---|---|
delta |
delta(signal, window) |
Absolute change over window |
slope |
slope(signal, window) |
Linear regression slope |
ema |
ema(signal, window) |
Exponential moving average |
sma |
sma(signal, window) |
Simple moving average |
min |
min(signal, window) |
Minimum value in window |
max |
max(signal, window) |
Maximum value in window |
count |
count(signal, window) |
Observation count |
last |
last(signal) |
Most recent value |
Window Formats
30s- 30 seconds5m- 5 minutes6h- 6 hours1d- 1 day7d- 7 days
Project Structure
PSDL follows industry-standard patterns (like GraphQL, CQL, ONNX):
- Specification defines WHAT
- Reference Implementation shows HOW.
psdl/
โโโ README.md # This file
โโโ spec/ # SPECIFICATION
โ โโโ schema-v0.1.yaml # YAML schema + operator semantics
โโโ src/psdl/ # REFERENCE IMPLEMENTATION (Python)
โ โโโ __init__.py
โ โโโ parser.py # YAML parser
โ โโโ evaluator.py # Batch execution mode
โ โโโ operators.py # Temporal operators
โ โโโ execution/ # Execution Modes
โ โ โโโ batch.py # Batch mode + SQL compiler
โ โ โโโ streaming/ # Streaming mode (Flink)
โ โโโ adapters/ # Data Adapters
โ โโโ omop.py # OMOP CDM adapter (SQL)
โ โโโ fhir.py # FHIR R4 adapter (REST)
โโโ examples/ # Example scenarios
โ โโโ icu_deterioration.yaml
โ โโโ aki_detection.yaml
โ โโโ sepsis_screening.yaml
โโโ docs/
โ โโโ getting-started.md
โ โโโ WHITEPAPER.md # Full specification document
โ โโโ assets/ # Images and diagrams
โโโ tests/
โโโ test_parser.py
โโโ test_evaluator.py
| Component | Description |
|---|---|
| Specification | PSDL language definition (YAML schema + operator semantics) |
| Reference Implementation | Python implementation demonstrating the spec |
| Parser | Parses PSDL YAML into internal representation |
| Evaluator | Executes parsed scenarios (batch mode) |
| Data Adapter | Interface to clinical data sources (OMOP, FHIR) |
Running Tests
# Run all tests
pytest tests/ -v
# Run with verbose output
pytest tests/ -v -s
Test Coverage: 234 Tests (All Passing)
- Unit Tests: Parser, evaluator, operators, scenarios
- Integration Tests: FHIR adapter, OMOP backend with population filtering
- Validation: SQL equivalence (100% match), KDIGO clinical guidelines
- Streaming Tests: Window functions, logic evaluation, Flink compiler
See tests/TEST_VALIDATION.md for detailed methodology.
Example Scenarios
| Scenario | Description | Clinical Use |
|---|---|---|
| ICU Deterioration | Monitors for early signs of clinical deterioration | Kidney function, lactate trends, hemodynamics |
| AKI Detection | KDIGO criteria for Acute Kidney Injury staging | Creatinine-based staging |
| Sepsis Screening | qSOFA + lactate-based sepsis screening | Early sepsis identification |
Design Principles
| Principle | Description |
|---|---|
| Declarative | Define what to detect, not how to compute it |
| Portable | Same scenario runs on any OMOP/FHIR backend with mapping |
| Auditable | Structured format enables static analysis and version control |
| Deterministic | Predictable execution with no hidden state |
| Open | Vendor-neutral, community-governed |
Roadmap
| Phase | Status | Focus |
|---|---|---|
| Phase 1: Semantic Foundation | โ Complete | Spec, parser, operators, OMOP/FHIR adapters, 234 tests |
| Phase 2: Enhanced Runtime | ๐ง Current | โ Streaming, โ SQL generation, triggers, packaging |
| Phase 3: Community | ๐ Planned | Blog series, conferences, tooling ecosystem |
| Phase 4: Adoption | ๐ฎ Future | Hospital pilots, standards engagement |
Related Standards
| Standard | Relationship |
|---|---|
| OMOP CDM | Data model for signals (concept_id references) |
| FHIR | Planned runtime target |
| CQL | Similar domain, different scope (quality measures) |
| ONNX | Inspiration for portable format approach |
Documentation
| Document | Description |
|---|---|
| Whitepaper | Full project vision and specification (5 languages) |
| Getting Started | Quick start guide |
| Roadmap | Development phases and timeline |
| Schema | YAML schema definition |
| Changelog | Version history |
Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Ways to Contribute
- Specification: Propose language features, operators, semantics
- Implementation: Build runtimes, backends, tooling
- Documentation: Improve guides, tutorials, examples
- Testing: Add conformance tests, find edge cases
- Adoption: Share use cases, pilot experiences
License
Apache 2.0 - See LICENSE for details.
Clinical AI doesn't fail because models are weak.
It fails because there's no semantic layer to express clinical logic portably.
PSDL is the semantic layer for clinical AI โ like SQL for databases.
An open standard built by the community, for the community.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file psdl_lang-0.2.0.tar.gz.
File metadata
- Download URL: psdl_lang-0.2.0.tar.gz
- Upload date:
- Size: 106.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29a5682aabc4e95ccdbec6bf68a68ac4512705a3bb4e24a65e5761e71543cd37
|
|
| MD5 |
a51489295530887a0ab633428d8eb208
|
|
| BLAKE2b-256 |
1fadd3bb1f3c28175e59858a80324d236b4f8584b7b978d7c66d6b994aec0f25
|
Provenance
The following attestation bundles were made for psdl_lang-0.2.0.tar.gz:
Publisher:
publish.yml on Chesterguan/PSDL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
psdl_lang-0.2.0.tar.gz -
Subject digest:
29a5682aabc4e95ccdbec6bf68a68ac4512705a3bb4e24a65e5761e71543cd37 - Sigstore transparency entry: 760405295
- Sigstore integration time:
-
Permalink:
Chesterguan/PSDL@15f3603557b94a90937f2572278e46b6630aaafd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Chesterguan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@15f3603557b94a90937f2572278e46b6630aaafd -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file psdl_lang-0.2.0-py3-none-any.whl.
File metadata
- Download URL: psdl_lang-0.2.0-py3-none-any.whl
- Upload date:
- Size: 66.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66b40de072c9d03d69b1c866052db074917b735fdd4ae21fecff61107111414a
|
|
| MD5 |
3ad0b071d653f9a963c738e244c41cce
|
|
| BLAKE2b-256 |
6ff5a4dbaa779889e6f169479c43d3c3f41105290ecc7b36dc96f3e71a9ef1b8
|
Provenance
The following attestation bundles were made for psdl_lang-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on Chesterguan/PSDL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
psdl_lang-0.2.0-py3-none-any.whl -
Subject digest:
66b40de072c9d03d69b1c866052db074917b735fdd4ae21fecff61107111414a - Sigstore transparency entry: 760405303
- Sigstore integration time:
-
Permalink:
Chesterguan/PSDL@15f3603557b94a90937f2572278e46b6630aaafd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Chesterguan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@15f3603557b94a90937f2572278e46b6630aaafd -
Trigger Event:
workflow_dispatch
-
Statement type: