Skip to content

Cooking with CQL Q&A: Functions in CQL

cnguyenn4 edited this page Aug 16, 2022 · 10 revisions

Each Q&A has the Cooking with CQL session number and date. For the most current and accurate information, please check the CQL Qs&As for a more recent answer to your question.

Beginning of Encounter: In the Clinical Quality Language, library 1.5, is the AgeInYearsAt function in this expression example going to return yes or no without having operator access present? (Session 63 - 4/28/22)
define "Initial Population":
		AgeInYearsAt(date from start of "Measurement Period") in Interval[23, 64)
		and Patient.gender = 'female'
		and exists "Qualifying Encounters"
  • The expression returns a Boolean true (yes) or Boolean false (no) because it is part of the “in” operator. Additionally within this code, the bracket - [ - represents a closed boundary [23 indicating that 23 is included; whereas, the parenthesis - ) - indicates an open boundary 64) indicating that up to, but excluding 64. The datatype of the interval (in this case an integer) and the precision of the expression as integer, number, year, day, minute, etc. (in this case the AgeInYearsAt function returns the number of years as an integer) impacts the granularity or how close a value can approach the open boundary.
Beginning of Encounter: Encounters do not end in the Electronic Health Record (EHR) until closed. Completion of documentation could occur 3 days after the patient has left even though they were only there for 20 minutes. Most implementers figure out how to say the encounter has ended. They either say Departure Time and apply that to the ended encounter or they automatically end all encounters for the measure calculation at the end of the day. While Fast Healthcare Interoperability Resource (FHIR) or Quality Data Model (QDM) allows you say the end, that is not really where the EHR sees it as an end. The implementer has to figure that out and it can get a little complicated. Would it be reasonable to say the beginning of the encounter starts on that day, if you are talking ambulatory, because you’re looking for the number that started that day? Is that significantly different? I am asking that question to decrease implementer variability. (Session 43 - 4/23/20)
  • Thank you for bringing up this concern. The QDM User Group addressed this issue on June 19, 2019 (link to minutes) based on the QDM-235 Jira tracker item. The QI-Core Implementation Guide STU 4 (v4.0.0 for FHIR 4.0.1) also includes encounter timing guidance. The resulting guidance for QDM “Encounter, Performed” relevantPeriod endTime is that implementation sites determine local mechanisms to overcome the issue. Feedback on the QDM User Group identified two approaches. Some use the check-in and check-out time for the actual encounter timing noting that the encounter may actually be opened ahead of the visit to prepare before the patient’s arrival and remain open long after the patient departs, perhaps days later. Another implementer automatically assigns an encounter end time as 23:59 of the day the encounter occurred. Your approach to limit measure expressions to compare actions only to ambulatory encounter start times may work. However, the intent of the measure may require an action after the patient departs. As you note, this is a complicated workflow issue. Hopefully the discussion in the QDM User Group minutes and the QI-Core documentation will be helpful. There are different implementation variations happening and that is the challenge.
Capturing principal diagnosis in the Quality Improvement (QI)-Core 5.0 release: In the Quality Improvement (QI)-Core 5.0 release, is there a function to capture principal diagnosis? (Session 66 - 7/28/22)
  • There is currently not a function defined for principal diagnosis, though it is a good candidate. The Ischemic Stroke measure has an example of capturing the principal diagnosis. The logic uses "Inpatient Encounter" to find the principal diagnosis in the code:

// connectathon/fhir4/cql/MATGlobalCommonFunctions_FHIR4-4.0.000.cql
define "Inpatient Encounter":
  [Encounter: "Encounter Inpatient"] EncounterInpatient
    where EncounterInpatient.status = 'finished'
      and "LengthInDays"(EncounterInpatient.period) <= 120
      and EncounterInpatient.period ends during "Measurement Period"


// EXM105
define "Inpatient Encounter with Principal Diagnosis of Ischemic Stroke":
  "Inpatient Encounter" Encounter
    let PrincipalDiagnosis:
      (singleton from (Encounter.diagnosis D where D.use ~ ToConcept("Billing") and D.rank = 1)) PD
        return singleton from ([Condition: id in Last(Split(PD.condition.reference, '/'))])
    where PrincipalDiagnosis.code in "Ischemic Stroke"

