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:
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.
Follow the guide step-by-step to build up the components shown:
Define your clinical observations
Define your specimens
Define your orderable services
Define your laboratory procedures
Our recommendations are informed by the Order Catalog Implementation Guide implementation guide, which developed with contributions from Labcorp, Quest Diagnostics, and other industry leaders.
Sample Data
You can download the examples in this guide as a FHIR bundle here, and upload them to your project using the Medplum Batch Upload Tool
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 an HBA1c percentage. For a given patient, this observation might have a value such as 5.3%.
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.
Patient-friendly name used for reporting the observation result.
Sodium Level
Key amongst these is the qualifiedInterval element, which is used to define how results should be interpreted. See our guide on reference ranges for more information.
In the context of laboratory use cases, it's essential to recognize that observations are based on samples extracted from patients, known as "specimens". A well constructed diagnostic catalog links the specimen requirements for each test to the test definition to provide lab operators a complete picture of the collection process.
The Specimen resource resource refers to a specific specimen, like a tube of blood, usually belonging to a patient. As with Observations, Specimen has a corresponding administrative resource, called SpecimenDefinition.
SpecimenDefinition describes the type of specimen material to be collected, as well as details about the collection process, storage, handling, and preparation for testing.
The SpecimenDefinition allows you to specify many details about your specimen, but the most relevant are:
Whether this collection output is the preferred form, or an alternate
preferred | alternate
preferred
typeCollected vs typeTested
Material that is collected from a patient may be split up, prepared, and handled different ways. The typeTested elements describe all the potential outputs of the collection process, and contains a lot more information about the containment vessel, rejection criteria, and temperature restrictions for each output.
Example: Capillary Blood Sample
The following examples defines a fingerprick blood sample that is distributed into two collection tubes: a red cap and a green cap.
The next step is to roll up your individual tests into orderable services that your patients can order. These can be thought of as your diagnostic "product offerings," and are commonly known as "panels" in a lab context.
These products are represented as PlanDefinition resources. The PlanDefinition is primarily a grouping resource that stores metadata about the service and references the ActivityDefinitions you will create in the next section.
In the next section, we'll learn more about the PlanDefinition.action element, which represents the lab procedures used to fulfill the diagnostic service order.
Now that you have represented your service menu as PlanDefinitions , you will use ActivityDefinition resource to define your corresponding procedures to fulfill each service.
While PlanDefinitions are patient facing resources, ActivityDefinitions are primarily used by lab operators to aid them in fulfilling the order. To link the two, each entry in PlanDefinition.action references an individual lab procedure, with PlanDefinition.action.definitionCanonical referencing an ActivityDefinition resource for details.
Note: Canonical References
PlanDefinitions and ActivityDefinitions are linked via what is known as a canonical reference, not a standard reference as with most other resources. PlanDefinition.action.definitionCanonical is a URL string, that must match the url field of the ActivityDefinition it references.
There is a bit of an art to determining divide the individual tests into procedures, and it requires an understanding of your lab operations. Some considerations to help guide you:
Are there reusable groups of tests that are always performed together?
Known as the "canonical URL" for the resource. This should be a fully qualified, globally unique URL.
FHIR recommends for many administrative resources (aka "definitional resources") to have canonical URLs to provide a globally unique business identifier. Read more about canonical URLs here
A recommended pattern for constructing this URL is: http://[your-company-url]/ActivityDefinition/[test-name]
In most cases, each service will only require a single laboratory procedure. In these cases, you will only need a single PlanDefinition.action and ActivityDefinition, representing the main operational procedure performed to fulfill this laboratory service.
Example: Electrolyte Panel
In the example below, a patient can order an Electrolyte Panel, which is a single laboratory procedure
Patient-facing service
{ resourceType:'PlanDefinition', id:'example-lab-service-electrolytes-panel-blood', status:'active', // Canonical URL url:'http://example.org/PlanDefinition/lab-service-electrolytes-panel-blood', // Business Identifier identifier:[ { use:'official', value:'electrolytes_panel_test', }, ], // Machine-friendly name name:'electrolytes-panel-blood-measurement', // Human-friendly name title:'Electrolytes panel measurement in blood', description:'Electrolytes panel measurement on blood specimen', // 'test' or 'panel' 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', }, ], }, // This service contains a single action since only one procedure is required for fulfillment action:[ { code:[ { coding:[ { system:LOINC, code:'55231-5', display:'Electrolytes panel - Blood', }, ], }, ], definitionCanonical:'http://example.org/lab-procedure-electrolytes-panel-blood', }, ], // 'LABOE' indicates that this PlanDefinition is represents a Lab service 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', }, ], }, }, ], };
In some cases, a product offering might embed multiple procedures that are reused across service offerings. In these cases, we can define multiple entries in PlanDefinition.action, each with their own ActivityDefinition.
This allows you to reuse the data definition of your procedures, while allowing you to compose them into different patient-facing product offerings.
Example: Men's Health Panel
This PlanDefintion reuses the Electrolyte Panel from the previous example, and but adds a free testosterone test.
Patient-facing service
{ resourceType:'PlanDefinition', id:'example-lab-service-mens-health', status:'active', // Canonical URL url:'http://example.org/PlanDefinition/lab-service-mens-health', // Business Identifier identifier:[ { use:'official', value:'mens_health_panel_test', }, ], // Machine-friendly name name:'mens-health-panel', // Human-friendly name title:"Men's Health Panel", description:"Men's health-related laboratory tests", // 'test' or 'panel' 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', }, ], }, }, ], };
Beyond flat lists of procedures, FHIR PlanDefinitions can be used to represent sub-procedures, mutually exclusive groups of procedures, reflex tests, and other complicated arrangements.
These advanced scenarios are out of scope for this guide, but you can check out the this implementation guide for examples of how these might be implemented
Another common query is to get all the ObservationDefinition and SpecimenDefinitions in a single service. Unfortunately, there is currently no way to do this using a single query. However, this can be done in two parts:
Query all ActivityDefinitions for a given PlanDefinition using _include directive