Agreeing on optional user interface hints in templates

I totally understand the convenience factor of adding many things into the same place. But what I understand you are saying is: current scope of archetypes and templates are not enough to represent content semantics.

So the questions for the SEC would be:

  1. is conditional us of RM attributes is part of content semantics? or is in another layer?
  2. is local aliases for term lists part of content semantics? or is in another layer?
  3. and so on…

If we can classify those requirements considering current scope of archetypes and templates, we can find if we need or not to represent those extra elements in the same or a different layer.

I’m not sure if we have concrete examples for those requirements we can use to analyze. For instance the conditional use of attributes, I think is liked to GUI. because if you don’t have a GUI, how is that conditional metadata used?

For the aliases thing, I would need to see an example to have an opinion, but if that is also something that will be used by GUI, then even if it’s on top of model semantics, usage might indicate another semantic layer.

Also would be good to summarize all requirements related to this topic so we can discuss further, maybe in a SEC meeting? Then we might get to some conclusion and close the topic.

1 Like

Having thought about this for 15 years now (ha), I’d say mostly ‘another layer’. The raison d’être of archetypes is to say how to record X if it is needed. But the logic of when X is needed is highly use-case dependent. So I’d say it is mainly the business of ‘form workflows’ to define it. This kind of artefact doesn’t yet exist in openEHR, but it’s the category of object that e.g. Better’s Form Designer would save: it references fields in templates, and adds all the logic of:

  • visual arrangement, including tabbing / sections etc
  • order of visiting / filling
  • conditionality of fields becoming visible, being ignored, being filled with defaults etc.

