FHIR Chat · Output of cql execution framework · cql

Stream: cql

Topic: Output of cql execution framework


view this post on Zulip Georg Fette (Aug 30 2018 at 09:16):

Hello,
I executed the age.cql example from the cql execution framework documentation using the bundle as well described in the same documentation. The results written to the output console lead me to some questions:
- The cql script is defined to use the context 'patient'. The bundle which is supplied to the script, however, contains two patients. The output of the query looks like both patients were processed. Does the cql interpreter implicitly switch to 'population' mode because no explicit context was given ? Where can the context be set when using the cql execution framework ?
- The script contains no 'retrieve' statement. What is the expected extent of data that is returned by the interpreter ?
- The actual output contains three root objects: patientResults, populationResults and localIdPatientResultsMap. What are the semantics of the objects populationResults and localIdPatientResultsMap ?
- Is there a documentation how the output is syntactially defined ? There are standard patient resource instance serializations in JSON contained in the output, but parts of the surrounding objects (_bundle, patientResults, populationsResults) look proprietary.
- The 'patientResults' output contains both patients from the input bundle. Both patients are encapsulated by an object denoted by their ID (i.e. "1" and "2") in which the respective patient resource instance is contained, as well as the "InDemographic" definition from the cql script. Are all definitions from all included cql scripts contained in the results when these definitions relate to the returned resources ?
- The bundle to which each patient belongs to is also contained in the result. Is this the standard behavior how a FHIR resource instance is serialized in JSON ? This way the output looks a bit verbose when all referenced resource instances are also contained in the output.
- Is the syntactical format of the output independent of the model used in the cql script ?
Greetings

view this post on Zulip Chris Moesel (Aug 31 2018 at 12:13):

Hi George. I'm just seeing this now. I'll try to answer your questions as best I can this morning.

view this post on Zulip Chris Moesel (Aug 31 2018 at 16:29):

Hi @Georg Fette, these are good questions. I'll do my best to answer them. First, I'd like to point out a few things:

1. The CQL specification doesn't prescribe how results should be returned from a CQL execution process — so many of the aspects of how the results are returned (and wrapped) by the cql-execution project are implementation details (not spec-prescribed details).
2. The example you pointed to uses the QUICK data model, which in this code base is not fully implemented and is based on an old interim FHIR release (v1.6 if I remember correctly). In other words, it's a rough example.
3. You may want to look at cql-exec-examples, which provides a more fully featured example of executing CQL using a FHIR DSTU2 data model and value sets defined in the NLM Value Set Authority Center. This is a better example as it uses CQL execution, data model, and code service implementations that have been piloted in actual clinical settings (although with different CQL).

Now to your specific questions:

The cql script is defined to use the context 'patient'. The bundle which is supplied to the script, however, contains two patients. The output of the query looks like both patients were processed. Does the cql interpreter implicitly switch to 'population' mode because no explicit context was given ? Where can the context be set when using the cql execution framework ?

The CQL execution engine is designed to be able to execute against multiple patients in sequence — so if you want to run a quality measure against a set of patients, it can be done in one call with one aggregated result. In the returned JSON document, the patientResults object includes the individual results for each patient (run in Patient context). The populationResults contains the results from the Population context, if applicable. In the example you used, nothing is done in the Population context, as indicated by the empty object for populationResults.

The script contains no 'retrieve' statement. What is the expected extent of data that is returned by the interpreter ?

I'm not sure I fully understand this question, but you can see the cql-exec-examples for an example that includes 'retrieve' statements. As for what data the interpreter (CQL execution) returns, it essentially returns the results of executing each defined expression in the CQL. For example, if the CQL defines expressions called Foo and Bar, then for each patient, the CQL execution engine will return the results of evaluating the Foo and Bar expressions.

The actual output contains three root objects: patientResults, populationResults and localIdPatientResultsMap. What are the semantics of the objects populationResults and localIdPatientResultsMap ?

I covered some of this above, but here's a summary:

  • patientResults contains the Patient context results for each patient bundle passed into it. It's indexed by patient ID.
  • populationResults contains the Population context results based on the entire population of patients passed into it. If the CQL doesn't have a Population context, then this result will be empty.
  • localIdPatientResultsMap was introduced and is used by the Bonnie project. To be completely honest, I don't remember exactly how it works.

Is there a documentation how the output is syntactially defined ? There are standard patient resource instance serializations in JSON contained in the output, but parts of the surrounding objects (_bundle, patientResults, populationsResults) look proprietary.

As noted at the top of my response, these aspects of the results are implementation details not defined (or addressed) by the CQL specification. Unfortunately, we have not documented these result formats, but at least the patientResults and populationResults formats are pretty simple:

{
  "patientResults": {
    "$patientId_1": {
      "Patient": { /* Patient 1 data */ },
      "$patient_ctx_expression_1": /* patient context expression 1 result for patient 1 */,
      "$patient_ctx_expression_2": /* patient context expression 1 result for patient 1 */
    },
    "$patientId_2": {
      "Patient": { /* Patient 2 data */ },
      "$patient_ctx_expression_1": /* patient context expression 1 result for patient 2 */,
      "$patient_ctx_expression_2": /* patient context expression 2 result for patient 2 */
    }
  },
  "populationResults": {
    "$population_ctx_expression_1": /* population context expression 1 result */,
    "$population_ctx_expression_2": /* population context expression 2 result */
  }
}

The 'patientResults' output contains both patients from the input bundle. Both patients are encapsulated by an object denoted by their ID (i.e. "1" and "2") in which the respective patient resource instance is contained, as well as the "InDemographic" definition from the cql script. Are all definitions from all included cql scripts contained in the results when these definitions relate to the returned resources ?

As noted above, the patientResults contains the results of each expression in the Patient context for each patient. You actually see Patient as one of the keys because CQL implicitly adds a Patient expression into the Patient context. As for whether it includes the results of expressions in every CQL library referenced (e.g., CQL libraries "used" by the primary CQL library) — I'm not sure. I'd have to look into that. I know it at least returns every expression from the primary library passed in.

The bundle to which each patient belongs to is also contained in the result. Is this the standard behavior how a FHIR resource instance is serialized in JSON ? This way the output looks a bit verbose when all referenced resource instances are also contained in the output.

The inclusion of _bundle in the result is an implementation detail of the QUICK data model binding used by the example — which stores the whole bundle in the patient object. If you look at the cql-exec-examples I referenced at the top of this response, it does not include the entire bundle in the response. I agree that it's rather redundant and unnecessary in this case.

Is the syntactical format of the output independent of the model used in the cql script ?

Yes, to the extent that the execution returns CQL results, those results may contain data formatted according to the data model used by the CQL. The overall result container (with patientResults and populationResults) wouldn't change based on the model, but the expression results could.

It's also worth noting that results reflecting data types from the model will usually take on a syntax similar to how the model is defined in its model-info file. This is important to note because the FHIR DSTU2 model (used in cql-exec-examples) may return some data type results that don't conform fully to the FHIR-defined JSON format (but do conform to the way the FHIR DSTU2 model is described in its model-info file). For example, primitives might be serialized as an object with a value property rather than the direct value itself (as in FHIR JSON). We may at some point modify this behavior so that when results are converted to JSON, they serialize to FHIR-compliant versions, but it's not in any direct plans right now.

Anyway, I hope this has been helpful. Thanks for asking some good questions and I hope the execution framework works well for you.

view this post on Zulip Georg Fette (Sep 06 2018 at 07:55):

cool, thank you for the detailed response.


Last updated: Apr 12 2022 at 19:14 UTC