Getting Started with PHRAME
A data scientist’s guide to patient-centered health infrastructure.
Getting Started with PHRAME
A data scientist’s guide to patient-centered health infrastructure.

Personal Health Record Architecture for Modular Extensibility
If you work with patient data — as an informaticist, a data scientist at a research foundation, or an engineer building health tooling — you already know the shape of the problem. The records are fragmented across providers. The standards are real but the mappings are manual. And the gap between “we have data” and “we can act on it for an individual patient” is wide and mostly hand-built.
PHRAME is an open-source suite from HealthKey designed to close that gap. It is infrastructure, not an end-user product: a set of components you assemble into a longitudinal, standards-based patient record and then build on. This post walks through how to go from a pile of patient data to working trial matching, outcomes analytics, and standard-of-care suggestions — using five projects that fit together.
Everything is available at github.com/healthkey-ai. The projects are designed to be adopted incrementally: you can start with the database alone and add the rest as you need them.
The Shape of the Suite
Before the steps, the mental model. PHRAME is organized as a pipeline with a storage layer in the middle and a serving layer on top:
- PRomop — the patient database. A standards-based longitudinal store built on the OMOP Common Data Model (CDM 5.4), with oncology extensions. This is where every patient record lives.
- PRism — the analytics platform that sits over PRomop, for population and cohort-level insight.
- EXACT — the clinical trial matcher, which evaluates patients against trial eligibility criteria.
- SoC — the standard-of-care service, which evaluates guideline-based care options for a patient.
- fhir_importers — the ingestion path for pulling additional records in from EHRs via FHIR.
The key architectural idea worth internalizing up front: everything serves off the same patient record. Trial matching, outcomes analytics, and standard-of-care evaluation all read from PRomop rather than each maintaining its own copy of the truth. That is what makes the suite coherent rather than five disconnected tools.
Step 1 — Load Patients with PRomop
Start with the database. PRomop gives you a standard OMOP CDM 5.4 schema — the familiar tables like person, condition_occurrence, drug_exposure, measurement, observation, procedure_occurrence — plus oncology-specific extensions for episodes and lines of therapy that the base CDM doesn't cover well.
The first task is getting your source data mapped into that schema. If you come from the OHDSI world this will feel native: PRomop is designed to work with the standard tooling (WhiteRabbit and Rabbit-in-a-Hat for profiling and source-to-OMOP mapping, Usagi and Athena for vocabulary mapping to LOINC, SNOMED CT, RxNorm, and ICD-O-3). You profile your source, author the field mappings, and load.
What makes PRomop more than “just an OMOP database” is PatientRecord — a flattened, denormalized projection of each patient into a single wide row of ~266 fields. The transactional CDM tables are the source of truth and capture everything that ever happened; PatientRecord is the decision-ready view of what is true now: demographics, staging, treatment lines, biomarkers, labs, derived fields like prior-therapy and current status. You populate it with a management command after loading.
This projection is the load-bearing piece for everything downstream — it is what lets analytics, trial matching, and care evaluation all run on the same substrate without re-deriving patient state each time. By the end of this step you have a queryable, standards-conformant longitudinal record for your patient population.
Step 2 — Analyze Aggregate Outcomes with PRism
With patients loaded, PRism gives you the population view. It is the analytics layer over PRomop, built for the questions a research foundation or informatics team actually asks: what are the outcomes across this cohort, how do treatment patterns shift over time, what does survival look like for a given subgroup.
Out of the box you get standard oncology analytics — Kaplan-Meier curves for overall survival, progression-free survival, and event-free survival; treatment-sequence visualizations (a sunburst of how therapy changes line to line); cohort definition and saving; and the data-characterization and quality metrics you’d expect from an OHDSI-style stack.
Because PRism reads the same PatientRecord projection, defining a cohort and computing an outcome on it is fast — you are querying a flat structure, not reassembling longitudinal state on every run.
A live demo running on synthetic data is at prism.healthkey.ai — you can create an account and explore the chart types against synthetic multiple myeloma and breast cancer patients to see the shape of what you’d get on your own cohort. This is the step where most teams get their first “we couldn’t see this before” moment: aggregate outcomes across a fragmented population, computed on a standardized record.
Step 3 — Find Trials for Patients with EXACT
EXACT is the open-source clinical trial matcher. Where most matchers return an opaque ranked list, EXACT evaluates each patient against trial eligibility criteria one criterion at a time and returns a tri-valued verdict per trial:
- Eligible — all inclusion criteria pass and no exclusions fire.
- Potential — the only thing standing between the patient and a verdict is missing data; EXACT tells you exactly what is missing.
- Ineligible — an inclusion failed or an exclusion triggered.
That middle state is the one that matters operationally. In real cohorts, “potential — need one more data point” is often the largest group, and surfacing precisely what’s missing turns a dead-end into an action: go collect that value, or import it (see Step 5).
EXACT runs against a structured trials database — for example a continuously updated feed of oncology trials from ClinicalTrials.gov, EU-CTR, and ISRCTN — using the same PatientRecord fields you populated in Step 1, so no patient re-modeling is required to start matching.
Because the verdicts are per-criterion and explained, EXACT’s output is also auditable: you can show a clinician or a patient navigator why a trial matched or didn’t, rather than asking them to trust a score.
Step 4 — Suggest Standard-of-Care Options with SoC
Trial matching answers “what research could this patient join.” The SoC service answers the equally important question patients and clinicians face: “what are the established care options right now.”
SoC evaluates guideline-based standard-of-care pathways against the patient’s record, with cancer-type-specific logic, and produces the care options applicable to that patient’s current state.
Running trial matching and standard-of-care evaluation on the same substrate is deliberate. A patient deciding what to do next needs both in view — a trial is rarely the right frame in isolation, and the most useful systems present research options and established care side by side. Because EXACT and SoC both read PatientRecord, you get that side-by-side view without integration glue.
One caution worth carrying: in rare disease there may be no accepted standard of care to compare against, so don’t assume SoC always returns a comparator.
Step 5 — Import Additional EHR Records via FHIR
Steps 1–4 work entirely on the data you started with. But patient records are never complete, and the fhir_importers project is how you enrich them. It ingests FHIR R4 resources — Patient, Condition, Observation, MedicationRequest, and the rest — and routes them into PRomop, where they land in the same CDM tables and flow back into the PatientRecord projection.
This is the step that turns a static cohort into a living one. As you connect EHR sources (including via networks like TEFCA/QHIN), new labs, diagnoses, and treatments arrive, the projection updates, and every downstream capability sees the richer picture automatically: outcomes analytics get more complete, trial matches that were “potential — missing data” can resolve to “eligible,” and standard-of-care evaluation reflects the patient’s current state.
The importers are FHIR-native, so FHIR Bundles route in directly; non-FHIR formats like C-CDA go through conversion first.
A practical note on sequencing: many teams deliberately start without EHR import — a manual or research-loaded cohort is enough to stand up the whole pipeline and prove value — and add fhir_importers once the data-sharing permissions are in place. The architecture supports either order.
Putting It Together
The whole loop, in one breath: load your population into PRomop and populate PatientRecord; see aggregate outcomes with PRism; match individuals to trials with EXACT; evaluate established care with SoC; and keep the records growing with fhir_importers — each new record flowing back through the same projection so every capability improves at once.
The reason it hangs together is the single shared record. You model patient state once, in a standards-based way, and four different kinds of value — population analytics, trial matching, care evaluation, ongoing ingestion — all read from it. That is the whole thesis of PHRAME as infrastructure: do the hard part (a clean longitudinal record) once, and make everything else a query against it.
Where to Start
Clone the projects from github.com/healthkey-ai and stand up PRomop first against a small cohort — even synthetic or research-loaded data is enough to see the pipeline work end to end. Explore the analytics live at prism.healthkey.ai before you load your own. From there, add EXACT, SoC, and fhir_importers in whatever order matches your priorities.
It’s open source because patient-centered infrastructure should be something the whole field can build on. If you’re an informaticist or data scientist working on this problem, we’d like to see what you build with it.
Specific setup instructions, dependencies, and supported versions are in each project’s repository README.
메타데이터
- post_id
- 6ff30b9115f3
- slug
- getting-started-with-phrame-6ff30b9115f3
- url
- https://medium.com/@adamsblum/getting-started-with-phrame-6ff30b9115f3
- canonical_url
- https://medium.com/@adamsblum/getting-started-with-phrame-6ff30b9115f3
- author_url
- https://medium.com/@adamsblum
- status
- ok
- fetched_at
- 2026-07-14 07:27:29