CountOfListOfNulls vs. LengthOfListOfNulls functions: Regarding aggregate functions in Clinical Quality Language (CQL) using Fast Healthcare Interoperability Resources® (FHIR®) v4.0.1, what is the difference between the CountOfListOfNulls function versus the LengthOfListOfNulls function? (Session 61 - 2/24/22)
  • The CountOfListOfNulls, an aggregate operator, will ignore nulls consistent with the other aggregate operations available in CQL. The Count operator counts the number of non-null elements in a list. Whereas Length is a list operator that returns how many elements are in a list, including nulls.
Difference between "GetBaseExtensions", "GetExtensions", and "GetExtension": What are the differences between the functions "GetBaseExtensions", "GetExtensions", and "GetExtension" in the current Global Common Library? (Session 55 - 6/24/21)
  • : "GetExtension" and "GetExtensions" are used to return extensions from FHIR elements and domain resources. Measure developers should use the plural if the extension is allowed to be specified multiple times (i.e. has a cardinality greater than 1 in the profile definition. The singular function ensures that only one extension will be returned to the measure developer as a result of the function. If the singular function is used on an extension that is allowed to be specified multiple times, it will result in an error if it is used with an instance that has multiple appearances of the extension. The function "GetBaseExtensions" provides a default for the base Uniform Resource Locator (URL), instead of writing out the entire URL. Extensions in FHIR are defined by a complete URL, for example http://hl7.org/fhir/StructureDefinition/valueset-source. The GetBaseExtension functions allow only the “tail” of this URL to be used, defaulting the portion that is common for all base FHIR extensions: http://hl7.org/fhir/StructureDefinition/.

 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)

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)


Dosages and Number of Doses Per Day: There is significant logic involved with looking at dosages and number of doses per day. Is that part of the global library yet? (Session 32 - 2/28/19)
  • Not yet. The global library is based on what measure developers identify as being used in enough measures to warrant including in the library.
