Defining your Diagnostic Catalog | Medplum
On this page
A diagnostic catalog contains all the pertinent information about the diagnostic services you provide, including your analytes, reference ranges, panels, specimen requirements, and laboratory procedures.
Having a well-defined, structured catalog enables:
- Robust access controls
- Higher quality analytics
- Smoother CLIA/CAP certification
- Streamlined billing
At the end of this guide, you will understand how to represent your diagnostic catalog in FHIR at a detailed level an example of which is shown in this diagram.
Define your clinical observations
The first step in building your catalog is to define which clinical quantities, or "observations", you will measure. In a lab context, an example of a clinical observation would be an HBA1c percentage.
The Observation is the primary operational resource used to record a clinical quantity for a specific patient. ObservationDefinition is the corresponding administrative counterpart, and is used to define how an Observation should be measured, interpreted, and reported.
Example: Blood Sodium Level
{
resourceType: 'ObservationDefinition',
id: 'observation-blood-sodium',
code: {
coding: [
{
system: LOINC,
code: '2947-0',
display: 'Sodium [Moles/volume] in Blood',
},
],
},
preferredReportName: 'Sodium Level',
quantitativeDetails: {
unit: {
coding: [
{
system: UCUM,
code: 'mmol/L',
display: 'millimoles per liter',
},
],
},
decimalPrecision: 2,
},
qualifiedInterval: [
{
condition: 'Normal',
range: {
low: {
value: 135,
unit: 'mmol/L',
},
high: {
value: 145,
unit: 'mmol/L',
},
},
},
],
};
Define your specimens
In the context of laboratory use cases, it's essential to recognize that observations are based on samples extracted from patients, known as "specimens".
Example: Capillary Blood Sample
{
resourceType: 'SpecimenDefinition',
id: 'fingerprick-capillary-blood',
typeCollected: {
coding: [
{
system: SNOMED,
code: '122554006',
display: 'Capillary Blood Specimen',
},
],
},
collection: [
{
coding: [
{
system: SNOMED,
code: '278450005',
display: 'Finger-prick sampling',
},
],
},
],
typeTested: [
{
preference: 'preferred',
container: {
type: {
coding: [
{
system: SNOMED,
code: '467989009',
display: 'Capillary blood collection tube, no-additive',
},
],
},
},
},
],
};
Define your services
The next step is to roll up your individual tests into orderable services that your patients can order.
Example: Men's Health Panel
{
resourceType: 'PlanDefinition',
id: 'example-lab-service-mens-health',
status: 'active',
url: 'http://example.org/PlanDefinition/lab-service-mens-health',
identifier: [
{
use: 'official',
value: 'mens_health_panel_test',
},
],
name: 'mens-health-panel',
title: "Men's Health Panel",
description: "Men's health-related laboratory tests",
type: {
coding: [
{
system: 'http://hl7.org/fhir/uv/order-catalog/CodeSystem/laboratory-service-definition-type',
code: 'panel',
display: 'collection of tests and panels performed on one or more in vitro biologic specimens',
},
],
},
action: [
{
code: [
{
coding: [
{
system: LOINC,
code: '41018-3',
display: 'Testosterone.free+weakly bound [Moles/volume] in Serum or Plasma',
},
],
},
],
definitionCanonical: 'http://example.org/lab-procedure-testosterone-serum',
},
{
code: [
{
coding: [
{
system: LOINC,
code: '55231-5',
display: 'Electrolytes panel - Blood',
},
],
},
],
definitionCanonical: 'http://example.org/lab-procedure-electrolytes-panel-blood',
},
],
useContext: [
{
code: {
system: 'http://terminology.hl7.org/CodeSystem/usage-context-type',
code: 'task',
},
valueCodeableConcept: {
coding: [
{
system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
code: 'LABOE',
display: 'laboratory test order entry task',
},
],
},
},
],
};
Define your lab procedures
Now that you have represented your service menu as PlanDefinitions , you will use ActivityDefinition resource to define your corresponding procedures to fulfill each service.
Example: Electrolyte Panel
{
resourceType: 'ActivityDefinition',
id: 'lab-procedure-electrolytes-panel-blood',
status: 'active',
name: 'electrolytes-panel-blood-measurement-procedure',
title: 'Procedure - Electrolytes panel measurement in blood',
url: 'http://example.org/lab-procedure-electrolytes-panel-blood',
identifier: [
{
use: 'official',
value: 'electrolytes_panel_test',
},
],
code: {
coding: [
{
system: LOINC,
code: '55231-5',
display: 'Electrolytes panel - Blood',
},
],
},
kind: 'ServiceRequest',
observationResultRequirement: [
{ reference: 'ObservationDefinition/observation-blood-potassium', },
{ reference: 'ObservationDefinition/observation-blood-chloride', },
{ reference: 'ObservationDefinition/observation-blood-carbon-dioxide', },
{ reference: 'ObservationDefinition/observation-blood-sodium', },
],
specimenRequirement: [{ reference: 'SpecimenDefinition/fingerprick-capillary-blood' }],
};
Querying your catalog
You can query all PlanDefinitions that represent a laboratory procedure using TypeScript, CLI, or cURL.
TypeScript Example
await medplum.searchResources('PlanDefinition', { context: 'LABOE' });
cURL Example
curl 'https://api.medplum.com/fhir/R4/PlanDefinition?context=LABOE' \
-H 'authorization: Bearer $ACCESS_TOKEN' \
-H 'content-type: application/fhir+json' \
Putting it all together
Now we'll put all these concepts together to model a basic lab catalog.