Common CQL Artifacts for FHIR (US-Based)
2.0.0 - Informative 2
Common CQL Artifacts for FHIR (US-Based), published by HL7 International / Clinical Decision Support. This guide is not an authorized publication; it is the continuous build for version 2.0.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/us-cql-ig/ and changes regularly. See the Directory of published versions
| Page standards status: Informative |
The FHIR Observation resource supports capturing a variety of information in a medical record, including simple name/value pair assertions, as well as multi-component observations, and logical groupings of observations. US Core defines several observation profiles to support a variety of use cases, including:
US Core defines the base US Core Vital Signs Profile to represent vital signs generally, as well as specific vital signs for many common vital signs such as Weight, Height, BMI, and Blood Pressure.
US Core defines US Core Observation Clinical Result Profile to represent clinical test results. Note that the laboratory test result profile is derived from the clinical result profile (i.e. all laboratory results are clinical results).
US Core defines US Core Laboratory Result Observation to record laboratory observations.
Observation codes will be LOINC. Result values will generally be represented in different ways, according to the type of lab result. The LOINC code itself will often describe the expected representation of possible values for a given observation or test result.
US Core defines US Core Screening Assessment to record the result of screening assessment tools.
US Core defines US Core Simple Observation to record observations not otherwise classified as clinical tests, laboratory results, vital signs, screening assessments, or other specific profiles defined in US Core.
US Core defines the following additional profiles for capturing specific types of observations:
Regardless of which profile is used, the Observation resource defines the following modifier elements:
In addition to being a modifier, this element is required with a required binding. The USCoreCommon library defines several functions for determining the status of an observation, as discussed in the Status section below.
USCore defines the following mandatory search parameters:
In addition, the following optional search parameters are described:
NOTE: For discussion on how to manage search parameters with terminology, see the Terminology Considerations discussion in the Architectural Guidance topic.
NOTE: For discussion on how to manage optional search parameters, see the Performant Data Access discussion in the Architectural Guidance topic.
Generally, new versions of USCore since 3.1.1 have introduced additional profiles, but have not impacted representation of existing profiles. As of 6.1.0, there are generally:
The FHIRCommon library defines functions and terminology declarations to support determining status of an observation:
isResulted(): returns true if the status is final, amended, or correctedisFinal(): Returns true if the status is finalisAmended(): Returns true if the status is amendedisCorrected(): Returns true if the status is correctedAs well as for filtering lists of observations with a given status:
resulted(): returns Observations in the given list with a status of final, amended, or correctedfinal(): Returns Observations in the given list with a status of finalamended(): Returns Observations in the given list with a status of amendedcorrected(): Returns Observations in the given list with a status of corrected.hasCategory(Code): Returns true if the given observation has the given category.isSocialHistory(): Returns true if the given observation has a category of social history.isVitalSign(): Returns true if the given observation has a category of vital sign.isImaging(): Returns true if the given observation has a category of imaging.isLaboratory(): Returns true if the given observation has a category of laboratory.isProcedure(): Returns true if the given observation has a category of procedure.isSurvey(): Returns true if the given observation has a category of survey.isExam(): Returns true if the given observation has a category of exam.isActivity(): Returns true if the given observation has a category of activityNote that the interpretation element of an observation may not be present, and may not be coded as expected. Care must be taken in the use of this element to ensure that data conforms with the expectations of the logic.
.positive(): Returns Observations in the given list that have an interpretation of positive.negative(): Returns Observations in the given list that have an interpretation of negative.during(Encounter): Returns Observations in the given list whose effective time is during the given Encounter, accurate to the minute.chronologically(): Returns Observations chronologically by their effective time.chronologicallyAfter(Observation): Returns Observations chronologically by their effective time, on or after the start of the effective time of the given ObservationNOTE: We are seeking implementer feedback on timing functions specifically: What additional timing functions would be useful?
Note that for the specific timing of specimen collection time, although the FHIR Specimen resource defines a collection time element, that element is not indicated as must support in the US Core Specimen profile, and so is not likely to be available for use. In addition, the effectiveTime element of the Observation resource is specifically documented as the "physiologically relevant time", and "usually either the time of the procedure or specimen collection". To allow for the specimen collection time to be used, logic can prefer that element if present, falling back to the observation effective time if for laboratory results. As with all clinical logic patterns, when this method is used, care should be taken to ensure that the data on which the logic will be run conforms to this usage pattern.
As an example, consider the index date of an infection using specimen collection time:
define "Bacteremia or Fungemia Result With Specimen":
from
"Bacteremia or Fungemia Result" R,
[Specimen: "Specimen Type - Blood"] S
where R.specimen.references(S)
return {
result: R,
specimen: S
}
The index date of a set of results could then be determined by:
indexDate: Min(
results R
return Coalesce(
start of R.specimen.collection.collected.toInterval(), // Specimen.collection.collected, if present
start of R.result.effective.toInterval() // Fallback to Observation.effective
)
)
Note that the specimen collection type here still needs to be identified (using the "Specimen Type - Blood" value set in this case), as it can usually not be reliably inferred from the test type.
In addition, the USCoreElements library defines expressions for accessing the various USCore observation profiles:
In general, the expressions to retrieve observations for a particular profile include the .resulted() function to ensure only final, amended, or corrected observations are returned. Each profile typically provides an All Statuses variant that returns observations regardless of status, along with a status-filtered expression built on top of it.
Clinical test results (including imaging results) in US Core use the ObservationClinicalResult profile. By default, clinical test results in US Core are characterized by the code element.
define ObservationClinicalResult:
["Observation Clinical Result Profile"] O
where O.isResulted()
Note that observations associated with imaging are expected to represent specific measurements obtained from imaging. See the Imaging Procedures discussion for more information.
NOTE: US Core 5 defined two different profiles for clinical results, one for test results, and one for imaging results. These profiles were combined in US Core 6 in the clinical result profile.
US Core allows for the presence of pregnancy to be represented in multiple resources. The US Core profile Pregnancy Status allows for the representation of pregnancy as an Observation. However, pregnancy information may also be represented in a laboratory test result, an encounter diagnosis, or a problem list item.
As an example, to determine if an individual is pregnant at any point during a measurement period, the following approach may be used to consider all four approaches:
valueset "Pregnancy Condition Codes": 'TBD'
valueset "Pregnancy Test Codes": 'TBD'
codesystem "SNOMEDCT": 'http://snomed.info/sct'
codesystem "Interpretation Codes": 'http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation'
code "Pregnant": '77386006' from "SNOMEDCT" display 'Pregnant (finding)'
code "Positive": 'POS' from "Interpretation Codes" display 'Positive'
define "Positive Pregnancy Observation":
["Observation Pregnancy Status Profile"] PregnancyStatus
where PregnancyStatus.status = 'final'
and PregnancyStatus.value ~ "Pregnant"
and PregnancyStatus.effective.toInterval() overlaps "Measurement Period"
define "Positive Pregnancy Test Result":
["Laboratory Result Observation Profile": "Pregnancy Test Codes"] PregnancyTest
where PregnancyTest.status = 'final'
and PregnancyTest.value ~ "Positive"
and PregnancyTest.effective.toInterval() overlaps "Measurement Period"
define "Pregnancy Encounter Diagnosis":
[ConditionEncounterDiagnosisProfile: "Pregnancy Condition Codes"] EncounterDiagnosis
with "Encounters" Encounter
such that EncounterDiagnosis.encounter.references(Encounter)
define "Pregnancy Condition":
[ConditionProblemsHealthConcernsProfile: "Pregnancy Condition Codes"] Condition
where Condition.clinicalStatus ~ "active"
and Condition.verificationStatus ~ "confirmed"
and Condition.prevalenceInterval() overlaps "Measurement Period"
define IsPregnant:
exists "Positive Pregnancy Observation"
or exists "Positive Pregnancy Test Result"
or exists "Pregnancy Condition"
or exists "Pregnancy Encounter Diagnosis"
Note that the examples above assume the existence of a ValueSet "Pregnancy Condition Codes" containing codes pertaining to conditions while pregnant.
In addition, the "Pregnancy Encounter Diagnosis" criteria is assuming the existence of an "Encounters" expression that constrains the encounter diagnoses to measure intent as well as the measurement period.
If a use case requires the use of prevalence period (onset and/or abatement time for a condition), it will require the use of condition profiles because onset and/or abatement times are only available in the Condition resource.
The Pregnancy Intent profile sets minimum expectations for the Observation resource to record, search, and retrieve the "patient's intent to become pregnant" over the next year.
codesystem "LOINC": 'http://loinc.org'
code "Pregnancy intention in the next year - Reported": '86645-9'
code "Yes, I want to become pregnant": 'LA26438-4'
define "Positive Pregnancy Intent":
["Observation Pregnancy Intent Profile"] PregnancyIntent
where PregnancyIntent.effective.toInterval() during "Measurement Period"
and PregnancyIntent.value ~ "Yes, I want to become pregnant"
This example illustrates logic for identifying three consecutive negative "stick tests":
define StickTest:
[Observation: "Stick Test Codes"] O
where O.status in { 'final', 'amended', 'corrected' }
define "First Three Stick Tests In Encounter":
Take(StickTest.during(Encounter).chronologically(), 3)
define "Three Consecutive Negative Stick Tests":
Count("First Three Stick Tests In Encounter".negative()) = 3
NOTE: The use of the term consecutive here means there are no intervening positive tests, rather than that they are strictly sequential chronologically (i.e. with no gaps in time in between).
In addition, this expression can be parameterized with current context (for example, a triggering Observation supplied as a parameter named ContextObservation) with:
parameter ContextObservation Observation
define "Three Consecutive Negative Stick Tests After Context":
Count(Take(StickTest.chronologicallyAfter(ContextObservation), 3).negative()) = 3
NOTE: Content for this page was adapted from the QICore Authoring Patterns - Laboratory Result topic.