FHIR Chat · diagnoses algorithms to CQL · cql

Stream: cql

Topic: diagnoses algorithms to CQL


view this post on Zulip Adrien Prost (Jun 08 2021 at 15:25):

Hello, I am working on translating a CDS to CQL format:

Intuitively, having explored a bit CQL, the straightforward way would be to represent the nodes as retrieve statements of observations and conditions and then creating a function which defines the logic of the flowchart and returns the results of the diagnostic. Before implementing this, I was wondering if there was some existing standard (that I overlooked) on representing these algorithms in CQL ?

view this post on Zulip Bryn Rhodes (Jun 10 2021 at 20:55):

@Adrien Prost , you could express that as a decision tree in a PlanDefinition where the conditions on each node reference expressions in CQL. There are groups doing that, and there is even some basic tooling to convert simple decision tables to PlanDefinitions with corresponding CQL libraries. There's some manual work to do after the generation step, but it saves a lot of scaffolding. Here's a project that's using that tooling: https://github.com/who-int/anc-cds/blob/feature_updated_dataelements_with_decision_tables/input/l2/WHO-SRH-21.2-eng.xlsx

view this post on Zulip Adrien Prost (Jun 15 2021 at 16:00):

Thanks @Bryn Rhodes ! I am not aware of what are PlanDefinitions, googling around I landed on this: http://www.hl7.org/fhir/clinicalreasoning-module.html, if you have any links on more docs related to this it would be great :)

view this post on Zulip Adrien Prost (Jun 16 2021 at 10:58):

I have looked at some PlanDefinition examples from http://hl7.org/fhir/R4/plandefinition.html. In these examples I can clearly see the CQL references however I do not see the decision tree logic encoded in the resource, is there any example of a PlanDefinition resource in which a decision tree logic is encoded ?

view this post on Zulip Bryn Rhodes (Jun 16 2021 at 21:57):

@Adrien Prost , here's an example of one of those decision tables represented in a PlanDefinition:

view this post on Zulip Bryn Rhodes (Jun 16 2021 at 21:57):

https://github.com/who-int/anc-cds/blob/master/input/resources/plandefinition/plandefinition-ANCDT03.json

view this post on Zulip Bryn Rhodes (Jun 16 2021 at 21:58):

And the associated CQL for it: https://github.com/who-int/anc-cds/blob/master/input/cql/ANCDT03.cql

view this post on Zulip Bryn Rhodes (Jun 16 2021 at 21:59):

Most of the structure there is generated from the data dictionary and the decision tables. Only the final CQL is "engineered", and even that has pseudo-code coming from the decision tables (see the comments on the expressions in the CQL).

view this post on Zulip Adrien Prost (Jun 17 2021 at 09:33):

@Bryn Rhodes thanks for the pointers, my guess is that in my case the algorithms are more complex than decision tables and therefore I think it is best to encode them using CQL, then have a PlanDefinition Resource with a single action refering to the CQL algorithm

view this post on Zulip Bryn Rhodes (Jun 17 2021 at 18:35):

Yes, that makes sense, and here's an example of that type of usage: https://github.com/cqframework/opioid-cds-r4/blob/master/input/resources/plandefinition/plandefinition-opioidcds-05.xml, and the CQL that it references: https://github.com/cqframework/opioid-cds-r4/blob/master/input/pagecontent/cql/OpioidCDSREC05.cql

view this post on Zulip Adrien Prost (Jul 08 2021 at 15:24):

Hey @Bryn Rhodes I am coming back on this again after continuing my research on how to convert our medical algorithms to CQL code. In our case, we are working with complex consultation medical algorithms for patient consultations for which the order in which the questions and observations on patients is done is of great importance. To be more specific, our CDS algorithms are complex decision trees where nodes may have multiple outgoing edges / descendant nodes and we wish to use CQL to guide patient consultation. My initial guess was to proceed in the following way:

  • We represent the algorithm using a CQL function define algorithm() which returns a List of strings where each string is either a possible diagnose, or a string indicating that a specific measurement/questions should be asked (example "question X") to the patient as the algorithm cannot output more possible diagnoses as there are missing measurements on the patient.
  • We then create clauses for each questions that could be asked to a patient: for example:
define "should ask question X" :
    algorithm() contains "question X"
  • For each possible question, a PlanDefinition Resource is created which activates under the condition that the "should ask question X" clause evaluates to true.
  • The consultation would work as follows: the patient would answer basic mandatory questions and Observation/Condition resources will be uploaded to the FHIR server. Depending, on the observations, the clinical reasoning module will activate and return PlanDefinition resources to the consultation that indicate what are the next questions to be asked to the patient.

I was wondering if this workflow makes sense or if I am overlooking at some FHIR resources that could be more useful in this context. The problem with this approach is that the algorithm() CQL function (which will be pretty complex) would be evaluated many times for each possible question at each iteration.

view this post on Zulip Bryn Rhodes (Jul 08 2021 at 16:25):

Would it make sense to collapse the questions into a single PlanDefinition with multiple actions? Each action can have an applicability condition, so you could potentially model the whole process in a single PlanDefinition (or potentially a set of PlanDefinitions appropriately modularized).

view this post on Zulip Bryn Rhodes (Jul 08 2021 at 16:27):

As far as evaluation, the simplest case would evaluate all the expressions on every iteration, but it would be potentially straightforward to implement some optimization there so that the evaluation only asked for evaluation of expressions relevant in the decision tree.

view this post on Zulip Bryn Rhodes (Jul 08 2021 at 16:28):

In addition, the Java-engine at least can do caching of expression evaluation, but it only does it on Expressions currently. Is there a reason to define algorithms() as a function without parameters, as opposed to an expression definition?

view this post on Zulip Adrien Prost (Jul 09 2021 at 07:25):

No, indeed I have wrongly assumed that expressions only returned boolean values, but apparently this is not the case. I would then ask what is the difference between both ?

view this post on Zulip Bryn Rhodes (Jul 14 2021 at 19:12):

The difference is syntactic from an invocation perspective, but from a definition perspective, a function is allowed to be external.


Last updated: Apr 12 2022 at 19:14 UTC