Skip to content

Authoring Patterns QICore v5.0.0

Michael Holck edited this page Apr 9, 2024 · 16 revisions

Authoring Patterns - QICore v5.0.0

This page provides discussion and best-practice recommendations for authoring patterns for accessing patient information in FHIR and CQL. For general conventions and guidance regarding the use of FHIR and CQL, refer to the Using CQL topic in the Quality Measure IG.

Feedback on the patterns and discussion here can be provided by submitting a New Issue to this repository.

QICore Information Model Overview

HL7 Fast Healthcare Interoperability Resources (FHIR) is a platform specification for exchanging healthcare data. FHIR defines a core information model that can be profiled for use in a variety of applications across the healthcare industry. These profiles are defined in Implementation Guides that provide constraints on the ways that FHIR resources can be used in to support interoperability (i.e. the ability of both sides of an interaction to correctly interpret the information being exchanged).

In the United States, the US Core Implementation Guide defines a floor for that interoperability, enabling a broad range of clinical and administrative use cases. For quality improvement use cases, such as decision support and quality measurement, the QI Core Implementation Guide extends US Core to support additional information used for quality improvement. For the most part, US Core covers the data required, but some use cases, such as documentation of events that did not occur, require additional profiles.

Clinical Quality Language(CQL) is high-level, domain-specific language focused on clinical quality and targeted at measure and decision support artifact authors.

To simplify the expression of logic in quality improvement artifacts, CQL can be authored directly against the information model defined by the QI Core profiles. In the simplest terms, that information model provides:

  1. Patient - Representation of patient demographic and basic characteristics
  2. Encounters - Encounters between a patient and healthcare providers, typically taking place at a facility or virtually
  3. Observations - Facts about the patient such as lab results, vital signs, social history, etc.
  4. Conditions - Conditions the patient has (or does not have)
  5. Allergies - Allergies and intolerances the patient has (or does not have)
  6. Medications - Information related to medications the patient is prescribed and/or using
  7. Procedures - Information related to procedures ordered and/or performed for the patient
  8. Devices - Information related to devices the patient is using and/or has been prescribed
  9. Immunizations - Information related to immunizations the patient has received or been recommended
  10. Communication - Information related to communications with or about the patient

NOTE: The information in this page specifically uses the 5.0.0 version of QICore, which depends on the 5.0.1 version of USCore, and both of which are based on the R4 version 4.0.1 of FHIR.

The following sections provide specific examples of best practices for accessing information in each of these high-level areas.

Patient

QICore defines a QICore Patient profile that extends the USCore patient.

Patient age

Patient information includes the birth date, and CQL provides a built-in function to calculate the age of a patient, either current age (i.e. as of now), or as of a particular date. In quality improvement artifacts, age is typically calculated as of a particular date such as the start of the measurement period:

define "Patient Age Between 50 and 75":
  AgeInYearsAt(date from start of "Measurement Period") between 50 and 75

NOTE: The AgeInYearsAt function in CQL uses the data model (QICore in this case) to understand how to access the patient's birth date information. NOTE: CQL supports age calculation functions using both Date and DateTime values. In both cases the function is shorthand for a date/datetime duration calculation. If the DateTime overloads are used, note that the timezone offset is considered and there may be edge cases that result in unexpected results, depending on how large the timezone offset is from the execution timestamp. To avoid these edge cases, best practice is to use the date from extractor as shown in the above pattern to ensure the Date calculation is used.

Patient gender

Patient gender in FHIR is represented using codes from the AdministrativeGender code system:

define "Patient Is Male":
  Patient.gender = 'male'

NOTE: Terminology-valued elements in FHIR resources are bound to value sets. The gender element is an example of a required binding, which means that only the codes in that binding are allowed to be used. This is why the logic here can be specific about comparing to the actual string 'male'. In general, terminology-valued elements should be compared using terminology operators. For more information see the Using Terminology topic in the Quality Measure IG.

Patient race and ethnicity

US Core defines extensions for representing the race and ethnicity of a patient using the CDC's race and ethnicity codes. When authoring using QICore, these extensions can be accessed directly on the patient using the "slice name" of the extension:

define "Patient Race Includes Alaska Native":
  Patient P
    where exists (P.race.ombCategory C where C ~ "American Indian or Alaska Native")
      and exists (P.race.detailed C where C ~ "Alaska Native")

NOTE: CQL uses the data model (QICore in this case) to understand how to access patient information using the Patient definition. This definition is available in Patient contexts.

Encounters

QICore defines an Encounter profile to model any encounter between a patient and any number of providers in any setting, including virtual.