I used to think it might be reasonable to put all this into a template. However, I think we need to be able to create standard reusable templates (e.g. ‘Swedish discharge summary’ and the like) that also don’t try to lock down all the above form workflow. HOWEVER, they probably do want to be able to state some inter-field conditionality (e.g. the classic 'if /path/to/is_smoker = yes then Exists /path/to/tobacco_use_details). Archetype rules allow this, and that’s what they should be used for. Such conditions would be limited to those regarded as semantically part of the data set.

To achieve the rest of the items in the list above, I think they need to go in an ‘application workflow’ artefact that we don’t yet have.

What formalism would be needed for this? I do think we could use archetype formalism (remember, constraints on an information model) plus the (an) Expression Language. To achieve references to visual elements, there would have to be some kind of mapping between logical template fields and visual items, e.g. done like this:

PANE[main] matches {
    style matches {"3-col"}
    columns matches {
        PANE[left] matches {
            etc
        }
        PANE[centre] matches {
            rows matches {
                ROW[demographics] matches {
                    controls matches {
                            TEXT_DROPDOWN matches {
                                     data_ref matches {/path/to/pat_name/in/template}
                            }
                    }
            }
        }
        PANE[right] matches {
            etc
        }
    }
}

I’ve completely made up the visual meta-model (PANEs, columns, ROWs etc) so imagine those names are the common ones from modern frameworks. Now, the inter-field relationships could be stated as expressions, either throughout the ADL, or at the bottom.

Current ADL won’t manage the above, but it’s not far off, and what I am thinking of for ADL3 would allow things like PANE[left] to be used instead of requiring codes.

1 Like

This thread keeps getting pulled in all kinds of divergent (often interesting) directions. Below are some clarifications, regarding what we (at Karolinska and in some national Swedish projects) are (fairly urgently) looking for - and not looking for.

We want reduce duplication of work downstream after templete modeling and reduce “out of band” ad-hoc documentation of recurring needs when using the same template in several different vendor’s systems. All those systems already have their own native ways of expressing forms with display logic etc, but those systems have been enhanced with a way to base their forms on openEHR (web)templates instead of starting with a blank slate. WIthout agreening on some hints in templates e.g. via annotations they can only get the structure (and openEHR paths) from the template, but will get no information about the intention to link display logic between fields (becaiuse major template tools don’t support ADL rules yet) and no information about fields that should be sent to the CDR but not shown to the end user (e.g. a patient). That is why there are some suggestions in this thread about how to add ADL rule information via annotations and something like hide_on_form. Could we descuss those before exploring too many other directions?

The thread was originally about informally but in collaboration agree on some semantically important hints/directives in templates (as a technical format) WITHOUT right now inventing new formalisms/formats or changing any openEHR specifications. (But by experimenting with this together we may of course find patterns that could inspire some specification additions later). So could we take the “what new specs do we need”-discussion later or move that to another thread?

Please don’t confuse the described template needs with very generally reusable archetypes - the need described is for USE CASE SPECIFIC TEMPLATES.

In the cases where there is a need for…

…then let’s make that general template without these extra annotations and then in another layer/step specialize the general template into more specific ones where we add the annotations to use case specific specialized tempates (e.g. with hints for end user forms). I have tried to highlight this posibility of layering BY USING (several) LAYERS OF TEMPLATES (for separate purposes if you don’t want to mix purposes) but there still is repeated talk about the need for “another layer” that is not template based. For all the nittty gritty display things much further down the line I agree other existing formalisms like CSS and layout frameworks for differnt platforms are better to use than stuffing all that into templates, but those formalisms have already been invented by others for different targets platforms like HTML+CSS or Flutter layout systems or Better’s form renderer or Cambios’s form runtime or the form support in Sectra’s IDS7 or whatever. Those that really want to put parts of this into an openEHR-based formalism for specific use cases (or specific platforms) could possibly export something like css-classes etc to downstream toolchains from some template annotations if needed.

Actually we don’t at all need to decide now how many layers are recommended or needed for different purposes, a form renderer won’t know at what level of template specialisation layers a certain annotation was added, it just gets the sum of all layers’ annotations.

Discussing other things can be interesting too, but it would be nice to get some feedback on the actual suggestion of annotation use for:

  • Representing ADL rules (e.g. logic links between fields) via tempates (while waiting for better support of rules in template tools) - A script could convert these to actual ADL rules for platforms support those.
  • Some hide_on_form annotation key (Perhaps with optional use-case specific variations by adding values under that key like: always | patient-view | clinician-view | presentation_view | …or whatever)
  • Some way of giving a node a progamming-friendly short meaningful ID/alias so that you don’t need to refere to the entire path in rules etc.

P.S. regarding @pablo’s question

If you have a template about smoking habits used for data import in a national registry (with data coming from several differnt systems) you may want to use such rules to refuse submissions that have status “never smoked” combined with consumplion “2 packs per day”. So they conditionals are not only for GUI, I believe that’s why they are already part of ADL rule possibilities.

1 Like

Indeed. People should keep in mind the fact that adding various kinds of power to a formalism (even if just saying how to use the annotations section) doesn’t mean that all those capabilities have to be used in one layer of templates - you want to do what Erik is saying here, and separate the use of those capabilities into layers of artefacts.

See discussion here. Example of doing this:

    symbol_bindings = <
      ["apgar_events"] =   <
          root = <"/data[id3]/events">
          children = <
              ["apgar_respiratory_value"] =   <"data[id2]/items[id10]/value[id43]/value">
              ["apgar_heartrate_value"] =     <"data[id2]/items[id6]/value[id44]/value">
              ["apgar_muscle_tone_value"] =   <"data[id2]/items[id14]/value[id45]/value">
              ["apgar_reflex_value"] =        <"data[id2]/items[id18]/value[id46]/value">
              ["apgar_skin_colour_value"] =   <"data[id2]/items[id22]/value[id47]/value">
              ["apgar_total_value"] =         <"data[id2]/items[id26]/value[id48]/magnitude">
          >
       >
    >

ADL2.3 doesn’t do this but I would propose that ADL2.5 implements it. Could be short-term faked in annotations.

That was our thinking on that.

I might misinterpret this but here I go…

I think there are different ways for doing something like that, mainly:

  1. define a capability in layer X that is very generic can could be used in many ways maybe by layer X, but maybe not, and is left there for other layers to use or extend

  2. define a capability in layer X for a known requirement of layer X, then realizing on layer X+1 that capability could be reused or used in a different way

Both make sense to me, what doesn’t make sense is defining a capability in layer X without any use for that in layer X and hoping that layer X+Y uses or defines how to use that capability.

Think of network protocol packet definitions, we have layers: app (HTTP), transport (TCP), network (IP), link (Ethernet) and physical (bytes in the wire), each layer defines it’s own capabilities and a payload part for the layer on top to put it’s data, so HTTP data goes inside a TCP datagram, the HTTP+TCP goes inside the IP packet, etc. Though there are exceptions of cross-layer capabilities, like one layer reading the data from another layer to implement something, like security or statistics, but in general each layer defines it’s own capabilities and uses them, independently from the other layers (or as much as possible). I think this approach is good architecture and Internet is the proof, so we need to be careful if we want things that mix up semantic layers. My personal preference would be to define the semantics of the annotations (scope) in one layer and use the annotations ONLY for that. If we need something else, another capability, design something specific for that, including extending something from another layer, like annotations, but we know that extension is actually in another layer.

@thomas.beale since rules are already in adl/aom and symbol bindings are planned, perhaps we (in tools that don’t yet support them natively) should prefix such annotation keys with am (or aom or adl) to separate from things that are not (planned to be) part of the archetype model spec, so for example am.symbol_binding instead of previous a.id suggestion

Annotation position Annotation Key Annotation value
A am.symbol_binding tobacco_user
B am.symbol_binding tobacco_details
position at root of template (if using only defined symbols in rule) or position on a specific node if using the THIS keyword for self reference am.rule check tobacco_user = ‘Y’ implies defined (tobacco_details)

…in order to make it clear that these could be represented natively in ADL as opposed to things like a.hide_on_form that are meant to be passed on to, and possibly modeled in, other layers of the modeling stack.

P.s. instead of THIS as a keyword, SELF could of course be an alternative

Nice thinking. I like this.

@nedap we use ‘rules’ for that. At archetype or template level.

We use custom annotations for that with a similar syntax.

I agree with Thomas this should mostly not be in an archetype (unless it makes semantic sense e.g. “type of irregularity, in case of irregularity” that is good for an archetype”.

On the other hand it works fine without any issues. And potential issues (having to migrate annotation syntax, remove from Template and put in form) seem acceptabel.

Examples here: Sign In with Auth0

If you click “to basic editor”, and (from your own repository) create a new archetype there’s a ui for basic rules creation:

The semantics are subtly different at data vresus UI level as well.

Somewhat of a devil’s advocate argument:

AN archetype might quite resaonably have a rule of the form

if X = yyy then exists /tree/of/yyy/related/data

which is saying something about the conditional mandation of part of the data. Independently of that, a
form definition artefact might have a rule of a similar form, such as ‘if X.filled then show /sub-form/of/yyy/data’. Now, it’s pretty obvious that you don’t really need the latter if you have the former - the form
level tools / builders etc treat the data conditional rule as a proxy for some show-on-form logic.

So then the question is: could all such needs be solved just in the archetype? For Nedap, within their controlled universe, the answer is yes (perfectly reasonable). But generally? Well, it’s easy to imagine how an international archetype might not have a conditional mandation rule, but some local use in whatever jurisdiction does.

Example: the condition is about ‘active tobacco user?’ → ‘details of tobacco use’. It’s reasonable to allow the details part to be completely optional even if the answer to the question is ‘yes’ (just recording the fact of tobacco use without details is still useful). But let’s say some jurisdictions are trying to manage tobacco use in a precise way (e.g. offering relevant educational materials to heavy smokers, occasional cigar smokers, tobacco chewers and so on…), then they may want such a rule.

They could still put it in a localised specialisation of the original archetype, which gets them out of having to have any special form logic representation.

So we might then ask ourselves, well why would anyone want conditional mandation rules solely at the form level, with nothing in the archetype level? Either the semantics of the data in your product / deployment situation are that there is a rule for conditional mandation, or else you are putting semantics in the UI not tied to any data specification level artefact. Why do that? Well, it might be convenience, e.g. a vendor might do that because they don’t want to have to create a localised archetype for each of 50% of clients who want that rule and not for the other 50% that don’t - so they just make it a form builder thing. The problem with that, I would argue is that this is hidden semantics - like all semantics in forms that is not tied to underlying models.

A better solution to the above situation (the devil would argue) is indeed to create specialised archetypes containing the rules (for those clients that want them), and not to put any rules in forms that are not purely visual.

I note that both @joostholslag and @thomas.beale sometimes refer to archetypes rather than the main theme of this thread: templates. Of course in ADL2 the technical difference is not big, but there is a very reasonable recurring demand from people to keep the international archetypes “pure” (without any UI-related stuff) so that they are really globally reusable.

So, could we assume that we talk about use case specific templates when we discuss anything UI-related? Otherwise I fear that this thread will once again get misunderstood and distracted away. Of course some data conditional rules may really need to be at arcetype level to prevent nonsense data, but let’s treat that as an already allowed thing in ADL rules and focus on the use at template level instead.

Yes, exactly, the ADL-rules (and/or corresponding "am.*"annotations) plus UI hints (like a.hide_on_form) could, as an option when when initially loading the template file at least serve an initial input to a form tool’s (often more powerful/detailed) UI behaviour modeling capabilities. Those initial hints/rules can then be refined with the UI tool’s native mechanisms.

This way we would not have to rebuild all of the logic in (what Karolinska’s case can be up to three) different vendor’s UI tools. Even if the vendors would not pick up the rules/annotations we could create some open source scripts that read the rules+hints and then automatically enrich the vendors’ proprietary (but often openly readable) form formats with basic if-then presentation rules that are already present in their different form-definition file formats.

So perhaps we could get back to discussing the actual syntax and sematics of:

  • UI-hints and
  • the “am.rule” annotations/shortcuts to representing ADL rules meant as an interm solution for those template tools that do not yet support ADL rules and
  • the additional “am.symbol_binding” meant for experimenting with a potential upcoming clever ADL extension to make rules more readable and maintainable by allowing the use of symbols to substitute (parts of) paths.

When it e.g. comes to am.symbol_binding do we believe that the previously mentioned syntax i a good one or could it be improved? Or is a shorter am.symbol better?

What about self-references like “THIS” or “SELF” (in the annotation value of am.rule) what kind syntax (wording capitalisation etc) would fit with ADL2 style of syntax?

Any thoughts about prefix (a.* or something else) and other syntax for UI-hints like hide_on_form? Better’s tools e.g. used to have ways both to define something as hidden in a UI-input form and another way to hide things in special read-only “display” views. So instead of just having the syntax/semantics a.hide_on_form=true we could do:

  • if the annotation with key a.hide_on_form is present without any value, then UI tools should set the field to initialy hidden (both in input and presentation mode and any other posible ‘modes’)
  • if the annotation with key a.hide_on_form is present with an oprional value then UI tools can use that value to determine what particular view(s) the field should be hidden in. Two predefined possible view values could be input and presentation
  • the default is of course that there is no annotation with key a.hide_on_form ant the field is then shown as default in all views

Regarding the input and presentation values above: we have use cases like these where a patient should see a long question (The text that in the template has replaces the “Presence?” in the Symptom/sign screening questionnaire archetype in the input view of an entry form but the patient should not see the short “Symptom/sign name” field. When presenting this to a clinician (very used to reading form) the visibility should sometimes be the opposite.

image

Note to self + @thomas.beale and others to remember before settling on syntax discussed above: In SEC internal disucssions and in public wiki page https://openehr.atlassian.net/wiki/spaces/ADL/pages/2135457828/ADL2+Evolution about posible future readable identifiers in ADL, the term “key” has also been used rather than “symbol (binding)”