FHIR Chat · Seeking pattern for evaluating "small" valuesets · cql

Stream: cql

Topic: Seeking pattern for evaluating "small" valuesets


view this post on Zulip Aziz Boxwala (Apr 03 2021 at 00:16):

Looking for the best practice on how to write an expression such as

define "Get Condition from Code Declaration":
   [Condition: "Acute Pharyngitis Code"] C where clinicalStatus in "Active and Recurrence and Relapse VS"

I don't want to create an external value set Active and Recurrence and Relapse VS. Seems like overkill . Is there a better way to write the expression, perhaps using FHIR.ToConcept and checking for membership in a list of Concepts?

view this post on Zulip Aziz Boxwala (Apr 03 2021 at 00:23):

As I was typing my post, one of my team-mates, provided this solution:

codesystem ConditionClinical: 'http://terminology.hl7.org/CodeSystem/condition-clinical'
code "Active Status" : 'active' from ConditionClinical display 'Active'
code "Recurrent Status": 'recurrence' from ConditionClinical display 'Recurrence'
code "Relapse Status": 'relapse' from ConditionClinical display 'Relapse'
context Patient
define HasAsthma:
    exists ([Condition: code in "Asthma"] C  where
       ( (C.clinicalStatus ~ "Active Status") or
        (C.clinicalStatus ~ "Recurrent Status") or
        (C.clinicalStatus ~ "Relapse Status") ) )

Any feedback on this is welcome too.

view this post on Zulip Bryn Rhodes (Apr 05 2021 at 13:49):

The logic approach works, clearly, but ultimately a value set may be more maintainable and readable. Especially if all three statuses should be checked when detecting any active condition, which seems like is probably the case.

view this post on Zulip Chris Moesel (Apr 06 2021 at 14:50):

I'll note that it's tempting to use in for this (e.g., code in {Code1, Code2, Code3}) but this doesn't really work correctly since in is defined to use equality semantics, which would require code to be exact matches (including display). So you're stuck with creating a VS or using or. If you need it in multiple places, you could extract the or into a function though:

define HasAsthma:
    exists ([Condition: code in "Asthma"] C  where IsActiveOrRecurring(C))

define function IsActiveOrRecurring(C Condition):
    C.clinicalStatus ~ "Active Status" or
    C.clinicalStatus ~ "Recurrent Status" or
    C.clinicalStatus ~ "Relapse Status"

view this post on Zulip Bryn Rhodes (Apr 06 2021 at 16:46):

Yes, that's true, and to that end, I've put together some simple value sets in the CQF Common IG: http://build.fhir.org/ig/cqframework/cqf/artifacts.html

view this post on Zulip Bryn Rhodes (Apr 06 2021 at 16:47):

Which reminds me Chris, I know there is a CDS Connect Commons, should we try to align these two "Common" libraries: http://build.fhir.org/ig/cqframework/cqf/Library-FHIRCommon.html

view this post on Zulip Chris Moesel (Apr 06 2021 at 18:09):

@Bryn Rhodes -- it's probably worth at least reviewing them to see if it makes sense. One thing about CDS Connect Commons is that it is also used by the CDS Authoring Tool and fairly tightly coupled to it; so I always need to keep that in mind as I consider changes to CDS Connect Commons.

view this post on Zulip Bryn Rhodes (Apr 06 2021 at 18:14):

That makes sense, what process would be best to follow? I'm happy to submit an issue on the CQF Common repository github if that makes sense, but if there's a process supported by CDS Connect, happy to use that as well.

view this post on Zulip Corey Sanders (Apr 06 2021 at 19:49):

In the Java engine, a filtered retrieve (e.g. [Condition: MyValueSet]) is likely going to perform better than a retrieve that is filtered using the CQL "in" operator (e.g. [Condition] c where c.code in MyValueSet) since the RestFhirRetrieveProvider knows how to pass the filter along to the FHIR server via the :in modifier where the CQL in operator does not. It isn't directly relevant to the OP question about filtering based off clinicalStatus, but I thought it worth mentioning that not all code paths perform the same right now and it is best practice to use "primary code path" filters wherever possible.

view this post on Zulip JP (Apr 06 2021 at 20:10):

That's actually one of the cases where were looking at optimizing the ELM that the cql-translator produces . [Condition] c where c.code in MyValueSet could be emitted as an ELM Retrieve with the codePath set to code as opposed to a filter after the fact.

