Open jeffeastman opened 7 years ago
I haven't been a part of these conversations, but incorporating expressions is an interesting idea. One thing I'd suggest is that you consider alignment with the HL7 Clinical Quality Language (CQL).
This is a health IT expression language designed by MITRE (and sponsored by CMS & ONC) that is primarily used in eCQM and CDS, but is also quite fit for other applications. In short, it actually has two components: a human-readable authoring language (CQL) and an abstract syntax tree style logical model (ELM). Looking at your examples, they seem very close to the JSON serialization of ELM -- so I think alignment might not require too much effort and would provide some nice consistency.
Anyway, just throwing that out there as an interested spectator. Let me know if you'd be interested in seeing some ELM JSON examples. Also, the CQL repository has some XML examples available, from which you can easily imagine the corresponding JSON representations.
+1 I have also noted this similarity and would be keen to move to CQL/ELM representation. I need to do more reading on these topics so any suggestions or examples would be appreciated.
I've made some terminology changes to better align with the ELM nomenclature. Here's a revised document that describes them with the vital_signs module updated. I have this working in my implementation. The json is still a ways from what I perceive it should be from the xml definitions and examples I've found, but I have not found any good json examples to reference. Since you MITRE folks designed ELM, perhaps you could help me get this to a better representation?
Hi @jeffeastman. Unfortunately, my other projects have been keeping me from being able to provide much guidance here. I just remembered, however, that there are JSON examples available in our execution engine test suite.
One thing that's kind of nice is that the examples are split up nicely into folders by the functional aspect of the expression (e.g., aggregate, arithmetic, clinical, comparison, conditional, etc). So if you want to see an example for a specific CQL/ELM feature, it should be fairly easy to find (if the example exists). In each subfolder, you'll find a data.cql file with CQL snippets and a data.coffee file with corresponding ELM JSON expressions (generated by the CQL-to-ELM tool).
Again, I apologize I haven't been able to provide more hands-on support with this...
Oh yes, that helps a lot! Thanks Chris,
eJeff
On Apr 20, 2017, at 9:11 AM, Chris Moesel notifications@github.com wrote:
Hi @jeffeastman https://github.com/jeffeastman. Unfortunately, my other projects have been keeping me from being able to provide much guidance here. I just remembered, however, that there are JSON examples available in our execution engine test suite.
https://github.com/cqframework/clinical_quality_language/tree/master/Src/coffeescript/cql-execution/test/elm https://github.com/cqframework/clinical_quality_language/tree/master/Src/coffeescript/cql-execution/test/elm One thing that's kind of nice is that the examples are split up nicely into folders by the functional aspect of the expression (e.g., aggregate, arithmetic, clinical, comparison, conditional, etc). So if you want to see an example for a specific CQL/ELM feature, it should be fairly easy to find (if the example exists). In each subfolder, you'll find a data.cql file with CQL snippets and a data.coffee file with corresponding ELM JSON expressions (generated by the CQL-to-ELM tool).
Again, I apologize I haven't been able to provide more hands-on support with this...
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/synthetichealth/synthea/issues/189#issuecomment-295732825, or mute the thread https://github.com/notifications/unsubscribe-auth/AIO2lJo1l0bFDyNYbMAe5FFOdFTFyYJKks5rx1lygaJpZM4M_I2f.
I took a stab at refactoring Operands. Since its still a work in progress I'll save the document update for later. Here's an example of Creatinine Clearance. Looks pretty good except for the Variable stuff. Still working on that and looking over the other examples.
Do you have any suggestions for accessing patient information? Variables don't seem to have an ELM precedent.
{
"type": "Multiply",
"operand": [
{
"type": "Divide",
"operand": [
{
"type": "Multiply",
"operand": [
{
"type": "Subtract",
"operand": [
{
"valueType": "Decimal",
"value": 140.0,
"type": "Literal"
},
{
"context": "Patient",
"sign": "Age(yr)",
"type": "Variable"
}
]
},
{
"context": "Patient",
"sign": "Weight",
"type": "Variable"
}
]
},
{
"type": "Multiply",
"operand": [
{
"valueType": "Decimal",
"value": 72.0,
"type": "Literal"
},
{
"context": "Patient",
"sign": "Creatinine",
"type": "Variable"
}
]
}
]
},
{
"condition": {
"context": "Patient",
"sign": "isMale",
"type": "Variable"
},
"then": {
"valueType": "Decimal",
"value": 1.0,
"type": "Literal"
},
"else": {
"valueType": "Decimal",
"value": 0.85,
"type": "Literal"
},
"type": "If"
}
]
}
Ditching Variables and Ranges in favor of predefined Functions. Here's an example of Creatinine Clearance (eGFR). Much simpler and fully ELM:
{
"type": "Multiply",
"operand": [
{
"type": "Divide",
"operand": [
{
"type": "Multiply",
"operand": [
{
"type": "Subtract",
"operand": [
{
"valueType": "Decimal",
"value": 140.0,
"type": "Literal"
},
{
"name": "AgeInYrs",
"type": "FunctionRef",
"operand": []
}
]
},
{
"name": "VitalSign",
"type": "FunctionRef",
"operand": [
{
"valueType": "String",
"value": "Weight",
"type": "Literal"
}
]
}
]
},
{
"type": "Multiply",
"operand": [
{
"valueType": "Decimal",
"value": 72.0,
"type": "Literal"
},
{
"name": "VitalSign",
"type": "FunctionRef",
"operand": [
{
"valueType": "String",
"value": "Creatinine",
"type": "Literal"
}
]
}
]
}
]
},
{
"condition": {
"name": "isMale",
"type": "FunctionRef",
"operand": []
},
"then": {
"valueType": "Decimal",
"value": 1.0,
"type": "Literal"
},
"else": {
"valueType": "Decimal",
"value": 0.85,
"type": "Literal"
},
"type": "If"
}
]
}
If we chose this path, then a module authoring tool could use CQL to specify the expressions. This could then be parsed into EML to live in the Json representation. Still editable by mortals, but pretty verbose in comparison with CQL.
In the above, I considered using Retrieve for the Vital Signs but took the KISS path instead. If we wanted to refactor all module Logic to use CQL/ELM, then this would be needed.
Here's a link to a good Java CQL engine. Here's another link that I've found has useful clinical_quality_language artifacts. I've found ELM Expressions useful in computing values for Observation, SetAttribute, Symptom, VitalSign and Logic.
Adding an enhancement request that's been discussed on various email threads. I have a working implementation that I use to initialize and age vital signs. In a nutshell, Expressions have the following subtypes that are more fully defined in the attached document:
Expressions for Synthea v2.docx