Application Data-sets
Problem Description
I've been recently messing around with ADL-designer, and thinking more about how to do application building with templates. A few things are becoming clearer to me. Firstly, templates based on COMPOSITION (or PARTY, PERSON etc, for demographics) are potentially good for data capture, but don't in general make sense for data retrieval.
For a retrieval data set, e.g. a screen containing a combination of demographics, EHR clinical, other info, we need another kind of container. Let's call this DATA_SET for the moment, and assume it is defined as follows:
class DATA_SET inherit LOCATABLE content: LOCATABLE [*] end
Then an archetype of this could be built for a screen, and it could insert SECTIONS purely for display purposes. Maybe it could include style information. So let's imagine that instead of just SECTIONs we could use something a bit smarter, like DATA_GROUP. We could then create a template like the following (each included archetype is actually an overlay based on an underlying archetype):
DATA_SET[id1] matches { content matches { DATA_GROUP[id2] matches { name matches {[at20]} -- "Patient details" style matches {1} -- area; from an enumeration of tabs|menu|area|etc items matches { use_archetype PERSON[id3, openEHR-EHR-PERSON.ovl_patient_details_1.v1] } } DATA_GROUP[id4] matches { name matches {[at21]} -- "Clinical" style matches {1} -- area; from an enumeration of tabs|menu|area|etc items matches { DATA_GROUP[id6] matches { name matches {[at22]} -- "First trimester" style matches {0} -- tabs items matches { use_archetype OBSERVATION [id7, openEHR-EHR-OBERVATION.ovl_first_trimester_summary_1.v1] } } DATA_GROUP[id8] matches { name matches {[at23]} -- "Second trimester" style matches {0} -- tabs items matches { use_archetype OBSERVATION [id9, openEHR-EHR-OBERVATION.ovl_second_trimester_summary_1.v1] } } DATA_GROUP[id10] matches { name matches {[at24]} -- "Third trimester, first part" style matches {0} -- tabs items matches { use_archetype OBSERVATION [id11, openEHR-EHR-OBERVATION.ovl_third_trimester_summary_1.v1] -- overlay 1 } } DATA_GROUP[id12] matches { name matches {[at25]} -- "Third trimester, last month" style matches {0} -- tabs items matches { use_archetype OBSERVATION [id13, openEHR-EHR-OBERVATION.ovl_first_trimester_summary_2.v1] -- overlay 2 } } } } } }
Notice that now we have demographic data (magenta) and EHR data (blue) easily mixed in; we have a rough screen layout defined, something like two HBOX areas, with the second one having tabs inside for the various pregnancy trimesters.
In this construction, the only real data are the included archetypes; the outer DATA_SET and DATA_GROUPs are just defined structures that are created on the fly by a screen renderer. Different types of DATA_GROUP could be used to provide the UI hints we often talk about - use tabs, use a box with a name, and so on - people familiar with the typical UI elements like HBOX, VBOX, TREE, MENU, MENU_ITEM, DATE_FIELD, TEXT_FIELD (the names differ across UI toolkits) will see that this approach could be used to more or less fully define whole screens. A similar thing could be done to define messages or documents.
Paths through such a structure would effectively be paths to parts of a form (or a message), and could be referenced in other sections of the template to control visualisation.
We could embed the generating queries as well for example:
DATA_SET[id1] matches { content matches { DATA_GROUP[id2] matches { name matches {[at20]} -- first trimester query matches { "SELECT obs FROM EHR[$ehr_id] CONTAINS summary COMPOSITION[openEHR-EHR-COMPOSITION.pregnancy_summary.v1] WHERE summary/context/start_date > $current_date - P1Y " } style matches {0} -- tabs; from an enumeration of tabs|menu|etc items matches { use_archetype OBSERVATION [id3, openEHR-EHR-OBERVATION.ovl_first_trimester_summary_1.v1] } } etc } }
Doing the above requires adding some new classes to the RM, or a Presentation Model part of openEHR. It seems to me it would make application software development much easier, and substantially more automatable.
I am aware that other people with far more app/UI experience than I have worked intensively on specifying UI forms, application elements and so on, and have some very smart tools for such purposes. I am therefore not really claiming anything new here, just considering ways to formalise such ideas in a way that would make use of existing tools and formalisms that we have.
Existing Data-set / Visualisation Models
UITemplate Model - Pablo Pazos
This approach appears to be very compatible, or even a solution to the problem posed above. See the original reference for explanation. A model of UI semantics is proposed in this approach that is the kind of thing proposed above:
In the above, the UITemplate class is probably equivalent to the DATA_SET class in the original proposal; the ZoneContainer class is roughly equivalent to the DATA_GROUP class. The model above supports more than one 'layout' per UI template.
UITemplate artefacts would be processed into concrete deployable UI forms as follows.
The original proposal was intended to support not only UI/UX but also other retrieval data sets, e.g. extracted messages, documents etc. One way to do this might be to separate the data-set / data-group definition from its presentation - that is to use bother kinds of layers - a simple model of DATA_SET / DATA_GROUP as described earlier, and then a UI_TEMPLATE approach as shown above; a MESSAGE_TEMPLATE could be constructed in the same way but with meta-data oriented to messaging.
According to the original proposal, relevant class in both levels of such a model would inherit from LOCATABLE to make them archetypable, and thus processable by BMM-driven archetype tools.
Original reference - google docs.
RippleOSI
(From Tony Shannon, 18 Feb 2018, openEHR technical list)
Our approach has been a very deliberately clinically driven, user centred design approach, which has then driven the openEHR templates that underpin, but the UX is #1 in importance to frontline clinicians, not the data models.
(Still, all the key data is our stack created/updated/persisted in EtherCIS (& Marand) CDR using a RESTful JSON API.)
We know that many folk are doing/ do direct mapping from data models to UI eg we could have chosen to feed the UI framework with openEHR JSON API directly. We also know that then raises somewhat of a data migration challenge if you're sitting on any legacy non openEHR data (which most folk are), hence we use a middleware element (QEWDjs) which handles the mapping from both openEHR & non openEHR sources into the same UI JSON. We explain the rationale for that in this article, where we describe 5 step wise levels of integration between non openEHR & openEHR systems, that our UX framework accomodates. From this article:
As part of our work towards this open platform push the key aspects of our chosen PulseTile UX/UI framework – this framework follow key patterns in clinical process and information management, from business/clinical intelligence to multi-patient view to single patient view – all focused around a few key UI patterns.
Previous gui-generation-related discussions (add more if you find)
Publications
- H. van der Linden, T. Austin, J. Talmon, Generic screen representations for future-proof systems, is it possible? There is more to a GUI than meets the eye, Comput Methods Programs Biomed. 95 (2009) 213–226. doi:10.1016/j.cmpb.2009.03.003.
- Model Driven Development of Clinical Information Sytems using openEHR
Koray ATALAG , Hong Yul YANG, Ewan TEMPERO, Jim WARREN
Mailing list posts/threads
- 2008; GUI-hints in openEHR templates? (Was: PatientOS archetype to form demo (of sorts)) https://www.mail-archive.com/openehr-technical@lists.openehr.org/msg03855.html
2011; GUI-directives/hints again (Was: Developing usable GUIs) https://www.mail-archive.com/openehr-technical@lists.openehr.org/msg04892.html
- ...
Wikipages (including comments)
Possible Use Cases
OPT form renderer needed for pilot testing of surgery process supporting system
Region Östergötland is building an openEHR based extension for EHR parts extending the homegrown "OpGuide" surgery process supporting system. An RFI for openEHR platforms was been sent out, closing March 15 (possibility for questions closed March 8), but likely any following procurement processes time will extend beyond the time when final preparations for the first clinical pilot testing of the system needs to start. Thus one of the current main candidates is to use Ethercis or some other open source (or free) openEHR-REST-API-backend that we can host locally with real patient data during the pilot phase (late 2018/early 2019). After that, before wider roll out, we hope that the procurement processes might have lead to more options. This leads to a plan that is open for discussion and open collaboration:
- We need to at least support OPT form rendering, but components for formatted AQL response rendering and some other things are also high on the list.
- Licence under permissive open source licence, preferably Apache 2
- We plan to use the latest stable Angular release (currently 5.x). The plan is to generate "Angular templates" (see https://angular.io/guide/architecture) with reasonably readable syntax based on:
- OPTs processed via Ethercis new OPT introspection that produces a "JSON template" that will be further processed by a "web/angular template generator" (that we need to build).
- Hand coded configurable "Angular Components" based on the openEHR RM and configurable via OPT annotations, for example the ones suggested by CaboLabs above, like CODED_VALUE_MULTI_CHECK
- Hand coded configurable "Angular Services" for common functionality such as wrapping calls to terminology servers, composing and serialising form components in openEHR format before submission etc
Example: Provided we have made an Angular component for "selection" (that can be configured as multi-selection checklists) and an angular component for DV_ORDINAL, then a partial angular template snippet could look something like
<selection class="multi-check" path="/content[openEHR-EHR-SECTION.adhoc.v1]/items[openEHR-EHR-OBSERVATION.demo.v1]/data[at0001]/events[at0002]/data[at0003]/items[at0004]/items[at0012]">
<DV_ORDINAL default="true" value="0" terminology="local" code="at0038">No pain</DV_ORDINAL>
<DV_ORDINAL value="1" terminology="local" code="at0039">Slight pain</DV_ORDINAL>
<DV_ORDINAL value="2" terminology="local" code="at0040">Mild pain</DV_ORDINAL>
</selection>
The example above is a non-tested not so well thought through example, so syntax and structure will likely change, one might for example want to nest a <DV_CODED_TEXT> inside the <DV_ORDINAL> instead of having corresponding info in attributes. Also path format or length might be different. Se below for some alternatives of another example.
The approach could be used either for only current OPT COMPOSITION-based storage forms or also for wider application builds as described above.
The present draft system sketch (open for change, improvment and discussion) is provided below. (Erata: The Developers also need to code the "Web Template Generator")
This section (...renderer needed for pilot testing of surgery process...) was added by Erik Sundvall on behalf of the Region Östergötland "GOLI(a)T"-project that, among other things, extends OpGuide.
Other alternative angular template formats
Based on the example https://github.com/ethercis/ethercis/blob/master/doc/OPT%20introspection.md#dv_coded_text
<DV_CODED_TEXT attribute_name="value">
<constraints attribute_name="defining_code" min_op=">=" min="1" max_op="<=" max="1" class="radio-buttons">
<constraint code_string="at1003" terminology="local" description="The subject was standing." value="Standing"></constraint>
<constraint code_string="at1001" terminology="local" description="The subject was sitting (for example on bed or chair)." value="Sitting"></constraint>
</constraints>
...TO BE CONTINUED ANOTHER DAY...
TBD: If a recieving platform uses ECISFLAT-format then then perhaps using the compact syntax "terminology::code" for CODE_PHRASE or "terminology::code|value|" for DV_CODED_TEXT content alternatives would be an option?'
<selection class="multi-check" min="1" max="1" class="radio-buttons" path="/content[openEHR-EHR-SECTION....">
<DV_CODED_TEXT defining_code="local::at1003" description="The subject was standing.">Standing</DV_CODED_TEXT>
<DV_CODED_TEXT defining_code="local::at1001" description="The subject was sitting (for example on bed or chair).">Sitting</DV_CODED_TEXT>
</selection>
...TO BE CONTINUED ANOTHER DAY...
TBD: or more HTML-like from the beginning
<select class="multi-check" min="1" max="1" class="radio-buttons" path="/content[openEHR-EHR-SECTION....">
<option><DV_CODED_TEXT>local::at1003|Standing</DV_CODED_TEXT><description>The subject was standing.</description></option>
<option><DV_CODED_TEXT>local::at1001|Sitting</DV_CODED_TEXT><description>The subject was sitting (for example on bed or chair).</description></option>
</select>
...TO BE CONTINUED ANOTHER DAY...
References
Koray ATALAG , Hong Yul YANG, Ewan TEMPERO, Jim WARREN