Status: this page is in development.
Overview
NOTE: In this page, we use the term ‘decision logic module’ (DLM) for convenience, and it should not be taken to be a permanent name. Other names such as ‘computerised guideline module’ (CGM), ‘clinical practice guideline’ (CPG) etc are also common.
The problem
The aim of this page is to describe the form of a ‘decision logic module’ (DLM) that can be used in at least the following scenarios:
...
This achieves the same effect as the openEHR Element
type, just in a simpler type system. This approach enables typical null-value rules to be defined, such that an expression such as ejection_fraction > 20%
will not cause an exception even if the ejection_fraction
raw value is null. Of course it is usually better to test for defined (ejection_fraction)
first, if ejection_fraction
was defined as Quantity?
.
QUESTION: We might have to consider whether using the ‘?' declaration obscures the difference between a 'non-available’ variable (i.e. no value available from the outside world) and one that is simply null in the standard programming language sense. If we assume that the latter can happen within datasets and guidelines, we might want to allow both Type?
and e.g. the use of the explicit type Data_item<T>
to distinguish the two cases.
Effective time
Sometimes the clinically significant time of a data item needs to be accessed in rules. This can be done by the reference x.effective_time
, e.g. ejection_fraction.effective_time
returns when the ejection fraction measurement being used was taken. For a variable like is_diabetic
, it means when the diagnosis was made.
...
Code Block | ||
---|---|---|
| ||
class ProxyVarProxy_var <T> { name: String currency: Duration value: T { // get the value, e.g. by a call like // subject_proxy.getValget_val(name, currency) } } class ProxyVarQuantityProxy_var_quantity extends ProxyVar<Quantity>Proxy_var<Quantity> { // map of named value ranges ranges: Map <CodedTerm<Terminology_code, Interval<Quantity>> // range in which the current value is range: CodedTermTerminology_code { // return which range in 'ranges' value is in } // range in which the current value is in_range (a_range: Terminology_code): Boolean { // return True if range = a_range } } |
In an expression such as platelets < 60 x 10^9/L
, the platelets
reference is understood as a call to ProxyVarQuantityProxy_var_quantity.value
, which retrieves the actual value (it would require an internal reference to the Subject Proxy to do this). In an expression like platelets.in_range = (low)
, the platelets.in_range()
is a call to ProxyVarQuantity.range
Proxy_var_quantity.in_range()
.
According to this scheme, the execution of the declarations of is_diabetic
or platelets
causes creation of ProxyVarXxx
Proxy_var_xxx
objects that have access to the Subject Proxy data cache by making calls like getValueget_value(“is_diabetic”)
or perhaps typed calls like getQuantityValueget_quantity_value(“platelets”)
. How the Subject Proxy gets its data depends on the bindings of named variables like is_diabetic
to back-end binding meta-data such as AQL queries (for openEHR access), HL7 FHIR calls/resources for FHIR, and whatever other methods are available for other kinds of data source.
When a ProxyVar
Proxy_var
object is created, it would need to register the named variable, type, currency and possible the ‘hint’ meta-data described earlier, in the Subject Proxy component, for the current patient.
...