NHS North West Genomics
2.2.0 - ci-build
NHS North West Genomics - Local Development build (v2.2.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
This implementation guide primarily focuses on the Diagnostic Workflow and how it integrates within the broader health data model.
In software design, these areas are often referred to as domains. The Genomic Diagnostic Workflow operates across several of these domains — in software architecture terms, this is known as a bounded context.
National NHS bodies (e.g. NHS England, PDS, ODS) and NHS Trusts are, in
Domain Driven Design
terms, natural bounded
contexts in their own
right, each with its own internal data model - this guide doesn't cover
those models. Instead, this guide's resources reference that data via
identifiers (in FHIR, Reference.identifier), rather than modelling
those bounded contexts directly.
The relationship between bounded contexts like these is what Enterprise Integration Patterns calls a Canonical Data Model, and what Data Engineering calls a Data Contract - in HL7 FHIR terms, that's expressed as FHIR Profiles and the core models described below.
Why this is hard in practice. The same underlying clinical fact can take
a different shape at almost every step as it crosses these bounded contexts.
For example, whether a variant can even be tested for starts as a
suspected condition in a primary/secondary care system - the reason a
test is requested in the first place. Following testing, it becomes a
result panel (e.g. captured as a QuestionnaireResponse), then a
discrete Variant Observation, and once
reviewed, a Diagnostic
Implication. Only once
confirmed is it reported back to the Order Placer as a Condition - the same
clinical fact the referrer originally suspected, now represented by a
completely different resource:
flowchart LR
subgraph PSC["Primary/Secondary Care Domain — Order Placer"]
A["Suspected condition"]
TOF["Test Order Form"]
B["Test ordered"]
F["Confirmed Condition<br/>(back to Order Placer)"]
end
subgraph LAB["Genomics Laboratory Domain — Order Filler"]
C["Result panel<br/>(QuestionnaireResponse)"]
D["FHIR Variant"]
E["FHIR Diagnostic<br/>Implication"]
end
A --> TOF --> B --> C --> D --> E --> F
To complicate matters further, parts of this same chain may travel as HL7 v2 rather than FHIR in places, and the confirmed finding may just as easily arrive as a sentence within a PDF report rather than as discrete data at all
This isn't specific to genomics. The same shape-shifting happens in any
diagnostic pathway that crosses a Primary/Secondary Care boundary. For
example, a cardiology pathway follows an equivalent chain: a suspected
cardiac condition (e.g. suspected atrial fibrillation) leads to a Test Order
Form for an ECG/Holter monitor, which becomes the test order itself. The
cardiology domain then produces its own result panel, a discrete Observation
finding (e.g. an arrhythmia detected on the trace), and a reported diagnostic
conclusion - before, once reviewed, a confirmed Condition goes back to the
Order Placer, just as it does for a genomic variant:
flowchart LR
subgraph PSC2["Primary/Secondary Care Domain — Order Placer"]
A2["Suspected condition<br/>e.g. suspected AF"]
TOF2["Test Order Form"]
B2["Test ordered<br/>e.g. ECG/Holter monitor"]
F2["Confirmed Condition<br/>(back to Order Placer)"]
end
subgraph CARD["Cardiology Domain — Order Filler"]
C2["Result panel<br/>e.g. ECG trace"]
D2["FHIR Observation<br/>e.g. arrhythmia finding"]
E2["Diagnostic conclusion<br/>(DiagnosticReport.conclusion)"]
end
A2 --> TOF2 --> B2 --> C2 --> D2 --> E2 --> F2
Rather than every consuming system resolving these against the national service directly, this guide's resources carry identifiers that reference nationally-held data, while a local copy of the resource itself is still maintained where a genuine local need requires it. The three registers below follow the same shape as HL7 FHIR's own Administration Module registry pattern - Patient Registry, Service Provider Directory Registry and Clinical Categorization Registry - scoped down to what the UK's own national services actually provide, plus what stays genuinely local.
Analogous to FHIR's own Patient
Registry, but
scoped to just Patient and RelatedPerson - this guide has no need for the
generic Person/Group resources that page also shows.
Patient references NHS England's
Personal Demographics Service (PDS) - the UK's Master Patient Index (MPIP) -
via the patient's NHS Number - see NHS
Identifier. A local copy of
Patient is still maintained, rather than resolving PDS on every use,
because this guide also needs to support identifiers PDS itself doesn't
carry - CHI (Scotland) and HSC/HSNI (Northern Ireland) numbers, and
locally-assigned Medical Record
Numbers - see NHS
Identifier for how these are
represented together. The Regional Integration Engine (RIE) performs the
actual PDS check/enrichment - see Regional Integration Engine (RIE) - Order
Process and Report
Process.
flowchart LR
PDS[("PDS<br/>national Master Patient Index (MPIP)")]
Patient["Patient<br/>local copy - NHS Number,<br/>plus CHI/HSC/MRN PDS doesn't carry"]
RelatedPerson["RelatedPerson<br/>e.g. mother of a fetus,<br/>a family member"]
Patient -- "NHS Number" --> PDS
RelatedPerson --> Patient
Analogous to FHIR's own Service Provider Directory Registry, with each resource sourced from a different national service rather than one single directory:
PractitionerRole and OrganizationAffiliation are provided by NHS
England's centrally-held Organisation Data Service/Transfer (ODS/ODT) FHIR
API and its associated bulk downloads, via Organisation
Code (ODS Code) and
Practitioner Identifier
(GMP/GMC Number).HealthcareService is instead provided by a mix of Directory of Services
(DoS) APIs, which tend to be aligned to a particular technical service
(e.g. the NHS e-Referral Service, eRS), a particular order type (e.g. the
Electronic Prescription Service, EPS) or a clinical specialty, rather than
one single national HealthcareService directory.Endpoint has no direct NHS England equivalent used here, but Spine holds
an equivalent concept for routing technical endpoints.As with the Patient Registry above, the RIE performs this check/enrichment against the live ODT API rather than every consuming system doing so individually - see Regional Integration Engine (RIE) - Order Process and Report Process.
flowchart TB
subgraph National["National Care Directory Services"]
ODS[("ODS/ODT FHIR API<br/>+ bulk downloads")]
DoS[("Directory of Services (DoS) APIs<br/>aligned to a technical service (eRS),<br/>order type (EPS), or specialty")]
Spine[("Spine<br/>Endpoint equivalent")]
end
Organization["Organization"]
Practitioner["Practitioner"]
PractitionerRole["PractitionerRole"]
OrganizationAffiliation["OrganizationAffiliation"]
HealthcareService["HealthcareService"]
Endpoint["Endpoint"]
ODS --> Organization
ODS --> Practitioner
ODS --> PractitionerRole
ODS --> OrganizationAffiliation
DoS --> HealthcareService
Spine --> Endpoint
PractitionerRole --> Practitioner
PractitionerRole --> Organization
OrganizationAffiliation --> Organization
HealthcareService --> Organization
Analogous to FHIR's own Clinical Categorization
Registry -
EpisodeOfCare, Encounter, Account - but unlike the two registers above,
this one is not a national service: it is normally handled locally by
each NHS Trust's own PAS/EPR. In the UK, Account Number normally refers
to EpisodeOfCare.identifier - also known as the Hospital Spell
Identifier - see Hospital Provider Spell
Identifier. This
guide's own HospitalSpell profile
(built on Encounter, per the Entity Relationship
Diagram below) carries that same identifier
value, since no single national register of episodes/spells exists to
reference instead.
flowchart LR
Trust[("NHS Trust PAS/EPR<br/>(local - not a national register)")]
EpisodeOfCare["EpisodeOfCare<br/>Account Number / Hospital<br/>Spell Identifier"]
HospitalSpell["HospitalSpell<br/>(this guide's own Encounter<br/>profile, same identifier)"]
Trust --> EpisodeOfCare
Trust --> HospitalSpell
This is the basic model this guide is built on: an OrderingFacilityAndPractitioner
places a ServiceRequest (order) for a Patient, which references a
Specimen and produces a DiagnosticReport, with a HospitalSpell linking
orders and reports back to the episode of care they belong to. Both the order
and the report are extended with further detail beyond this basic model -
AskAtOrderQuestions for the order, ReportPanels and Results for the
report - see Archetype Questionnaires below.
erDiagram
OrderingFacilityAndPractitioner ||--|{ ServiceRequest : places
Patient ||--|{ ServiceRequest : subject
HospitalSpell ||--o{ ServiceRequest : links
ServiceRequest ||--o{ Specimen : contains
ServiceRequest ||--|{ DiagnosticReport : produces
Patient ||--|{ DiagnosticReport : subject
HospitalSpell ||--o{ DiagnosticReport : links
ServiceRequest ||--o{ AskAtOrderQuestions : "extended by"
DiagnosticReport ||--o{ ReportPanels : "extended by"
DiagnosticReport ||--o{ Results : "extended by"
ServiceRequest and DiagnosticReport are the two separate aggregates
(in the Domain-Driven Design
sense) this model is built around - each with its own extension mechanism.
This is deliberately a high-level (level 1) view - just the entities and how they relate. Field-level (level 2) diagrams, showing the actual attributes each entity carries, are on the two archetype Questionnaire pages below.
Every order/report relationship in this guide is a closed loop: something
requests work (a ServiceRequest), and something else closes that loop with
a result (usually a DiagnosticReport, sometimes a Test Result or a
report/clinic letter). The generic ServiceRequest/DiagnosticReport pair
in the Entity Relationship Diagram above
takes several different concrete shapes in genomics, depending on who is
placing the request and why - summarised below, with how
ServiceRequest.intent changes to reflect that.
| Order / Referral | Report / Result | Interaction(s) | Description | Data Model | Use Case(s) |
|---|---|---|---|---|---|
| Laboratory Order | Laboratory Report | LAB-1 / LAB-3 | The requesting clinician/system places a genomic test order directly with the laboratory; once testing is complete, the laboratory reports the result straight back to that same requester. This is the "root" of every closed loop below - every other pattern either sits underneath one of these, or (for a Referral) stands in place of one. | ServiceRequest.intent = order (or reflex-order, if this Laboratory Order was itself automatically generated by an upstream reflex decision, before LAB-1 is even sent); the Laboratory Report follows HL7 Europe Laboratory Report (plus the additional genomic content this IG itself defines) |
Regional Integration Engine (RIE), iGene Orders and Reports (Alder Hey, MFT, Liverpool), Whole Genome Sequencing (Proposed - Alder Hey, MFT, Liverpool), Histocompatibility and Immunogenetics (Clatterbridge to Histotrac) |
| Laboratory Order (Sub-Contracted) | Laboratory Report | LAB-35 / LAB-36 | The Order Filler cannot fulfil the Laboratory Order itself, so it forwards it as a new order to another laboratory (a different Genomic Laboratory Hub) - the same test the original requester asked for, just performed elsewhere. The result closes the loop back to the subcontracting lab, which remains responsible for the LAB-3 report to the original requester. | ServiceRequest.intent = filler-order - a new ServiceRequest, referencing the original order, created by the Order Filler rather than by the original requester; the Laboratory Report follows HL7 Europe Laboratory Report (plus the additional genomic content this IG itself defines) |
Distributed WGS (dWGS), StarLIMS / iGene Integration |
| Laboratory Order (Reflex Order) | Laboratory Report | LAB-35 / LAB-36 | The Order Filler automatically triggers a further test based on an earlier result, without any new request from the original requester - e.g. a pathology finding reflexing on to a genomic test. Uses the same LAB-35/LAB-36 sub-order transactions as a subcontracted order, but the trigger is a result, not a forwarding decision. | ServiceRequest.intent = reflex-order - a new ServiceRequest, created automatically, not requested by the original placer; the Laboratory Report follows HL7 Europe Laboratory Report (plus the additional genomic content this IG itself defines) |
Cheshire and Merseyside Pathology, Haemato-Oncology Diagnostic Pathway |
| Work Order | Test Result | LAB-4 / LAB-5 | Purely internal to the Order Filler: it splits its own Laboratory Order into one or more Work Orders to organise the actual analytical work (which analyser, which specimen aliquot), and the analyser/automation manager returns Test Results against that Work Order. Several Work Orders/Test Results can feed into a single Laboratory Report. | ServiceRequest.intent = instance-order - an internal instance of doing the analytical work, not a new order relationship with an external party; the Test Result follows HL7 FHIR Genomics Reporting and this IG's own Report Panels |
OMICS DSS Result Integration, BCR-ABL Monitoring (Cepheid ASTM to iGene), Cytogenetics and Haemato-Oncology Diagnostic Pathway |
| Referral | Discharge/Hospital Report | REF_I12 / ORU_R01 (or IHE 360X) |
Not a diagnostic test order at all - a referral for clinical assessment, genetic counselling and/or cascade testing, closed by a report/clinic letter rather than a DiagnosticReport-shaped lab result. Analysis-only in this IG - if ever modelled as a ServiceRequest, see Genetic Referrals - Referral Data Model. |
ServiceRequest.intent not currently modelled - FHIR's request-intent value set has no distinct "referral" code, so a referral ServiceRequest would most likely reuse order, the same as a Laboratory Order; the report/clinic letter back could instead follow HL7 Europe Hospital Discharge Report (HDR) as a FHIR-native alternative to ORU_R01 |
Genetic Referrals |
| (none - not order-driven) | Laboratory Report (Composition or PDF) | MDM_T02 or ITI-105 with the report in PDF or FHIR Document format (i.e. modern version of CDA/XD-LAB) | Not a closed loop at all - an aggregation, downstream of the closed loops above rather than a response to any of them: it collates one or more existing Laboratory Report(s) (DiagnosticReport) and their Test Results (Observations) into a single Composition-led document. See overview.md - Future Composition / Aggregated Laboratory Report. |
ServiceRequest.intent not applicable - no ServiceRequest is created or referenced, and Composition has no intent element; the document itself follows HL7 Europe Laboratory Report, while the aggregated Test Results it carries follow HL7 FHIR Genomics Reporting |
ctDNA NHS England Unified Genomic Record (UGR) - Phase 2, Regional Shared Care Records - Greater Manchester Care Record (GMCR), Regional Shared Care Records - Lancashire and South Cumbria |
| (none - wire-tap copy) | Management Information Copy (metadata only) | LAB-2 / LAB-3 | Not a closed loop referral at all - included here for completeness. A wire-tap copy of the existing LAB-2 (filler order) and LAB-3 (report) messages between the Order Filler and the original requester, sent on to a regional management information portal rather than being a request/response relationship in its own right. The clinical content (the PDF/result) is stripped before forwarding - the portal only needs to know that a test happened and when it was reported, for activity/turnaround-time reporting, not the clinical result itself. | ServiceRequest.intent not applicable - no new ServiceRequest is created; the copy follows the same FHIR Message O21/R01 shape as the LAB-2/LAB-3 interaction it copies, with clinical content removed |
NE&Y Management Information (ctDNA) |
Summary of the modelling differences:
order); a Sub-Contracted Order and a Reflex Order are
both created by the Order Filler itself, just for different reasons
(forwarding work it can't do, versus reacting to a result) - both use a
ServiceRequest.intent value that signals "this was not the original ask"
(filler-order, reflex-order); a Work Order is created by the Order
Filler too, but stays entirely internal, hence its own distinct
instance-order value rather than reusing filler-order.ServiceRequest.intent tracks position in the chain, not clinical
urgency or type of test - the same genomic test could arrive as order
(direct), filler-order (subcontracted) or reflex-order (reflexed), and
the FHIR resource shape doesn't otherwise change.DiagnosticReport - LAB-5 returns a
Test Result (which may be represented as Observations rather than a full
report), and a Referral closes with a report/clinic letter that may not be
lab-shaped at all - see HL7 Europe Hospital Discharge
Report as a possible FHIR-native
alternative.ServiceRequest/DiagnosticReport pair this page's Entity Relationship
Diagram is otherwise built around, and is
not yet backed by a profile in this IG.ServiceRequest
behind it and nothing for ServiceRequest.intent to describe.ServiceRequest.intent says what kind of order a given ServiceRequest
is, but not which original Laboratory Order it belongs to - that's a separate
job, done by ServiceRequest.requisition (HL7 v2 ORC-4, Placer Group
Number - see Order Group Number).
A Sub-Contracted Order, a Reflex Order and a Work Order are each their own
ServiceRequest resource, with their own identifier and their own intent
value (filler-order, reflex-order, instance-order respectively - see
the table above) - but its requisition most often carries the original
Laboratory Order's own Filler Order Number (Order
Identifier, ORC-3) - the
identifier the Order Filler itself already assigned when it first received
that order - rather than a new group number invented for the child order. It
may instead carry the original order's Placer Order Number (ORC-2)
where that's what the receiving system expects, but Filler Order Number is
the more common choice, since it's the identifier already under the Order
Filler's own control. Either way, this is what lets every order in the
family be found and correlated back to the one original Laboratory Order,
however many sub-contract/reflex/work-order hops it went through.
The same logic applies one level further up the chain, for Genetic
Referrals - Referral Data Model:
a Referral's own Referral Number - Placer (RF1-6, analogous to a Laboratory
Order's Placer Order Number) or Filler (analogous to its Filler Order
Number) - becomes the requisition on any Laboratory Order(s) that result
from that referral, the same way a Laboratory Order's own number becomes the
requisition on any Sub-Contracted Order, Reflex Order or Work Order beneath
it.
flowchart TB
REF["Referral<br/>identifier (Placer/Filler Referral Number) = REF-001"]
LO["Laboratory Order<br/>intent = order<br/>requisition = REF-001<br/>identifier[OrderFillerNumber] (Filler) = FIL-001"]
SC["Sub-Contracted Order<br/>intent = filler-order<br/>requisition = FIL-001"]
RO["Reflex Order<br/>intent = reflex-order<br/>requisition = FIL-001"]
WO["Work Order<br/>intent = instance-order<br/>requisition = FIL-001"]
REF -.->|"requisition references<br/>Referral Number<br/>(where the order results<br/>from a referral)"| LO
LO -.->|"requisition references original<br/>order's Filler Order Number<br/>(most often)"| SC
LO -.->|"requisition references original<br/>order's Filler Order Number<br/>(most often)"| RO
LO -.->|"requisition references original<br/>order's Filler Order Number<br/>(most often)"| WO
Distributed WGS (dWGS) uses
requisition slightly differently again - there, several sibling
participants' sub-orders (Proband, Family Member(s)) each get their own
new ServiceRequest, and all of them share one requisition value
assigned by the Requesting Genomic Laboratory for the referral as a whole,
rather than each one referencing back to a single parent order's own Filler
Order Number.
ServiceRequest.requisition links one order to the order it was derived
from, within a single family descending from one Laboratory Order (or
Referral). Two other identifiers link work together in a different way -
correlating genuinely separate, independently-placed orders that happen to
share the same patient episode or the same physical specimen, potentially
across different diagnostic services entirely (genomics, pathology,
radiology):
ServiceRequest.encounter/DiagnosticReport.encounter point to the same
HospitalSpell resource. Every Referral, Episode/Stay and Laboratory
Order placed by any diagnostic service during that one hospital spell can
be found by following that shared reference back.Specimen.accessionIdentifier) - links Laboratory Orders together
whenever the same physical specimen is reused across more than one
order (e.g. a single blood draw used for both a pathology test and a
genomics test) - each order's ServiceRequest.specimen references the
same Specimen resource, or its Specimen.accessionIdentifier value is
repeated across separately-tracked Specimen resources per service.This basic model is deliberately abstract - it doesn't yet say which specific
fields an order or report needs, or how those fields map onto HL7 v2 segments
and FHIR profiles. That detail is added by two archetype Questionnaires,
one for each side of the ServiceRequest/DiagnosticReport relationship
above:
flowchart LR
M["Basic model<br/>(this page)"] --> O["Questionnaire-<br/>GenomicTestOrder"]
M --> R["Questionnaire-<br/>GenomicTestReport"]
O --> OAOE["Ask At Order Entry<br/>Questionnaires<br/>(derived/extended)"]
R --> RP["Report Panels<br/>(derived/extended)"]
O --> FHIRV2O["FHIR ServiceRequest /<br/>HL7 v2 OML_O21"]
R --> FHIRV2R["FHIR DiagnosticReport /<br/>HL7 v2 ORU_R01"]
Answering an Ask At Order Entry or Report Panel Questionnaire produces
Observation resources - the same resource type on both sides, just
referenced back from a different aggregate:
erDiagram
AskAtOrderQuestions ||--o{ Observation : "answers become"
ServiceRequest ||--o{ Observation : supportingInfo
ReportPanels ||--o{ Observation : "answers become"
Results ||--o{ Observation : "are also"
DiagnosticReport ||--o{ Observation : result
Observation,
which the order references via ServiceRequest.supportingInfo - see the
Observation entity
on that page's own level-2 diagram.On the report side, a Report Panel finding is also an Observation, which
the report references via DiagnosticReport.result. Genomic
Results (the
underlying HL7 FHIR Genomics Reporting profiles) are themselves Observation
resources too, and are referenced from DiagnosticReport.result the same
way - whether a given finding came from a Report Panel Questionnaire or
directly from a Genomics Reporting profile, it ends up in the same place.
derivedFrom/extend this common core - see Order Entry
Questions for
the full list. ServiceRequest itself also splits into OriginalOrder and
FillerOrder - see Original Order, Instance and Filler
Orders.derivedFrom/extended from this common core - see Report
Panels for the full
list.Each archetype's own page carries the field-by-field detail this summary page doesn't: which HL7 FHIR profile and HL7 v2 segment each field maps onto, ready to implement against.