NOTE: For background information on accessing clinical information with CQL, see the Retrieve topic in the CQL specification.

Office visit encounters

By default, encounters in QICore are characterized by the type element, which is typically associated with a value set to limit the set of encounters returned to those that a code in the given value set. For example:

define "Office Visit Encounters":
  [Encounter: "Office Visit"]

Accessing Encounters with a Direct-reference code

Reviewed 2023-07-25

The type element of Encounters is plural (or multi-cardinality), meaning that a given Encounter may have multiple types associated with it. When using value sets such as the "Office Visit" example above, the retrieve resolves using the List overload of the in(ValueSet) operator in CQL. However, when attempting to use a direct-reference code, there is no overload of the Equivalent (~) operator to support the comparison.

This issue is being reviewed and may result in a specification or tooling change to support this use case (see Translator Issue 1181). However, at this time there are two possible workarounds:

Define a value set containing the required code and use that value set to perform the retrieve Use an equivalent where clause with an exists to retrieve the expected results, as shown in the below example: define "Office Visit Encounters By Code": [Encounter] E where exists ((E.type) T where T ~ "Office Visit Code") Note that this latter workaround will typically result in an unrestricted data requirement for Encounters. For this reason, best-practice is to use the first workaround

Encounters by class

Reviewed 2023-02-16

The QICore profile also supports characterizing encounters by the class element, which is used to categorize encounters more broadly than the type element, using the ActEncounterCode value set. For example:

define "Virtual Encounters":
  [Encounter: class ~ QICoreCommon."virtual"]

Note that although QDM-based eCQMs have typically used a type-based approach to filtering encounters, because class is a required element in USCore, we propose using class to filter encounters first, unless measure intent needs to search for encounters by type across classes. Additional filtering may be required beyond the class to limit encounters based on specialty, for example:

define "Opthalmology Encounter Codes":
  [Encounter: class in "Inpatient Encounter Classes"] InpatientEncounter
    where InpatientEncounter.type in "Opthalmology Encounter Codes"

Completed encounters in a period

Reviewed 2023-02-21

Encounters often need to be filtered based on status and period, for example:

define "Completed Encounters During the Measurement Period":
  [Encounter: "Office Visit"] OfficeVisit
    where OfficeVisit.status = 'finished'
      and OfficeVisit.period during "Measurement Period"

Encounters with a certain length

The CQMCommon library defines a lengthInDays() function that calculates the difference in days between the start and end of a period. For example, to filter encounters by the duration of stay:

define "Non-Elective Inpatient Encounter Less Than 120 Days":
  ["Encounter": "Non-Elective Inpatient Encounter"] NonElectiveEncounter
    where NonElectiveEncounter.period.lengthInDays() <= 120

Other durations can also be calculated, for example:

define "Non-Elective Inpatient Encounter Over 24 Hours":
  ["Encounter": "Non-Elective Inpatient Encounter"] NonElectiveEncounter
    where duration in hours of NonElectiveEncounter.period >= 24

NOTE: For ongoing encounters, the end of the period is often not specified, which will typically be interpreted in CQL as an ongoing period, resulting in large duration values.

Hospitalization

For inpatient encounters, measures and rules often need to consider total hospitalization period, including any immediately prior emergency department and/or observation status encounters. To facilitate this, the CQMCommon library defines a hospitalizationWithObservation() function that returns the total duration from admission to the emergency department or observation to the end of the inpatient encounter. For example:

define "Comfort Measures Performed":
  ["Procedure": "Comfort Measures"] InterventionPerformed
    where InterventionPerformed.status in { 'completed', 'in-progress' }

define "Encounter with Comfort Measures Performed during Hospitalization":
  "Non-Elective Inpatient Encounter Less Than 120 Days" Encounter
    with "Comfort Measures Performed" ComfortMeasure
      such that start of ComfortMeasure.performed.toInterval() during Encounter.hospitalizationWithObservation()

Conditions

QICore defines the ConditionProblemsHealthConcerns profile to represent information about patient problems and health concerns, and the ConditionEncounterDiagnosis profile to represent diagnoses indicated as part of an encounter.

As an aside, whether expressions in general should use the various elements of a profile depends entirely on measure or rule intent. However, there are some general guidelines that should be followed to ensure correct expression and evaluation of CQL.

To begin with, all elements in FHIR profiles have a cardinality that determines whether and how many values may appear in that element. Cardinality is expressed as a range, typically from 0 or 1 to 1 or *. A cardinality of 0..1 means the element is optional. A cardinality of 1..1 means the element is required. A cardinality of 0..* means the element may appear any number of times, and a cardinality of 1..* means the element must appear at least once, but may appear multiple times. Although other cardinalities are possible, those described above are the most common.

