Quality Measure Implementation Guide
2.0.0-ballot - STU 2 Ballot

Quality Measure Implementation Guide - Downloaded Version null See the Directory of published versions

## Library: MAT Global Common Functions FHIR Library (Experimental)

Official URL: http://hl7.org/fhir/uv/cqm/Library/MATGlobalCommonFunctions | Version: 5.0.000 | Highlight text changes?
Standards status: Informative Active as of 2019-09-03 | Computable Name: MATGlobalCommonFunctions
Other Identifiers: http://example.org/fhir/cqi/ecqm/Library/Identifier#MATGlobalCommonFunctions (use: official, ), OID:2.16.840.1.113883.4.642.40.61.28.25

This library is used as an example in the FHIR Quality Measure Implementation Guide

Metadata
Title | MAT Global Common Functions FHIR Library
Version | 5.0.000
Identifier | MATGlobalCommonFunctions
Identifier | urn:oid:2.16.840.1.113883.4.642.40.61.28.25
Approval Date | 2019-08-03
Last Review Date | 2019-08-03
Experimental | true
Jurisdiction | 001 from http://unstats.un.org/unsd/methods/m49/m49.htm
Topic | FHIR
Topic | CQL
Steward (Publisher) | HL7 International / Clinical Quality Information
Description | This library is used as an example in the FHIR Quality Measure Implementation Guide
Type | logic-library from http://terminology.hl7.org/CodeSystem/library-type
Dependency | Description: Library FHIRHelpers Resource: http://hl7.org/fhir/uv/cql/Library/FHIRHelpers|4.0.1 Canonical URL: `http://hl7.org/fhir/uv/cql/Library/FHIRHelpers|4.0.1`
Dependency | Description: Code System LOINC Resource: Logical Observation Identifiers, Names and Codes (LOINC) Canonical URL: `http://loinc.org`
Dependency | Description: Code System SNOMEDCT Resource: SNOMED CT (all versions) Canonical URL: `http://snomed.info/sct`
Dependency | Description: Code System RoleCode Resource: RoleCode Canonical URL: `http://terminology.hl7.org/CodeSystem/v3-RoleCode`
Dependency | Description: Code System Diagnosis Role Resource: Diagnosis Role Canonical URL: `http://terminology.hl7.org/CodeSystem/diagnosis-role`
Dependency | Description: Code System RequestIntent Resource: RequestIntent Canonical URL: `http://hl7.org/fhir/request-intent`
Dependency | Description: Code System MedicationRequestCategory Resource: MedicationRequest Category Codes Canonical URL: `http://terminology.hl7.org/CodeSystem/medicationrequest-category`
Dependency | Description: Code System ConditionClinicalStatusCodes Resource: Condition Clinical Status Codes Canonical URL: `http://terminology.hl7.org/CodeSystem/condition-clinical`
Dependency | Description: Code System ConditionVerificationStatusCodes Resource: ConditionVerificationStatus Canonical URL: `http://terminology.hl7.org/CodeSystem/condition-ver-status`
Dependency | Description: Code System AllergyIntoleranceClinicalStatusCodes Resource: AllergyIntolerance Clinical Status Codes Canonical URL: `http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical`
Dependency | Description: Code System AllergyIntoleranceVerificationStatusCodes Resource: AllergyIntolerance Verification Status Canonical URL: `http://terminology.hl7.org/CodeSystem/allergyintolerance-verification`
Dependency | Description: Value Set Encounter Inpatient Resource: Encounter Inpatient Canonical URL: `http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.666.5.307`
Dependency | Description: Value Set Emergency Department Visit Resource: Emergency Department Visit Canonical URL: `http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.117.1.7.1.292`
Dependency | Description: Value Set Observation Services Resource: Observation Services Canonical URL: `http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1111.143`
Data Requirement | Type: Encounter Profile(s): Encounter Code Filter(s): Path: type ValueSet: Encounter Inpatient
Data Requirement | Type: Encounter Profile(s): Encounter Code Filter(s): Path: type ValueSet: Observation Services
Data Requirement | Type: Encounter Profile(s): Encounter Code Filter(s): Path: type ValueSet: Emergency Department Visit
Data Requirement | Type: Condition Profile(s): Condition
Data Requirement | Type: Location Profile(s): Location
Data Requirement | Type: Provenance Profile(s): Provenance Code Filter(s): Path: target
Data Requirement | Type: Medication Profile(s): Medication
Parameters
Name | Use | Card. | Type | Documentation
Measurement Period | In | 0..1 | Period |
Patient | Out | 0..1 | Patient |
Inpatient Encounter | Out | 0..* | Encounter |
Library Content
CQL Content |
    /*
    This example is a work in progress and should not be considered a final specification
    or recommendation for guidance. This example will help guide and direct the process
    of finding conventions and usage patterns that meet the needs of the various stakeholders
    in the measure development community.
    */
    library MATGlobalCommonFunctions version '5.0.000'

    using FHIR version '4.0.1'

    include hl7.fhir.uv.cql.FHIRHelpers version '4.0.1' called FHIRHelpers

    codesystem "LOINC": 'http://loinc.org'
    codesystem "SNOMEDCT": 'http://snomed.info/sct'
    codesystem "RoleCode": 'http://terminology.hl7.org/CodeSystem/v3-RoleCode'
    codesystem "Diagnosis Role": 'http://terminology.hl7.org/CodeSystem/diagnosis-role'
    codesystem "RequestIntent": 'http://hl7.org/fhir/request-intent'
    codesystem "MedicationRequestCategory": 'http://terminology.hl7.org/CodeSystem/medicationrequest-category'
    codesystem "ConditionClinicalStatusCodes": 'http://terminology.hl7.org/CodeSystem/condition-clinical'
    codesystem "ConditionVerificationStatusCodes": 'http://terminology.hl7.org/CodeSystem/condition-ver-status'
    codesystem "AllergyIntoleranceClinicalStatusCodes": 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical'
    codesystem "AllergyIntoleranceVerificationStatusCodes": 'http://terminology.hl7.org/CodeSystem/allergyintolerance-verification'

    valueset "Encounter Inpatient": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.666.5.307'
    valueset "Emergency Department Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.117.1.7.1.292'
    valueset "Observation Services": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1111.143'

    code "Birthdate": '21112-8' from "LOINC" display 'Birth date'
    code "Dead": '419099009' from "SNOMEDCT" display 'Dead'
    code "ER": 'ER' from "RoleCode" display 'Emergency room'
    code "ICU": 'ICU' from "RoleCode" display 'Intensive care unit'
    code "Billing": 'billing' from "Diagnosis Role" display 'Billing'

    // Condition Clinical Status Codes - Consider value sets for these
    code "active": 'active' from "ConditionClinicalStatusCodes"
    code "recurrence": 'recurrence' from "ConditionClinicalStatusCodes"
    code "relapse": 'relapse' from "ConditionClinicalStatusCodes"
    code "inactive": 'inactive' from "ConditionClinicalStatusCodes"
    code "remission": 'remission' from "ConditionClinicalStatusCodes"
    code "resolved": 'resolved' from "ConditionClinicalStatusCodes"

    // Condition Verification Status Codes - Consider value sets for these
    code "unconfirmed": 'unconfirmed' from ConditionVerificationStatusCodes
    code "provisional": 'provisional' from ConditionVerificationStatusCodes
    code "differential": 'differential' from ConditionVerificationStatusCodes
    code "confirmed": 'confirmed' from ConditionVerificationStatusCodes
    code "refuted": 'refuted' from ConditionVerificationStatusCodes
    code "entered-in-error": 'entered-in-error' from ConditionVerificationStatusCodes

    code "allergy-active": 'active' from "AllergyIntoleranceClinicalStatusCodes"
    code "allergy-inactive": 'inactive' from "AllergyIntoleranceClinicalStatusCodes"
    code "allergy-resolved": 'resolved' from "AllergyIntoleranceClinicalStatusCodes"

    // Allergy/Intolerance Verification Status Codes - Consider value sets for these
    code "allergy-unconfirmed": 'unconfirmed' from AllergyIntoleranceVerificationStatusCodes
    code "allergy-confirmed": 'confirmed' from AllergyIntoleranceVerificationStatusCodes
    code "allergy-refuted": 'refuted' from AllergyIntoleranceVerificationStatusCodes

    // MedicationRequest Category Codes
    code "Community": 'community' from "MedicationRequestCategory" display 'Community'
    code "Discharge": 'discharge' from "MedicationRequestCategory" display 'Discharge'

    parameter "Measurement Period" Interval<DateTime>
      default Interval[@2019-01-01T00:00:00.0, @2020-01-01T00:00:00.0)

    context Patient

    define "Inpatient Encounter":
    	[Encounter: "Encounter Inpatient"] EncounterInpatient
    		where EncounterInpatient.status = 'finished'
    		    and "LengthInDays"(EncounterInpatient.period) <= 120
    			and EncounterInpatient.period ends during "Measurement Period"

    define function "ToDate"(Value DateTime):
    	DateTime(year from Value, month from Value, day from Value, 0, 0, 0, 0, timezoneoffset from Value)

    define function "CalendarAgeInDaysAt"(BirthDateTime DateTime, AsOf DateTime):
    	days between ToDate(BirthDateTime)and ToDate(AsOf)

    define function "CalendarAgeInDays"(BirthDateTime DateTime):
    	CalendarAgeInDaysAt(BirthDateTime, Today())

    define function "CalendarAgeInMonthsAt"(BirthDateTime DateTime, AsOf DateTime):
    	months between ToDate(BirthDateTime)and ToDate(AsOf)

    define function "CalendarAgeInMonths"(BirthDateTime DateTime):
    	CalendarAgeInMonthsAt(BirthDateTime, Today())

    define function "CalendarAgeInYearsAt"(BirthDateTime DateTime, AsOf DateTime):
    	years between ToDate(BirthDateTime)and ToDate(AsOf)

    define function "CalendarAgeInYears"(BirthDateTime DateTime):
    	CalendarAgeInYearsAt(BirthDateTime, Today())

    define function "LengthInDays"(Value Interval<DateTime>):
    	difference in days between start of Value and end of Value

    define function "ED Visit"(TheEncounter FHIR.Encounter):
        singleton from (
            [Encounter: "Emergency Department Visit"] EDVisit
                where EDVisit.status = 'finished'
                    and EDVisit.period ends 1 hour or less on or before start of FHIRHelpers.ToInterval(TheEncounter.period)
        )

    define function "Hospitalization"(TheEncounter FHIR.Encounter):
    	( "ED Visit"(TheEncounter) ) X
        return
            if X is null then TheEncounter.period
            else Interval[start of FHIRHelpers.ToInterval(X.period), end of FHIRHelpers.ToInterval(TheEncounter.period)]

    define function "Hospitalization Locations"(TheEncounter FHIR.Encounter):
    	( "ED Visit"(TheEncounter) ) EDEncounter
        return
            if EDEncounter is null then TheEncounter.location
            else flatten { EDEncounter.location, TheEncounter.location }

    define function "Hospitalization Length of Stay"(TheEncounter FHIR.Encounter):
    	LengthInDays("Hospitalization"(TheEncounter))

    define function "Hospital Admission Time"(TheEncounter FHIR.Encounter):
    	start of "Hospitalization"(TheEncounter)

    define function "Hospital Discharge Time"(TheEncounter FHIR.Encounter):
    	end of FHIRHelpers.ToInterval(TheEncounter.period)

    define function "Hospital Arrival Time"(TheEncounter FHIR.Encounter):
    	start of FHIRHelpers.ToInterval(First(
    	    ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation
    			sort by start of FHIRHelpers.ToInterval(period)
    	).period)

    define function "HospitalizationWithObservation"(TheEncounter FHIR.Encounter):
    	TheEncounter Visit
    		let ObsVisit: Last([Encounter: "Observation Services"] LastObs
    				where LastObs.period ends 1 hour or less on or before start of Visit.period
    				sort by end of period
    			),
    			VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period),
    			EDVisit: Last([Encounter: "Emergency Department Visit"] LastED
    				where LastED.period ends 1 hour or less on or before VisitStart
    				sort by end of period
    			)
    		return Interval[Coalesce(start of EDVisit.period, VisitStart), end of Visit.period]

    define function "HospitalizationWithObservationLengthofStay"(Encounter FHIR.Encounter):
    	"LengthInDays"("HospitalizationWithObservation"(Encounter))

    /*
    *
    *    CQFMeasures Common Logic
    *
    */

    define function "Normalize Interval"(choice Choice<FHIR.dateTime, FHIR.Period, FHIR.Timing, FHIR.instant, FHIR.string, FHIR.Age, FHIR.Range>):
      case
    	  when choice is FHIR.dateTime then
        	Interval[FHIRHelpers.ToDateTime(choice as FHIR.dateTime), FHIRHelpers.ToDateTime(choice as FHIR.dateTime)]
    		when choice is FHIR.Period then
      		FHIRHelpers.ToInterval(choice as FHIR.Period)
    		when choice is FHIR.instant then
    			Interval[FHIRHelpers.ToDateTime(choice as FHIR.instant), FHIRHelpers.ToDateTime(choice as FHIR.instant)]
    		when choice is FHIR.Age then
    		  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(choice as FHIR.Age),
    			  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(choice as FHIR.Age) + 1 year)
    		when choice is FHIR.Range then
    		  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((choice as FHIR.Range).low),
    			  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((choice as FHIR.Range).high) + 1 year)
    		when choice is FHIR.Timing then
    		  Message(null as Interval<DateTime>, true, '1', 'Error', 'Cannot compute a single interval from a Timing type')
        when choice is FHIR.string then
          Message(null as Interval<DateTime>, true, '1', 'Error', 'Cannot compute an interval from a String value')
    		else
    			null as Interval<DateTime>
    	end

    define function "Normalize Abatement"(condition Condition):
    	if condition.abatement is FHIR.dateTime then
    	  Interval[FHIRHelpers.ToDateTime(condition.abatement as FHIR.dateTime), FHIRHelpers.ToDateTime(condition.abatement as FHIR.dateTime)]
    	else if condition.abatement is FHIR.Period then
    	  FHIRHelpers.ToInterval(condition.abatement as FHIR.Period)
    	else if condition.abatement is FHIR.string then
        Message(null as Interval<DateTime>, true, '1', 'Error', 'Cannot compute an interval from a String value')
    	else if condition.abatement is FHIR.Age then
    		Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(condition.abatement as FHIR.Age),
    			FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(condition.abatement as FHIR.Age) + 1 year)
    	else if condition.abatement is FHIR.Range then
    	  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((condition.abatement as FHIR.Range).low),
    		  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((condition.abatement as FHIR.Range).high) + 1 year)
    	else if condition.abatement is FHIR.boolean then
    	  Interval[end of "Normalize Interval"(condition.onset), condition.recordedDate)
    	else null

    define function "Prevalence Period"(condition Condition):
      Interval[start of "Normalize Interval"(condition.onset), end of "Normalize Abatement"(condition))

    define function "GetId"(uri String):
    	Last(Split(uri, '/'))

    define function "EncounterDiagnosis"(Encounter Encounter):
      Encounter.diagnosis D
        return singleton from ([Condition] C where C.id = "GetId"(D.condition.reference))

    // Returns the condition that is specified as the principal diagnosis for the encounter
    // TODO: BTR 2019-07-30: Shouldn't need the FHIRHelpers reference here, investigate
    define function "PrincipalDiagnosis"(Encounter Encounter):
    	(singleton from (Encounter.diagnosis D where FHIRHelpers.ToInteger(D.rank) = 1)) PD
    		return singleton from ([Condition] C where C.id = "GetId"(PD.condition.reference))

    // Returns the location for the given location reference
    define function GetLocation(reference Reference):
      singleton from (
        [Location] L where L.id = GetId(reference.reference)
      )

    /*
    NOTE: Extensions are not the preferred approach, but are used as a way to access
    content that is defined by extensions but not yet surfaced in the
    CQL model info.
    */
    define function "GetExtensions"(domainResource DomainResource, url String):
      domainResource.extension E
    	  where E.url = ('http://hl7.org/fhir/us/qicore/StructureDefinition/' + url)
    		return E

    define function "GetExtension"(domainResource DomainResource, url String):
      singleton from "GetExtensions"(domainResource, url)

    /*
    NOTE: Extensions are not the preferred approach, but are used as a way to access
    content that is defined by extensions but not yet surfaced in the
    CQL model info.
    */
    define function "GetExtensions"(element Element, url String):
      element.extension E
    	  where E.url = (url)
    		return E

    define function "GetExtension"(element Element, url String):
      singleton from "GetExtensions"(element, url)

    /*
    NOTE: Extensions are not the preferred approach, but are used as a way to access
    content that is defined by extensions but not yet surfaced in the
    CQL model info.
    */
    define function "GetBaseExtensions"(domainResource DomainResource, url String):
      domainResource.extension E
    	  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + url)
    		return E

    define function "GetBaseExtension"(domainResource DomainResource, url String):
      singleton from "GetBaseExtensions"(domainResource, url)

    /*
    NOTE: Provenance is not the preferred approach, this is provided only as an illustration
    for what using Provenance could look like, and is not a tested pattern
    */
    define function "GetProvenance"(resource Resource):
      singleton from ([Provenance: target in resource.id])

    define function "GetMedicationCode"(request MedicationRequest):
      if request.medication is CodeableConcept then
    	  request.medication as CodeableConcept
    	else
    	  (singleton from ([Medication] M where M.id = GetId((request.medication as Reference).reference))).code
ELM XML Content |
    Encoded data
ELM JSON Content |
    Encoded data
Generated using version 0.5.4 of the sample-content-ig Liquid templates