clinical-reasoning icon indicating copy to clipboard operation
clinical-reasoning copied to clipboard

CQL to ELM Translations Question

Open jmfadeley opened this issue 3 years ago • 7 comments

For our main project, we've been using a forked version of cql-execution to handle our processing, using CQL-to-ELM translations from clinical_quality_language with .json as our output. From a partner we're working with, we confirmed the results of this arrangement are correct.

We've been looking at cql-evaluator to see if it is faster than the other option. Unfortunately, we trying to use the same CQL, we're getting very different results against the same data. Are there any tips on how to handle the translation? Or is there a way to use XML or JSON directly, skipping the CQL translation?

jmfadeley avatar Oct 26 '22 02:10 jmfadeley

Further information. I believe I've traced the source of the issue to a List of objects we've thrown into our CQL. But this is sidestepping another issue we've run into in which ArrayLists cannot be cast as Tuples.

Cannot cast a value of type java.util.ArrayList as org.opencds.cqf.cql.engine.runtime.Tuple.

We've tried running this in compatibility level 1.4 but to no avail. Rather than worry about the above, do you have any tips on this issue?

jmfadeley avatar Oct 26 '22 16:10 jmfadeley

Hi @jmfadeley, that doesn't look familiar, but it definitely looks like the translator model and the runtime resolution are out of sync. Any way you could provide a reproduction?

brynrhodes avatar Oct 27 '22 21:10 brynrhodes

Related to the JavaScript and Java engines, we have a set of test cases published as part of the CQL specification that we are both working to get passing. There are quite a few tests, so the Java engine is not completely passing right now, and I'm not sure the state of the JavaScript engine, but both teams are working towards parity, so if you have identified a specific inconsistency between the two, we'd love to know about it so we can address it.

brynrhodes avatar Oct 27 '22 21:10 brynrhodes

Well... that closure was a genius "this is a button" moment on my part.

The issue here seems to relate to your post at... https://github.com/cqframework/CQL-Formatting-and-Usage-Wiki/wiki/Implementing-the-CQL-1.5-Terminology-Types

We're using CQL from the NCQA. The problem occurs with the "VS Cast Function" statement (the error above), which is a core function of theirs. Due to our agreement, I don't think I can C&P the CQL function itself. The function (I believe) is taking an ArrayList of System.Codes for the value set, and casting it into Tuples of the codes, oid, and version.

With the clinical_quality_language repo, we've been able to compile working .json outputs by setting the --compatibility-level=1.4 and processing that. I haven't had luck with the cql-evaluator. These are the options we've been trying:

{
  "options":[
    "EnableAnnotations",
    "EnableLocators",
    "DisableListDemotion",
    "DisableListPromotion"
  ],
  "formats":[
    "JSON"
  ],
  "validateUnits":false,
  "verifyOnly":false,
  "errorLevel":"Info",
  "signatureLevel":"None",
  "compatibilityLevel": "1.4",
  "analyzeDataRequirements":false,
  "collapseDataRequirements":false
}

We'll take any advice you can give us.

jmfadeley avatar Oct 28 '22 04:10 jmfadeley

Ah, yes, the VS Cast Function. That function is effectively directly manipulating the JavaScript internal terminology representation structures, so it's not surprising that it isn't portable to the Java logic. The particular manipulation it's doing isn't necessary in the Java engine, so if you just change the function to be a no-op (i.e. just return the argument) then it should work.

brynrhodes avatar Oct 28 '22 14:10 brynrhodes

That definitely got us past the casting issue. The results coming back aren't correct however. Diving into it... is any instance of a Tuple problematic? There are several in the core libraries.

jmfadeley avatar Oct 28 '22 19:10 jmfadeley

Please disregard the recent tuples comment, I've somewhat isolated the issue. It might be a logic difference between the JavaScript and Java engines.

The define in question gets a list of episode dates and checks a where not against four conditions using or. The CQL structure is like this:

define "Episode Sans Exclusions":
  ( "Episode Date Getter" episodeDate
    where not ( "Condition 1"(episodeDate)
        or "Condition 2"(episodeDate)
        or "Condition 3"(episodeDate)
        or "Condition 4"(episodeDate)
    ) ) episodesSansExcl
    return date from start of episodesSansExcl
    sort asc

I've broken this definition apart by the Condition define functions that return something and those that don't, there's some discrepancy in where not. The results are below (left is with the JavaScript, right is the Java engine):

image

The JAMES 1 CORRECT only runs the conditions that return a date, so they get picked up. JAMES 1 COMORBID and JAMES 1 COMPETING use just where. JAMES 1 NOT COMORBID and JAMES 1 NOT COMPETING use where not to check the logic.

When running all four conditions together, the Java seems to assume any empty array means the whole results set is empty. image

PS, apologies if you read this from your email... I had to edit this for wording/clarification and fix an erroneous picture.

jmfadeley avatar Oct 28 '22 22:10 jmfadeley