FHIR Chat · CQL date-based triggering? · cql

Stream: cql

Topic: CQL date-based triggering?


view this post on Zulip John Silva (Aug 31 2020 at 19:13):

If I have a Condition, with an onsetDateTime that I want to compare in CQL, e.g. something that occurred (or has started) at least 6 months ago, how would I write that in CQL? I'm trying to follow along section 5.5, Date-time operators and section 5.6, Timing and Interval Operators but can't seem to get the right syntax (therefore logic) to do this. Here's what I'm trying:

define "Asthma over 6 months ago"
exists ([Condition: "AsthmaValueSet"] C
where C.onsetDateTime before Today() - 6 months
)

the first thing I run into (using Atom with the language-cql plugin) is that it doesn't allow onsetDateTime but does seem to accept C.onset. However, after I fix that I can't seem to find the correct time expression that is syntactically correct. I was thinking I could use a simple date comparison but haven't been able to figure out how. I also tried using the Interval[] thought didn't have any luck with that either.

view this post on Zulip John Silva (Aug 31 2020 at 19:51):

I found my own answer, posting it here in case it helps another 'newbie' like me.

define "Asthma with duration > 6 months": exists ([Condition: "AsthmaValueSet"] C where C.onset before Today() - 6 months )

view this post on Zulip Chris Moesel (Aug 31 2020 at 20:01):

You can actually be a bit more specific in the CQL if you prefer:

define "Asthma with duration > 6 months":
  exists ([Condition: "AsthmaValueSet"] C
    where (C.onset as dateTime) before Today() - 6 months
  )

In this case, you probably don't need it because the compiler can figure out that dateTime is the only type that semantically makes sense with the before operator. But if you run into something similar again, know that for choices (like value[x]) you can use (value as type) to do the equivalent of valueType.

view this post on Zulip John Silva (Aug 31 2020 at 21:09):

Thanks @Chris Moesel ! I had seen some 'strange syntax' in the CQL spec page with something like dateTimeX where ... and didn't understand what that means. Also, since the onset can be of multiple different value types, how should this be handled? (In my case I'm only worried about onsetDateTime -- and not sure why I can't use C.onsetDateTime as the specifier)

view this post on Zulip Chris Moesel (Aug 31 2020 at 21:23):

@John Silva -- the set of possible attributes is defined by the data model the CQL library declares that it uses. For choices (e.g., onset[x]), it's a little confusing because:

  • the FHIR 1.0.2 CQL data model represents them as separate attributes (e.g., Condition has onsetDateTime with type FHIR.dateTime, onsetAge with type FHIR.Age, etc.)
  • but the FHIR 3.0.x and 4.0.x CQL data models represent them as CQL choice types (e.g., Condition has single onset attribute with a choice of types: FHIR.dateTime, FHIR.Age, etc.).

So if you see CQL with something like onsetDateTime -- it's probably using the FHIR 1.0.2 data model. But if you see CQL with just onset (or onset as dateTime) then it is probably using the FHIR 3.0.0, FHIR 4.0.0, or FHIR 4.0.1 data model.

For attributes that are CQL choice types, you use a cast if you want to specify a particular choice type. So, for Condition's onset in a FHIR 4.0.1 model, you could have:

  • onset -- not specifying any particular type
  • onset as dateTime -- specifically the dateTime representation of onset (if it exists)
  • onset as Age -- specifically the Age representation of onset (if it exists)
  • onset as Period -- specifically the Period representation of onset (if it exists)
  • onset as Range -- specifically the Range representation of onset (if it exists)
  • onset as string -- specifically the string representation of onset (if it exists)

So, if a FHIR 4.0.1 instance of condition has "onsetDateTime": "2020-08-31" in the JSON representation, you access this in CQL via onset as dateTime. Note that if you attempt to access it as onset as Age then the CQL spec says the result should be returned as null (since that specific data does not have an Age representation of onset).

CQL documentation on casting: https://cql.hl7.org/03-developersguide.html#casting

view this post on Zulip John Silva (Sep 01 2020 at 10:17):

Thanks for this explanation. I guess then the problem is that the CQL Author's Guide doesn't make this clear (due to the different FHIR versions).

https://cql.hl7.org/02-authorsguide.html

It seems like all (or most) of the examples on that page show Condition.onsetDateTime without any reference to the fact that this is FHIR 1.0.2 CQL (unless I missed it).

Does this same problem exist for other value type choices, e.g. Observation.value[x] or is it only on Condition, where the FHIR resource model changed?

view this post on Zulip Chris Moesel (Sep 01 2020 at 12:55):

Looking at the Author's Guide, it looks like most of the examples actually use the QUICK data model -- which is based on FHIR (hence the similarity). There are indications in the Author's Guide that the QUICK model is being used. That said, the same basic difference exists -- QUICK versions prior to QUICK 3.0.0 used the onsetDateTime approach, whereas QUICK versions 3.0.0 and later use onset as DateTime -- and it looks like the spec examples use the former.

In general, however, you'll find handling of choices consistent across a data model. So, for the FHIR 1.0.2 model, any choice ending w/ [x] will be represented as multiple fully spelled out properties (e.g., Condition has onsetDateTime, onsetAge, etc; Observation has valueQuantity, valueCodeableConcept, etc). And for FHIR models 3.0.0 and later, they'll be represented as a single attribute that can be cast to the desired type (e.g., Condition has onset, allowing for onset as dateTime, etc; Observation has value allowing for value as Quantity, etc).


Last updated: Apr 12 2022 at 19:14 UTC