NOTE: Cardinality determines whether and how many values may appear for a given element, but the fact that an element is specified as required (e.g. 1..1) does not mean that expressions using that profile must use that element.

In addition, elements in FHIR profiles may be marked must support, meaning that implementations are required to provide values for the element if they are present in the system. To ensure expression logic can be evaluated correctly, expressions must only use elements that are marked must support. For a complete discussion of this aspect, refer to the MustSupport Flag topic in the QICore Implementation Guide.

And finally, elements in FHIR profiles may be marked as modifier elements, meaning that the value of the element may change the overall meaning of the resource. For example, the clinicalStatus element of a Condition is a modifier element because the value determines whether the Condition overall represents the presence or absence of a condition. As a result, for each modifier element, authors must carefully consider whether each possible value would impact the intent of the expression.

To summarize, cardinality determines whether data will be present at all, must support determines whether the element can be used in an expression, and modifier elements must always be considered to determine the impact of possible values of the element on the result of the expression. End of aside.

Active conditions

By default, Condition resources are characterized by the code element which is typically associated with a value set of diagnosis codes.

Many clinical systems make a distinction between the active conditions for a patient (i.e. the problem list or health concerns) and the diagnoses associated with an encounter. Problem list items and health concerns are typically documented with additional information about the condition such as prevalence period and clinical status, while encounter diagnoses typically have less information, usually only the diagnosis code as part of the encounter information. Within FHIR, both these types of data are represented using the Condition resource. The category element is used to indicate which kind of data the Condition represents, a problem list item, a health concern, or an encounter diagnosis, and the ConditionHealthProblems and ConditionEncounterDiagnosis profiles separate conditions by these ctaegories.

Depending on measure intent, different approaches may be needed to access condition data. In particular, clinical status and prevalence period would only be expected to be present on problem list items and health concerns:

define "Active Diabetes Conditions":
  [ConditionProblemsHealthConcerns: Diabetes] Condition
    where Condition.isActive()

The QICoreCommon library defines isProblemListItem() and isHealthConcern() functions to facilitate identifying the category of a Condition, as well as an isActive() function to facilitate determining whether the Condition indicates the presence of a particular diagnosis for the patient. The isActive() function is equivalent to testing the clinicalStatus element for the active, recurrence, and relapse values.

NOTE: If measure intent is such that condition information should be considered whether it is problem list, health concern, or encounter diagnosis, the category check can be omitted.

Encounters with a condition

Reviewed 2023-02-21

For encounter diagnoses, CQMCommon defines an encounterDiagnosis() function to facilitate identifying encounter diagnoses:

define "Encounters with a Diabetes Condition":
  "Completed Encounters During the Measurement Period" CompletedEncounter
    where exists (
      (CompletedEncounter.encounterDiagnosis()) EncounterDiagnosis 
        where EncounterDiagnosis.code in "Diabetes"
    )

Note the absence of testing for the clinical status of the condition as this checking is performed in the background of the function.

History of a condition

Reviewed 2023-02-21

When looking for history of a condition, clinical status and whether or not the condition is documented as a problem list, health concern, or encounter diagnosis are typically less relevant, so those elements are not typically referenced. However, in QICore, because the two types of conditions are represented with different profiles, separate retrieve statements are used to gather both:

define "History of Diabetes":
  [ConditionProblemsHealthConcerns: Diabetes]
    union [ConditionEncounterDiagnosis: Diabetes]

Note that depending on measure intent, it may still be necessary to reference elements such as:

  1. Completion status of the associated encounter for encounter diagnoses
  2. Clinical status of problem list items and health concerns
  3. Verification status of problem list items and health concerns, especially refuted conditions

For example:

define "History of Diabetes":
  ([ConditionProblemsHealthConcerns: Diabetes] Condition
    where Condition.verificationStatus is not null implies Condition.verificationStatus !~ "refuted"
  ) union (
    [ConditionEncounterDiagnosis: Diabetes] Condition
      where Condition.getEncounter().status = 'finished'
  )

Onset, abatement, and prevalence period

The Condition profiles define onset and abatement elements that specify the prevalence period of the condition. The elements can be specified as choices of various types to allow systems flexibility in the way that information is represented. The QICore profile for Condition constrains those choices to only those that support actual computation of a prevalence period, and the QICoreCommon library defines abatementInterval and prevalenceInterval functions to facilitate accessing this information:

define "Active Diabetes Conditions Onset During the Measurement Period":
  "Active Diabetes Conditions" Diabetes
    where Diabetes.prevalenceInterval() starts during "Measurement Period"

The prevalenceInterval function takes a Condition resource and returns the interval from the start of the onset to the end of the abatement. If the Condition is active (i.e. has a clinicalStatus of active, recurrence, or relapse), then the ending boundary of the interval is inclusive (i.e. closed). Otherwise, the ending boundary of the interval is exclusive (i.e. open). When looking for whether a condition was active at some point, use the prevalenceInterval function rather than looking at the status element only.

Conditions present on admission

The QICore condition profiles also define a diagnosisPresentOnAdmission indicator to allow systems to indicate whether a particular diagnosis was present on admission for an encounter:

define "Encounter With Diabetes Diagnosis Present on Admission":
  "Non-Elective Inpatient Encounter Less Than 120 Days" IPEncounter
    where exists (IPEncounter.diagnosis D
      where D.condition.getCondition().code in "Diabetes"
        and D.diagnosisPresentOnAdmission in "Present on Admission or Clinically Undetermined"
    )

Note that this expression is using the condition reference from the Encounter to retrieve the specific encounter diagnosis. This is done using the getCondition() function defined in QICoreCommon, as opposed to retrieving the Condition resources directly as in the previous examples.

Observations

QICore defines a variety of profiles for use in accessing observations for a patient. Specifically, QICore includes the vital signs profiles defined in USCore such as blood pressure, body height and weight, and bmi, as well as several social determinants observations.

In general, these profiles do not constrain the value of the status element, meaning that retrieves of these profiles will return observations in any status. As a modifier element, authors must consider the possible values of the observation status when determining how to filter the results of a retrieve of these profiles.

Vital Signs

When using QICore to access profiled resources, the result of the retrieve will only include resources that conform to that profile. This means that the retrieve is effectively a filter by conformance, meaning that the expression does not need to provide filters for values that are fixed by the profile definition. When retrieving Respiratory rate, for example, this means that the expression does not need to test that the code of the Observation is the LOINC code for respiratory rate (9279-1), the retrieve will only result in observations that already have that code:

// Respiratory rate - 9279-1
// @profile: http://hl7.org/fhir/StructureDefinition/resprate
define RespiratoryRate:
  ["observation-resprate"] O
    where O.status in { 'final', 'amended', 'corrected' }

As a rule of thumb, if a profile definition defines a fixed value constraint for an element, then the expression does not need to use that element.

