-
Notifications
You must be signed in to change notification settings - Fork 25
Cooking with CQL Q&A: Functions in CQL
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: 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.
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.
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 typeList<Any>
(i.e. the list is a list of elements of any type). Since theSum
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.
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.
Authoring Patterns - QICore v4.1.1
Authoring Patterns - QICore v5.0.0
Authoring Patterns - QICore v6.0.0
Cooking with CQL Q&A All Categories
Additional Q&A Examples
Developers Introduction to CQL
Specifying Population Criteria