view this post on Zulip JP (Apr 06 2021 at 20:12):

(In principle all ELM engines, not just the Java one, would benefit from that optimization)

view this post on Zulip Chris Moesel (Apr 06 2021 at 21:41):

Do any of the popular commercial vendors actually support the :in modifier in their FHIR interfaces? Or is this an optimization that currently only works against some of the open source FHIR servers like HAPI?

view this post on Zulip Bryn Rhodes (Apr 06 2021 at 21:43):

Our experience has been the latter, and so we are currently working on having the planning step take the target system's capability statement into account to determine whether the value set should use the :in modifier, or if it should be in-lined.

view this post on Zulip Aziz Boxwala (Apr 07 2021 at 01:09):

Can a valueset be defined as a literal in CQL? Can be useful for such cases. It may not be practical to have these valuesets be hosted in many a terminology server.

view this post on Zulip Corey Sanders (Apr 07 2021 at 14:02):

I am working with IBM FHIR. It does not currently support the ":in" modifier, but support is coming in the next release.

view this post on Zulip Corey Sanders (Apr 07 2021 at 14:05):

@Aziz Boxwala CQL has a language feature concept that is similar to an inline value set. You can read about it here.

view this post on Zulip Aziz Boxwala (Apr 07 2021 at 14:12):

Thanks @Corey Sanders . concept appears to be equivalent to CodeableConcept. Could we use it as a Valueset?

view this post on Zulip Chris Moesel (Apr 07 2021 at 14:15):

You really shouldn't use it that way. Note that CQL section 4.2.4 explicitly states:

Note that the semantics of Concept are such that the codes within a given concept should all be semantically equivalent at the code level, but CQL itself will make no attempt to ensure that is the case. Concepts should never be used as a surrogate for proper valueset definition.

view this post on Zulip Corey Sanders (Apr 07 2021 at 14:17):

@Chris Moesel @Bryn Rhodes Related to the ":in" modifier and availability in FHIR servers, I'd love to be able to use the CapabilityStatement to determine whether that is there or not, but my experience with HAPI and IBM FHIR servers is that it isn't clearly spelled out in the metadata. Taking the Condition resource as an example, HAPI provides "definition": "http://hapi.fhir.org/baseR4/Condition-code" for the code search parameter, but it doesn't host that resource at that location, so you can't dig in for further detail. IBM FHIR doesn't even provide the definition attribute. I ended up just hard-wiring the Java engine to expand value sets in the term provider vs. letting it try use the ":in" modifier. The default behavior of the RestFhirRetrieveProvider, though, is to try to use the ":in" modifier (e.g. not expand value sets).

view this post on Zulip Aziz Boxwala (Apr 07 2021 at 14:20):

@Chris Moesel another challenge with using the ":in" operator is how the FHIR server resolves the valueset. Should we expect that the FHIR server will have every valueset that I want to use in my CQL expression? Or should it resolve to the URL of the valueset (which is not necessarily a physical address)?

view this post on Zulip Bryn Rhodes (Apr 07 2021 at 15:06):

That is definitely a challenge if the server doesn't advertise it's search parameter modifier support, sounds like we will need to be able to override that definition in some cases.

view this post on Zulip Bryn Rhodes (Apr 07 2021 at 15:08):

As far as versioning of value sets, we are working on an "artifact manifest" definition:
http://build.fhir.org/ig/HL7/cqf-measures/measure-terminology-service.html

view this post on Zulip Bryn Rhodes (Apr 07 2021 at 15:09):

That would you allow you to author artifacts without references to value set versions, but then deploy artifacts that would be specifically bound to particular versions of code systems and value sets. The $package operation would let you build bundles that contain all the required dependencies and deploy those to a target system.

view this post on Zulip JP (Apr 07 2021 at 18:05):

Though it's not yet supported by hapi AFAIK, the TerminologyCapabilities resource is where that could be advertised:

http://www.hl7.org/fhir/terminologycapabilities.html

The cql-engine actually handles that with a property called isExpandValueSets that is set depending on whether or not it's known that the ValueSets and clinical data resources are co-located on the same server:

https://github.com/DBCG/cql_engine/blob/8a11ef270d9f54b74d9996441ce76572fe1374ef/engine.fhir/src/main/java/org/opencds/cqf/cql/engine/fhir/retrieve/SearchParamFhirRetrieveProvider.java#L155


Last updated: Apr 12 2022 at 19:14 UTC