// Respiratory rate - 9279-1
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-respiratory-rate
define RespiratoryRate:
  [USCoreRespiratoryRateProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// Heart rate - 8867-4
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-heart-rate
define HeartRate:
  [USCoreHeartRateProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// Oxygen saturation - 2708-6
// @profile: http://hl7.org/fhir/StructureDefinition/oxygensat
define OxygenSaturation:
  ["observation-oxygensat"] O
    where O.status in { 'final', 'amended', 'corrected' }

// Body temperature - 8310-5
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-body-temperature
define BodyTemperature:
  [USCoreBodyTemperatureProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// Body height - 8302-2
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-body-height
define BodyHeight:
  [USCoreBodyHeightProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// Head circumference - 9843-4
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-head-circumference
define HeadCircumference:
  [USCoreHeadCircumferenceProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// Body weight - 29463-7
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-body-weight
define BodyWeight:
  [USCoreBodyWeightProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// Body mass index - 39156-5
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-bmi
define BodyMassIndex:
  [USCoreBMIProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// Blood pressure systolic and diastolic - 85354-9
// Systolic blood pressure - 8480-6
// Diastolic blood pressure - 8462-4
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-blood-pressure
define "BloodPressure less than 140 over 90":
  [USCoreBloodPressureProfile] BP
    where BP.status in { 'final', 'amended', 'corrected' }
      and BP.systolic.value < 140 'mm[Hg]'
      and BP.diastolic.value < 90 'mm[Hg]'

// USCore Smoking Status
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus
define SmokingStatus:
  ["USCoreSmokingStatusProfile"] O
    where O.status in { 'final', 'amended', 'corrected' }

// USCore Pediatric BMI for Age - 59576-9
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/pediatric-bmi-for-age
define PediatricBMIForAge:
  [USCorePediatricBMIforAgeObservationProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// USCore Pediatric Weight for Height - 77606-2
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/pediatric-weight-for-height
define PediatricWeightForHeight:
  [USCorePediatricWeightForHeightObservationProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

// USCore Pulse Oximetry - 59408-5
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-pulse-oximetry
define PulseOximetry:
  [USCorePulseOximetryProfile] O
    where O.status in { 'final', 'amended', 'corrected' }

Smoking Status

QICore includes the USCore Smoking Status profile:

// USCore Smoking Status
// @profile: http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus
define SmokingStatus:
  ["USCoreSmokingStatusProfile"] O
    where O.status in { 'final', 'amended', 'corrected' }

Laboratory Result

Laboratory results in QICore use the LaboratoryResultObservation profile. By default, Laboratory results in QICore are characterized by the code element.

define LaboratoryResultObservation:
  [LaboratoryResultObservation] O
    where O.status in { 'final', 'amended', 'corrected' }

Clinical Test Result

Clinical test results in QICore use the ObservationClinicalTestResult profile. By default, clinical test results in QICore are characterized by the code element.

define ObservationClinicalTestResult:
  [ObservationClinicalTestResult] O
    where O.status in { 'final', 'amended', 'corrected' }

Imaging Result

Imaging results in QICore use the ObservationImagingResult profile. By default, imaging results in QICore are characterized by the code element.

define ObservationImagingResult:
  [ObservationImagingResult] O
    where O.status in { 'final', 'amended', 'corrected' }

Survey

Survey observations in QICore use the ObservationSurvey profile. By default, survey observations in QICore are characterized by the code element.

define ObservationSurvey:
  [ObservationSurvey] O
    where O.status in { 'final', 'amended', 'corrected' }

Other Observations

In addition, QICore defines a general Observation profile for use when accessing observations that are not covered by the specific profiles defined in FHIR and US Core. Observations in QICore are characterized by the code element, which is typically filtered to a particular value set:

define "Pap Test with Results":
  [Observation: "Pap Test"] PapTest
    where PapTest.value is not null
      and PapTest.status in { 'final', 'amended', 'corrected', 'preliminary' }

NOTE: As with the other observation profiles, the status of a QICore Observation must be considered in order to ensure that the results of the expression will match measure intent. This typically means that the status element will be used in the expression as in the prior example.

Observations not done

And finally, QICore defines an ObservationCancelled profile to support identifying observations that were not performed for a particular reason:

define "Pap Test Refused":
  ["ObservationCancelled": "Pap Test"] PapTest
    where PapTest.notDoneReason in "Patient Refusal"

Medications

FHIR defines several medication-related resources that are profiled for use in the US by USCore, and then by QICore for use in quality improvement artifacts. For background on the FHIR medication resources, see the Medications Module in the base FHIR specification. Additional guidance on how medication information is profiled within US Core can be found in the Medication List Guidance topic in the US Core implementation guide.

Medication ordered

QICore defines the MedicationRequest profile to represent medication proposals, plans, and orders, as well as self-reported medications. The following example illustrates an order for Antithrombotic Therapy to be taken by the patient once discharged. MedicationRequest resources in QICore are characterized by the medication element which can be represented as a code or a reference.

define "Antithrombotic Therapy at Discharge":
  ["MedicationRequest": medication in "Antithrombotic Therapy"] Antithrombotic
    where (Antithrombotic.isCommunity() or Antithrombotic.isDischarge())
      and Antithrombotic.status in { 'active', 'completed' }
      and Antithrombotic.intent = 'order'

NOTE: Because the status element is a modifier that is not constrained by the profile to a specific value or value set, authors must consider all the possible values of the status to ensure the expression matches measure intent. In this case the statuses of active and completed indicate active or filled prescriptions for medications in the Antithrombotic Therapy value set.

NOTE: Because the MedicationRequest profile fixes the value of the doNotPerform element to false if it is present, that element does not need to be tested in the expression.

Medication not ordered

QICore defines the MedicationNotRequested profile to represent documentation of the reason for not ordering a particular medication or class of medications. By default, MedicationNotRequested resources in QICore are characterized by the medication element which can be represented as a code or a reference.

define "Reason for Not Ordering Antithrombotic":
  ["MedicationNotRequested": "Antithrombotic Therapy"] NoAntithromboticDischarge
    where (NoAntithromboticDischarge.reasonCode in "Medical Reason"
      or NoAntithromboticDischarge.reasonCode in "Patient Refusal")
      and (NoAntithromboticDischarge.isCommunity() or NoAntithromboticDischarge.isDischarge())
      and NoAntithromboticDischarge.status in { 'active', 'completed' }
      and NoAntithromboticDischarge.intent = 'order'

NOTE: Because the status element is a modifier that is not constrained by the profile to a specific value or value set, authors must consider all the possible values of the status to ensure the expression matches measure intent. In this case the statuses of active and completed indicate no active or filled prescriptions for medications in the Antithrombotic Therapy value set.

NOTE: Because the MedicationNotRequested profile fixes the value of doNotPerform to true, that element does not need to be tested in the expression.

Medication administered

QICore defines the MedicationAdministration profile to represent the administration of a medication to a patient. By default, MedicationAdministration resources in QICore are characterized by the medication element, which can be represented as a code or a reference.

define "Low Dose Unfractionated Heparin Administration":
  ["MedicationAdministration": medication in "Low Dose Unfractionated Heparin for VTE Prophylaxis"] VTEMedication
    where VTEMedication.status = 'completed'
      and VTEMedication.category ~ QICoreCommon."Inpatient"

NOTE: Because the MedicationAdministration profile does not fix the value of the status element, authors must consider all the possible values of the element to ensure the expression matches measure intent. In this case, the completed status indicates the only completed medication administrations should be returned.

Medication not administered

QICore defines the MedicationAdministrationNotDone profile to represent documentation of the reason a medication administration did not occur. By default, MedicationAdministrationNotDone resources in QICore are characterized by the medication element, which can be represented as a code or a reference.

define "Low Dose Unfractionated Heparin for VTE Prophylaxis Not Administered":
  ["MedicationAdministrationNotDone": "Low Dose Unfractionated Heparin for VTE Prophylaxis"] VTEMedication
    where VTEMedication.category ~ QICoreCommon."Inpatient"
      and (VTEMedication.reasonCode in "Medical Reason" or VTEMedication.reasonCode in "Patient Refusal")

NOTE: Because the MedicationAdministrationNotDone profile fixes the value of status to not-done, that element does not need to be tested in the expression.

Medication dispensed

QICore defines the MedicationDispense profile to represent the fulfillment of a medication request, either in a hospital or community pharmacy. By default, MedicationDispense resources in QICore are charaacterized by the medication element, which can be represented as a code or a reference.

define "Dementia Medication Dispensed":
  ["MedicationDispense": "Dementia Medications"] MedicationDispense
    where MedicationDispense.status in { 'active', 'completed', 'on-hold' }

NOTE: Because the MedicationDispense profile does not fix the value of the status element, authors must consider all the possible values of the element to ensure the expression matches measure intent. In this case, the active, completed, and on-hold statuses are used to retrieve any positive dispensing event.

Medication not dispensed

QICore defines the MedicationDispenseDeclined profile to represent documentation of the reason that a dispense did not occur. By default, MedicationDispenseDeclined resources in QICore are characterized by the medication element, which can be represented as a code or a reference.

define "Dementia Medication Not Dispensed":
    ["MedicationDispenseNotDone": "Dementia Medications"] MedicationDispense
      where MedicationDispense.statusReason in "Medical Reason"
        or MedicationDispense.statusReason in "Patient Refusal"

NOTE: Because the MedicationDispenseDeclined profile fixes the value of the status element to declined, that element does not need to be tested in the expression.

Medication in use

TODO

Procedures

FHIR defines several procedure-related resources to support representing the proposal, planning, ordering, and performance of services and procedures for a patient.

Procedure performed

QICore defines the Procedure profile to represent an in-progress or complete procedure for a patient. By default, Procedure resources in QICore are characterized by the code element.

define "Application of Intermittent Pneumatic Compression Devices":
  ["Procedure": "Application of Intermittent Pneumatic Compression Devices (IPC)"] DeviceApplied
    where DeviceApplied.status = 'completed'

NOTE: Because the Procedure profile does not fix the value of the status element, authors must consider all the possible values of the element to ensure the expression meets measure intent. In this case, completed status is used to indicate that only completed procedures should be returned.

Procedure not done

QICore defines the ProcedureNotDone profile to represent documentation of the reason a particular procedure, or class of procedures, was not performed. By default, ProcedureNotDone resources in QICore are characterized by the code element.

define "Intermittent Pneumatic Compression Devices Not Applied":
  [ProcedureNotDone: "Application of Intermittent Pneumatic Compression Devices (IPC)"] DeviceNotApplied
    where DeviceNotApplied.statusReason in "Medical Reason" 
      or DeviceNotApplied.statusReason in "Patient Refusal"

NOTE: Because the ProcedureNotDone profile fixes the value of the status element to not-done, that element does not need to be tested in the expression.

Procedure ordered

QICore defines the ServiceRequest profile to represent the proposal, planning, or ordering of a particular service. By default, ServiceRequest resources in QICore are characterized by the code element.

define "Intermittent Pneumatic Compression Devices Ordered":
  ["ServiceRequest": "Application of intermittent pneumatic compression devices (IPC)"] DeviceOrdered
    where DeviceOrdered.status in { 'active', 'completed', 'on-hold' }

NOTE: Because the ServiceRequest profile does not fix the value of the status element, authors must consider all the possible values of the element to ensure the expression matches measure intent. In this case, the active, completed, and on-hold statuses are used to ensure a positive order.

NOTE: Because the ServiceRequest profile fixes the value of the doNotPerform element to false if it is present, that element does not need to be tested in the expression.

Procedure not ordered

QICore defines the ServiceNotRequested profile to represent documentation of the reason a particular service or class of services was not ordered. By default, ServiceNotRequested resources in QICore are characterized by the code element.

define "Intermittent Pneumatic Compression Devices Not Ordered":
  ["ServiceNotRequested": "Application of intermittent pneumatic compression devices (IPC)"] DeviceNotOrdered
    where (DeviceNotOrdered.reasonRefused in "Medical Reason"
      or DeviceNotOrdered.reasonRefused in "Patient Refusal")
      and DeviceNotOrdered.status in { 'active', 'completed', 'on-hold' }

NOTE: Because the ServiceNotRequested profile does not fix the value of the status element, authors must consider all the possible values of the element to ensure the expression matches measure intent. In this case, the active, completed, and on-hold statuses are used to ensure a valid order statement.

NOTE: Because the ServiceNotRequested profile fixes the value of doNotPerform to true, that element does not need to be tested in the expression.

Devices

FHIR defines several resources related to the tracking and management of devices used by patients, including Device and DeviceRequest.

Device ordered

QICore defines the DeviceRequest profile to represent proposals, planning, and ordering of devices for a patient. By default, DeviceRequest resources in QICore are characterized by the code element, which can be represented as a code or a reference.

define "Device Indicating Frailty":
  [DeviceRequest: "Frailty Device"] FrailtyDeviceOrder
    where FrailtyDeviceOrder.status in { 'active', 'on-hold', 'completed' }
      and FrailtyDeviceOrder.intent in { 'order', 'original-order', 'reflex-order', 'filler-order', 'instance-order' }

NOTE: Because the DeviceRequest profile does not fix the value of the status element, authors must consider all the possible values of the element to ensure the expression matches measure intent. In this case the active, completed and on-hold statuses are used to ensure a positive device order.

NOTE: Because the DeviceRequest profile fixes the value of the doNotPerform element to false if it is present, that element does not need to be tested in the expression.

Device not ordered

QICore defines the DeviceNotRequested profile to represent documentation of the reason for not ordering a particular device, or class of devices. By default, DeviceNotRequested resources in QICore are characterized by the code element, which can be represented as a code or a reference.

define "Venous Foot Pumps Not Ordered":
  ["DeviceNotRequested": "Venous Foot Pumps (VFP)"] DeviceNotOrdered
    where (DeviceNotOrdered.doNotPerformReason in "Medical Reason"
      or DeviceNotOrdered.doNotPerformReason in "Patient Refusal")
      and DeviceNotOrdered.status in { 'active', 'on-hold', 'completed' }

NOTE: Because the DeviceNotRequested profile fixes the value of doNotPerform to true, this element does not need to be tested in the expression.

Device in use

TODO

Allergies

FHIR defines the AllergyIntolerance resource to represent allergies and intolerances for a patient.

Current allergies

QICore defines the AllergyIntolerance profile to represent allergies and intolerances for a patient. By default, AllergyIntolerance resources in QICore are characterized by the code element.

define "Statin Allergy Intolerance":
  ["AllergyIntolerance": "Statin Allergen"] StatinAllergyIntolerance
    where StatinAllergyIntolerance.clinicalStatus is null 
      or StatinAllergyIntolerance.clinicalStatus ~ QICoreCommon."allergy-active"

NOTE: Because the AllergyIntolerance profile does not constrain the values of the clinicalStatus or verificationStatus elements of the resource, authors must consider the possible values of these elements to ensure the expression matches measure intent. In this case, the clinicalStatus, if present, must be "allergy-active".

No known allergies

TODO

No evidence of a particular allergy

TODO

Immunizations

FHIR defines several immunization-related resources to track and manage the immunization information for a patient, including Immunization and ImmunizationRecommendation.

NOTE: The Immunization resources are reflective of immunization information as recorded in an Immunization Information System. For immunizations as part of clinical workflow, the medication resources should be used?

Immunization performed

QICore defines the Immunization profile to represent immunization information for a patient. By default, Immunization resources in QICore are characterized by the vaccineCode element.

define "Polio Immunizations":
  ["Immunization": "Inactivated Polio Vaccine (IPV)"] PolioVaccination
    where PolioVaccination.status = 'completed'

NOTE: Because the Immunization profile does not fix the value of the status element, authors must consider all the possible values for the element to ensure the expression meets measure intent.

Immunization not performed

QICore defines the ImmunizationNotDone profile to represent documentation of the reason an immunization was not performed. By default, ImmunizationNotDone resources in QICore are characterized by the vaccineCode element.

define "Reason for No Polio Immunization":
  ["ImmunizationNotDone": "Inactivated Polio Vaccine (IPV)"] PolioVaccination
    where PolioVaccination.statusReason in "Medical Reason"
      or PolioVaccination.statusReason in "Patient Refusal"

NOTE: Because the ImmunizationNotDone profile fixes the value of the status element to not-done, this element does not need to be tested in the expression.

Immunization recommended

TODO

Communications

Communication

QICore defines the Communication profile to represent communications with or about the patient. By default, Communication resources in QICore are characterized by the topic element.

define "Macular Edema Absence Communicated":
  ["Communication": "Macular edema absent (situation)"] MacularEdemaAbsentCommunicated
    with "Office Visit Encounters" EncounterDiabeticRetinopathy
      such that MacularEdemaAbsentCommunicated.sent after start of EncounterDiabeticRetinopathy.period
    where MacularEdemaAbsentCommunication.status = 'completed'

NOTE: Because the Communication profile does not fix the value of the status element, authors must consider all the possible values for the element to ensure the expression meets measure intent.

NOTE: This expression uses a direct-reference code of "Macular edema absent (situation)" (i.e. referencing a specific code from a code system, rather than a value set consisting of multiple codes). For more information on using direct-reference codes in CQL expressions, refer to the Codes topic in the Quality Measure IG.

Communication not done

QICore defines the CommunicationNotDone to represent documentation of the reason a communication was not done. By default, CommunicationNotDone resources in QICore are characterized by the topic element.

define "Reason for Macular Edema Absent Not Communicated":
  ["CommunicationNotDone": "Macular Edema Absent Findings"] MacularEdemaAbsentNotCommunicated
    with "Office Visit Encounters" EncounterDiabeticRetinopathy
      such that MacularEdemaAbsentNotCommunicated.sent during EncounterDiabeticRetinopathy.period
    where MacularEdemaAbsentNotCommunicated.statusReason in "Medical Reason"
        or MacularEdemaAbsentNotCommunicated.statusReason in "Patient Refusal"

NOTE: Because the CommunicationNotDone profile fixes the value of the status element to not-done, this element does not need to be tested in the expression.

NOTE: The positive counterpart for this statement (Macular Edema Absence Communicated) uses a direct-reference code, and ideally the negative statement would as well. However, at this time, direct-reference codes cannot be used as the terminology target of a retrieve of a negation profile. Available workarounds for this issue are to either create a value set with the single required code as in the prior example, or to use the long-hand expression of the negation statement, as shown in the following example:

define "Reason for Macular Edema Absent Not Communicated (Explicit Test)":
  ["CommunicationNotDone"] MacularEdemaAbsentNotCommunicated
    with "Office Visit Encounters" EncounterDiabeticRetinopathy
      such that MacularEdemaAbsentNotCommunicated.sent during EncounterDiabeticRetinopathy.period
    where (MacularEdemaAbsentNotCommunicated.topic ~ "Macular edema absent (situation)"
        or "Macular edema absent (situation)" in MacularEdemaAbsentNotCommunicated.topic
      )
      and (MacularEdemaAbsentNotCommunicated.statusReason in "Medical Reason"
        or MacularEdemaAbsentNotCommunicated.statusReason in "Patient Refusal"
      )

Communication ordered

Wiki Index

Home

Authoring Patterns - QICore v4.1.1

Authoring Patterns - QICore v5.0.0

Authoring Patterns - QICore v6.0.0

Authoring Measures in CQL

Composite Measure Development

Cooking with CQL Examples

Cooking with CQL Q&A All Categories
Additional Q&A Examples

CQL 1.3 Impact Guidance

CQL Error Messages

Developers Introduction to CQL

Discussion Items

Example Measures

Formatting and Usage Topics

Formatting Conventions

Library Versioning

Negation in QDM

QDM Known Issues

Specific Occurrences

Specifying Population Criteria

Supplemental Data Elements

Terminology in CQL

Translator Options For Measure Development

Unions in CQL

Clone this wiki locally