Execution error using Global Common Functions in Fast Interoperability Resources® (FHIR®) 4.0: When using Global Common Functions in Fast Healthcare Interoperability Resources® (FHIR®) 4.0, would an execution error result in ATOM if an electronic clinical quality measure (eCQM) was run against the [eCQM-content-r4-2022 repository](https://github.com/cqframework/ecqm-content-r4-2022)? (Session 64 - 5/26/22)
  • An error should not result from running an eCQM against the folder. However, using concurrent Global libraries for FHIR R4 and QI-Core could cause confusion at implementation.
Hospital Arrival Time: How is hospital arrival time defined? (Session 32 - 2/28/19)
  • The definition is included in the MAT Global Common Functions, it’s the start of the first location period for the locations in the encounter, or the immediately prior emergency department encounter if one exists.
List Type specifiers in CQL: With regard to aggregate functions in Clinical Quality Language (CQL) using Fast Healthcare Interoperability Resources® (FHIR®) v4.0.1, considering the expression define EmpyList: List { }, why does this definition include List, where the previous one does not? (Session 61 - 2/24/22)
  • In the define EmptyList: List { } expression, List<Integer> is the type specifier for the list. In a list selector in CQL, authors can optionally provide the type of the list (e.g., list of integers 1, 2, 3) in addition to the list itself. If the expression only provided the { } braces, since there are no elements, the list is of type List<Any> (i.e. the list is a list of elements of any type). Since the Sum operator is defined only for lists of numeric types (e.g. List), it is a type error to try to Sum it. By specifying that the expression is actually a list of Integers, the translator allows the list to be passed to the Sum function. If the list has elements, the type of the list will be inferred based on the type of elements in the list. For a complete reference of the aggregate functions available in CQL on the CQL webpage as well as the Aggregate Functions topic in the CQL Author's Guide.
Locating 2022 electronic clinical quality measures (eCQMs): When using Global Common Functions in Fast Healthcare Interoperability Resources® (FHIR®) 4.0, where are the 2022 electronic clinical quality measures (eCQMs) located? (Session 64 - 5/26/22)
  • The eCQMs are still in the process of being updated from the FHIR r4 2021 content. Only the shared libraries currently exist in the eCQM-content-r4-2022 repository to support measure developers. To support additional testing, many of the 2022 Annual Update measures are being converted to FHIR-based eCQMs and made available for connectathon usage in the eCQM-content-r4-2022 repository.
Measure run using Quality Improvement (QI)-Core: How is a measure run using Quality Improvement (QI)-Core? (Session 64 - 5/26/22)
  • There is a QI-Core repository in QI-Core version 4.1.1 that references the Fast Healthcare Interoperability Resources® (FHIR®) 4.0 Global Common Function library. In the example, the electronic clinical quality measure (eCQM) accesses patient ethnicity directly because the QI-Core model exposes ethnicity as an element of patient. The authoring of the eCQM would look different, but the engine would look the same in the Expression Logical Model translator.

library SupplementalDataElementsQICore4 version '2.0.0'
	

	/*
	@update: @@BTR 2020-03-31 ->
	Incremented version to 2.0.0
	Updated FHIR version to 4.0.1
	@@
	*/
	

	using QICore version '4.1.1'
	

	include FHIRHelpers version '4.0.1'
	

	valueset "ONC Administrative Sex": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1'
	valueset "Race": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.836'
	valueset "Ethnicity": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.837'
	valueset "Payer": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591'
	

	context Patient
	

	define "SDE Ethnicity":
	  Patient.ethnicity.detailed
	

	define "SDE Payer":
	    [Coverage: type in "Payer"] Payer
	      return {
	        code: Payer.type,
	        period: Payer.period
	      }
	

	define "SDE Race":
	  Patient.race.detailed
	

	define "SDE Sex":
	  case
	    when Patient.gender = 'male' then Code { code: 'M', system: 'http://hl7.org/fhir/v3/AdministrativeGender', display: 'Male' }
	    when Patient.gender = 'female' then Code { code: 'F', system: 'http://hl7.org/fhir/v3/AdministrativeGender', display: 'Female' }
	    else null
	  end

Random: Does Clinical Quality Language (CQL) support a mechanism for randomly picking an item from a list? (Session 37 - 7/25/19)
  • The short answer is no. Clinical Quality Language (CQL) is purposely a deterministic language, so we don't have functions like Random(). This was a design decision in the very earliest phases of language development to ensure that systems could reliably cache intermediate results. Even functions like Today() and Now() are defined deterministically so that they return the same value within any given evaluation session. However, CQL 1.3 introduced the ability to define external libraries. From the perspective of the translator, external definitions are just function signatures; it's up to the engine to resolve external definitions and provide the run-time implementation for them. For engines, this would be fairly straightforward to support, but

    • It would tie the CQL that uses the external definitions to engines that understood those externals (reducing portability)
    • The Java-based open source engine does support external libraries, but it's not a feature that has been well-tested.
Use of the expand operator in the Visual Studio Code (VS Code) CQL plugin: When using the Visual Studio Code (VS Code) CQL plugin, with regard to value sets, can the expand operator be used to expand a value set? (Session 65 - 6/23/22)
  • The VS Code CQL plugin is not currently able to make use of terminology servers directly, rather it relies on the presence of ValueSet resources in the vocabulary/valueset directory. If the ValueSet resources in that directory have an expansion element, that expansion will be used. If they do not have expansion elements, the plugin has a naïve implementation of expansion if the value set definition consists only of enumerated codes. This approach allows testing to proceed but is not suitable for final validation of the content. Adding the ability to make use of a FHIR Terminology Server is a planned enhancement to the plugin.
Writing a measure using Quality Improvement (QI)-Core in Fast Interoperability Resources® (FHIR®) 4.0: When writing a measure using Quality Improvement (QI)-Core, can the electronic clinical quality measure reference the Global Common Function library in Fast Healthcare Interoperability Resources® (FHIR®) 4.0? (Session 64 - 5/26/22)
  • The Clinical Quality Language (CQL)-to-Expression Logical Model translator can load multiple libraries and the engine should use the same provider because the QI-Core will map to the same model when executing. While testing the process, the test cases defined in the electronic clinical quality measure (eCQM)-content-r4-2021 repository were brought over to the 2022 published eCQM-content-r4-2022 repository, although dates may need to be updated. However, please note that an eCQM, such as ColorectalCancerScreeningsFHIR.cql, from 2021 would require edits to match the included libraries' names, version numbers, value sets, and pertinent CQL code alignment in addition to date alignment of test cases.

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