GDL 2.1

GDL 2.1

Placeholder for improvement ideas planned for GDL 2.1

REST APIs

APIs for GDL2 guideline execution and definition endpoints.

Multi-model data bindings

Support multiple input bindings for a single guideline variable (typically as @gt0001 in rule expressions), to allow further decoupling of rules and input data bindings. For example a published BMI calculation is modelled with v1 of openEHR-EHR-OBSERVATION.body_weight and openEHR-EHR-OBSERVATION.height.v1 archetypes, it should be possible to add support for v2 of both archetypes without breaking the support for v1 based input.

Example of multi-model bindings (notice gt0015 is bound to two possible input models)

"data_bindings": { "gt0014": { "id": "gt0014", "type": "INPUT", "models": { "openEHR-EHR-OBSERVATION.body_weight.v1": { "model_id": "openEHR-EHR-OBSERVATION.body_weight.v1", "elements": { "gt0015": { "id": "gt0015", "path": "/data[at0002]/events[at0003]/data[at0001]/items[at0004]" }, "gt0016": { "id": "gt0016", "path": "/data/events/time" } }, "predicates": [ "max(/data/events/time)" ] }, "org.hl7.fhir.r4.model.Observation": { "model_id": "org.hl7.fhir.r4.model.Observation", "elements": { "gt0015": { "id": "gt0015", "path": "/valueQuantity" }, "gt0016": { "id": "gt0016", "path": "/effectiveDateTime" }, "gt0017": { "id": "gt0017", "path": "/code/coding[0]" } }, "predicates": [ "/code/coding[0] is_a local::gt0018|Weight code|", "max(/effectiveDateTime)" ] } }

Tests

The guideline tests are designed to provide automated test coverage of clinical algorithms expressed in GDL format. These are unit level tests consist of input data and expected output grouped by short use case names.

In the guideline editor, these tests are generated as guidelines being manually tested and can be saved for test automation in later down stream steps.

Example of guideline test (in yaml format):

current_datetime: 2024-05-20T02:00:00+02:00 guidelines: "1": BMI.v1.1.2 test_cases: - id: Normal range input: "1": gt0002|Weight: 64,kg gt0003|Height/Length: 180,cm expected_output: "1": gt0004|Body Mass Index: 19.753,kg/m2 gt0009|BMI classification: 3|local::at0014|Within normal range|

Included data types

In the original GDL2.0 specification, the acutal data types of data bindings are not recorded in the guideline definition. Within the gudieline editor, as long as the definition of used archetype is accessbile the data types will be retrieved from relevant archetype. However at runtime, it is not always feasible to provide archetype definitions.

Example of GDL2.0 binding:

"openEHR-EHR-OBSERVATION.body_weight.v1": { "model_id": "openEHR-EHR-OBSERVATION.body_weight.v1", "elements": { "gt0015": { "id": "gt0015", "path": "/data[at0002]/events[at0003]/data[at0001]/items[at0004]" }, "gt0016": { "id": "gt0016", "path": "/data/events/time" } }

Example of GDL2.1 binding now including data type information:

"model_id": "openEHR-EHR-OBSERVATION.height.v2", "archetype_id": "openEHR-EHR-OBSERVATION.height.v2", "type": "INPUT", "elements": { "gt0003": { "id": "gt0003", "path": "/data[at0001]/events[at0002]/data[at0003]/items[at0004]", "data_type": "DV_QUANTITY", "units": [ "cm", "[in_i]" ] } }

Safe mode execution

This is not a change in the GDL model design, instead this is change of GDL guideline execution. Previously a given rule within a guideline will not run when at least one of the rule conditions are not met (evaluation doesn’t return true). This design makes it necessary to create many boilerplate conditions with sole purpose to make sure whatever variables used in the assignment expressions are initialized with values. This in turn increase the amount of work load, and unncessary complexy of the rules.

Example GDL 2.0 design

"rules": { "gt0030": { "id": "gt0030", "priority": 70, "when": [ "$gt0020|Height value|!=null", "$gt0015|Weight value|!=null" ], "then": [ "$gt5001.magnitude=(($gt0015.magnitude*$gt0020.magnitude)/3600)^0.5", "$gt5001.precision=2", "$gt5001.unit='m2'" ] } }

In contrast, example GDL 2.1 design

"rules": { "gt0030": { "id": "gt0030", "priority": 70, "when": [], "then": [ "$gt5001.magnitude=(($gt0015.magnitude*$gt0020.magnitude)/3600)^0.5", "$gt5001.precision=2", "$gt5001.unit='m2'" ] } }