# Agreeing on optional user interface hints in templates **Category:** [Specifications](https://discourse.openehr.org/c/specifications/6) **Created:** 2022-03-03 08:03 UTC **Views:** 2622 **Replies:** 52 **URL:** https://discourse.openehr.org/t/agreeing-on-optional-user-interface-hints-in-templates/2406 --- ## Post #1 by @erik.sundvall **In short:** Let's start experimenting with adding vendor neutral hints (e.g. in templates) that can help both automated user interface generators and "manual" form editors create forms with more logic. Details follow. **Current use-case background** There is a current need in multi-vendor projects (at least in Sweden) where we would like at least some GUI/form logic to be possible to author once nationally and then be reused in several different vendor solutions (Cambio, TietoEVRY/Better, SECTRA structured reporting forms. And perhaps e.g. Medblocks & NeoEHR later?) **openEHR historical discussion background** Previous mail list discussions (from 2008) regarding GUI-hints in openEHR templates. Some highlights: * Start: https://www.mail-archive.com/openehr-technical@lists.openehr.org/msg03855.html * Discussion examples: * https://www.mail-archive.com/openehr-technical@lists.openehr.org/msg03871.html * https://www.mail-archive.com/openehr-technical@lists.openehr.org/msg03880.html * https://www.mail-archive.com/openehr-technical@lists.openehr.org/msg03881.html * Summary: https://www.mail-archive.com/openehr-technical@lists.openehr.org/msg03882.html **Initial suggestion** * Let's start some experiments with (shared vendor neutral) template annotations and/or "ADL(2?) rules" reusing part of the design patterns of [“EnableWhen” in FHIR Questionnaires](http://www.hl7.org/fhir/questionnaire-definitions.html#Questionnaire.item.enableWhen) that could (optionally) be used by form building tools as input for creating (possibly vendor specific) conditional logic in forms (like what is now available in e.g. Better’s, DIPS's and Cambio’s tools) * Maybe later look at * “Presentation mode visibility” hints - see option in Better’s EHR studio * “Hide on form” hints - e.g. useful for marking intermediate level branch levels that are mostly needed for logic storage structure but not contributing to end-users' understanding at a GUI-level in the template-specific use case. * "LOD" - level of detail hints - for subtrees/parts that can be initially collapsed/hidden when screen space (or attention span) is limited. (Like the [“More…”-buttons in Clinergy/PEN&PAD](https://pen-pad-revival.github.io/)) * SelectWhen hints - Select an item in a multiple choice list when a condition based on data in other parts of the form is met. * Copy data between fields (and possibly discuss the Pandora’s box of “simple” calculations & aggregations based on data from multiple source fields) When this was discussed in [a SEC meeting](https://openehr.atlassian.net/wiki/spaces/spec/pages/1958019125/2022-01-10+SEC+Call+notes) and following discussioins after the meeting @pieterbos and others suggested looking at the "rules"-mechanism in ADL (Rules are definitely useful within an archetype - with ADL2 possibly also in templates across data from different archetypes). Nedap are using such rules and the implementation is open source in Archie. It outputs things such as 'set the value at this path to this', and 'this part of the data must exist (is mandatory)'. @pieterbos also said that Nedap has an implementation running at [archetype-editor.nedap.healthcare](http://archetype-editor.nedap.healthcare/). (where you can sign up and login, create a repository). Using the basic editor you can only define sums and averages. If you click 'advanced editor' at the bottom, you can see and edit the rules to achieve quite a lot more, and there's a form implementation that executes them as well. Note that this form only does compositions, observations and evaluations. It also outputs a copy of the object provided as input, modified by the rule evaluation, plus whatever assertions failed and succeeded, of course. For editing the rules by hand, he recommended the visual studio code extension, but it cannot execute them on data **Note:** User interface hints may not be of interest to all (and thus not expected to be supported by all) but very useful for some, please consider that when responding and let's explore options. Also note that we are talking of use case specific templates not more general archetypes. --- ## Post #2 by @thomas.beale [quote="erik.sundvall, post:1, topic:2406"] design patterns of [“EnableWhen” in FHIR Questionnaires](http://www.hl7.org/fhir/questionnaire-definitions.html#Questionnaire.item.enableWhen) [/quote] We do [have this in ADL2](https://specifications.openehr.org/releases/AM/Release-2.2.0/ADL2.html#_value_dependent_existence) (also in ADL1.4) - it doesn't seem to be used much. See here (ADL2.2). [quote="erik.sundvall, post:1, topic:2406"] “LOD” - level of detail hints [/quote] If level of detail were not simply computable from depth, it would probably require a number on all / some nodes that would be compared to a threshold value to unfold or not. [quote="erik.sundvall, post:1, topic:2406"] SelectWhen hints [/quote] This is certainly a GUI thing. [quote="erik.sundvall, post:1, topic:2406"] Copy data between fields [/quote] We will support computed fields in latest ADL2 - by distinguishing between assertions (if /x/y/z = a then something) and expressions (/x/y/z := a + b * c). Mainly I think we should clarify the distinction between UI level hints and model-level (archetype / template) rules. --- ## Post #3 by @pablo Hi @erik.sundvall we have discussed this in many occasions, here and in Slack. Because of the many disadvantages of mixing GUI stuff into a template, my opinion was always to avoid this at all costs. 1. Separation of concerns: visual hints, GUI commands / operators / definitions, etc. are not in the scope of the template, it's purpose is to specify a data set by constraints, not to define how form fields or data in a screen should be displayed. There is no concept of form, field or data visualization in the template model / AOM, and shouldn't be added. 2. Adding those GUI elements to the template are conceptually patches to comply with certain system requirements, that should be satisfied by other metadata constructs, not by templates. 3. Opening the door for some GUI hints allows to open the door for many other hints and extra requirements that are not in the current scope/purpose of a template. 4. Limiting the scope of templates just for "defining data sets by constraints" from the start allows these extra GUI requirements to be satisfied elsewhere. For instance, it enables the construction of another model, specific for GUI stuff. I worked on this area before and shared the initial model we reached with the SEC some time ago. 5. Having another model just for GUI stuff, allows to follow the inherent layered architecture openEHR currently has: RM < AOM < TOM < GUI Templates. I have also proposed other layers for that semantic "sandwich", for instance the CDS rules is another layer, the "data mappings" (to map openEHR data from/to other standards/models/messages) could also be another layer, a "process spec" could be another layer, etc. etc. So instead of adding elements that belong to a different semantic level to the templates, we create a new semantic layer for those, including: expression language, model, tools. This is just the openEHR approach for everything. This is the spec I was writing some time ago: [User Interface Templates for the openEHR specifications stack - 20200922.pdf|attachment](upload://5635h3NBrDHbY830w93jctgPsBM.pdf) (471.5 KB) That is basically a model that maps items from the template into GUI elements/controls/widgets, and allows to bind data back to the openEHR template for data validation and storage. So IMHO it is better to the whole architecture to extract those hints into a different layer than actually standardizing those to be part of the AOM. --- ## Post #4 by @erik.sundvall @pablo I'd say what is "GUI-stuff" and what is more of just template/use-case-specific logic and validation/selection-semantics is a greyzone/continuum. Thanks for linking to your UI-templates document suggestion @pablo. The (green) layout/zone-classes in that document I'd definately think is "GUI stuff" and likely more UI-product/technology/screensize-dependent. On the other hand, the "EnableWhen" example above, inspired by FHIR, would be towards logic end of the grayzone, and could as @thomas.beale hints, probably be solved using ADL rules. In the mentioned projects we are interested in having a convenient way for informaticians+clinicians to specify some of the logic _at the same time as they build the shared template_, preferrably using integrated tooling, saving files in a vendor neutral format. If it ends up in separate files or as annotations+rules inside a use-case-specific template file, or a mix thereof, would matter less for these users. Tooling support does matter though. Most current template tools do support annotations., what tools do support rules in **templates** (not only archetypes) in addition to the one I quoted @pieterbos mentioning? --- ## Post #5 by @pablo [quote="erik.sundvall, post:4, topic:2406"] I’d say what is “GUI-stuff” and what is more of just template/use-case-specific logic and validation/selection-semantics is a greyzone/continuum. [/quote] In understand your thinking, if we analyze those cases (GUI stuff and template use cases and validation/selection), IMO all is out of the scope of the template. In one way or the other those elements/artifacts/constructs end up in areas like: user interface, user experience, user interaction or just workflow definition. None of those cases are specific for "data set definition by constraints", as I define the current scope of the openEHR templates, which is informal but accurate. I think further analysis of those cases you mentioned is needed, so we can classify them in the categories mentioned above (GUI, workflow, etc) or create new categories. Then when we formalize that, we can check if there is any overlap with the scope of the templates, and if there is, then we can opt to add support for those requirements in the AOM, if there isn't, I would prefer not to touch the AOM but formalize those requirements on top of it as another semantic layer as described on the previous message. [quote="erik.sundvall, post:4, topic:2406"] On the other hand, the “EnableWhen” example above, inspired by FHIR, would be towards logic end of the grayzone, and could as @thomas.beale hints, probably be solved using ADL rules. [/quote] That seems exactly as a workflow construct, a definition/rule/constraint on top of the template, so I would argue the advantage of including such construct in the AOM for templates. Though my model didn't include workflow definitions, it is a better place to include them, and map back to the template fields involved in that rule (using paths or node ids). In fact that something is "enabled" or "disabled" is indeed GUI stuff, then the "when" part is a rule on top of that "enable/disable" directive., which could be formalize as: IF bool_expr THEN enable(path) ELSE disable(path). Though I think enable/disable applies to widgets (sets of fields) or individual fields, so it could be similar but instead of using paths, using the field id or widget id: IF bool_expr THEN enable(field_id) ELSE disable(field_id). or even lists of fields: IF bool_expr THEN enable(f1, f2, f3) ELSE disable(f1, f2, f3). That is why I don't think it is a grey zone, IMHO more analysis is required to conceptualize each requirement correctly at the finest grain possible, current requirements seem big items looking for fast solutions and we need to be careful, because this design will mark implementations for years to come. Tough this is not a perfect vs. good enough discussion, I think it's wrong to add solutions in the a place that is not for that. [quote="erik.sundvall, post:4, topic:2406"] In the mentioned projects we are interested in having a convenient way for informaticians+clinicians to specify some of the logic *at the same time as they build the shared template*, preferrably using integrated tooling, saving files in a vendor neutral format. [/quote] That is the issue, the "convenient" path is not the conceptually correct path for an international spec, that is my personal opinion based on my own experience, not saying I'm right or anything, just trying to open the discussion. --- ## Post #6 by @thomas.beale [quote="pablo, post:5, topic:2406"] That is why I don’t think it is a grey zone, IMHO more analysis is required to conceptualize each requirement correctly at the finest grain possible, current requirements seem big items looking for fast solutions and we need to be careful, because this design will mark implementations for years to come. Tough this is not a perfect vs. good enough discussion, I think it’s wrong to add solutions in the a place that is not for that. [/quote] We can certainly find some examples where the logic of whether a data hierarchy should only be present based on the value of another element. Classic example: ``` items +--- tobacco user: Y/N +--- tobacco use details +--- amount per week +--- cessation attempts | +--- xxxx +--- yyy rules /items[tobacco user] = 'Y' implies exists /items[tobacco use details] ``` If we consider the above rule a semantic property of the data independent of whether it is on the screen, in a message, document, survey or whatever other form, agreed on by the archetype experts, then it belongs within models - either the archetype or somewhere similar. (@erik.sundvall 's case) However we can undoubtedly find examples where the same structural conditionality is use / context specific, and not applicable to all instantiations of the template as data. We may well need a UI level of mechanism to accommodate this. (@pablo 's case) So it just means that not everything that looks like a certain kind of business rule for data or UI is necessarily one or the other. --- ## Post #7 by @pablo Hi @thomas.beale I agree if there is any data set related rule, it should be in the template itself, or in AOM in general, though each requirement need thorough analysis to know what mechanism should be used to satisfy them, if it's a data cross-node constraint, or if it's something that will affect the user workflow or the GUI. A separate but related topic is how to define and name those IF-THEN-ELSE rules for the data sets. I know we have the assertion language plus other new constructs. Let's say certain part of the structure defined by a template, which is optional, should be prohibited depending on a value in another part of the same template. I think we can use the AOM itself to be dynamically changed when these conditions are true, for instance: IF value_at(path) IN [a,b,c] THEN node_at(path).occurrences = [0..0] So instead of defining something new, we use the current RM functions and attributes to change their values at runtime. It's like a RM compatible scripting language. Same could be done if the optional node should be mandatory depending on the value(s) of another node in the template. Of course all values should come from COMPOSITION instances, so the "script" can only be evaluated using a given COMPOSITION + TEMPLATE. The language you described above doesn't seem to use the RM and seems like OCL (which we use to represent RM invariants in the specs). About naming, what I don't like is something like the mentioned "enableWhen", which kind of implies something related with GUI because of the "enable" part. In a data structure the nodes are not enabled or disabled, but are required, optional or prohibited. So naming is important to avoid misunderstandings with the scope of these rules: someone might want to use this mechanism to represent workflow or GUI rules when that is not the purpose of the rules. Of course, it is also difficult to discourage this usage when people have tools that allow them to do that and use template how they want instead of how they are designed to be used for. --- ## Post #8 by @thomas.beale [quote="pablo, post:7, topic:2406"] IF value_at(path) IN [a,b,c] THEN node_at(path).occurrences = [0…0] [/quote] we already have this - we just don't use exactly that syntax. In the syntax of today, it is : ``` /path/to/value matches {constraint} implies exists /path/to/other/node ``` In the newer syntax (future), it would be: ``` assert name_1 matches {constraint} implies defined(name_2) ``` or: ``` assert name_1 matches {constraint} implies name_2 matches {constraint} ``` where `name matches {constraint}` will often be `name = value` for the common simple cases. In the above, `name_1` and `name_2` have bindings to paths in a separate place. We also don't need special functions like `value_at()` or `node_at()` because predicates like `events[any_event].items[systolic_bp]` can be used, where `[any_event]`is shorthand for `[@archetype_node_id = '#systolic_bp']` and `#systolic_bp` is a future form of `[id23]` in ADL2. This is really just dot-syntax mixed with Xpath-style predicates. Some other more advanced things will be possible using lambdas, [as described here](https://specifications.openehr.org/releases/LANG/latest/expression_language.html#_container_item_selection_and_matching). NB: this new syntax is still being refined; I'm mentioning it here to show a proposed direction, not to say it will be in the next version of ADL. Next versions would potentially support path bindings ([see here](https://specifications.openehr.org/releases/AM/latest/ADL2.html#_rules_section) - look for 'symbol_bindings'), but we are working with @pieterbos and others to agree on how far to go at each ADL release. [quote="pablo, post:7, topic:2406"] The language you described above doesn’t seem to use the RM and seems like OCL (which we use to represent RM invariants in the specs). [/quote] It's not RM-specific, if that's what you mean - it's makes no assumptions about functions that might be available on specific classes in specific models - the way of finding items in a sub-tree or testing existence etc is completely generic, and doesn't change when you use it with another RM. So it's more like OCL in that way, true. [quote="pablo, post:7, topic:2406"] About naming, what I don’t like is something like the mentioned “enableWhen”, which kind of implies something related with GUI because of the “enable” part. In a data structure the nodes are not enabled or disabled, but are required, optional or prohibited [/quote] I agree with this. --- ## Post #9 by @pablo [quote="thomas.beale, post:8, topic:2406"] It’s not RM-specific, if that’s what you mean [/quote] I mean that the expression language could use the RM API (functions from the RM classes) instead of defining a whole new language without reusing the infrastructure we already have, which at implementation time could accelerate things. --- ## Post #10 by @thomas.beale [quote="pablo, post:9, topic:2406"] the expression language could use the RM API (functions from the RM classes) [/quote] Well it could, but then you are relying on functions from each RM to provide general semantics, e.g. finding nodes at paths. Each RM could easily have different functions for doing that. Worse, most RMs are not likely to have the complete set of functions defined that would be needed. We do however rely on the openEHR Base and Foundation types, which are not openEHR-specific. For example use of lambdas to find matching sub-parts: ``` class Book { title: String pub_date: Date } book_list: List book_list [(b:Book) {b.title.contains("Quixote")}] ``` [quote="pablo, post:9, topic:2406"] defining a whole new language without reusing the infrastructure we already have [/quote] Well, the Expression Language is based on very common / standard concepts, grammar etc, and the various parts are mostly cherry-picked from existing languages, e.g. Xpath, for path-related predicates. We do have some of the infrastructure needed for an Expression Language, in: * the simple and incomplete one in ADL2 * the very simple expression part of AQL * the expression meta-model in GDL * the small expression language in Task Planning. The main aim of a revised EL is to bring the semantics of all these together, or as close as possible, even if surface syntaxes might differ (as appears inevitable in AQL). This will support: * upgraded BMM so that all invariants and functional parts can be represented; * smart decision logic [like you see here](https://specifications.openehr.org/releases/PROC/latest/process_examples.html#_rchops21_decision_logic_module); * more interesting possibilities in AQL. The intermediate form we are currently working on for ADL 2.3 will do a fair bit. --- ## Post #11 by @erik.sundvall Hi! [quote="thomas.beale, post:8, topic:2406"] [quote="pablo, post:7, topic:2406"] About naming, what I don’t like is something like the mentioned “enableWhen”, which kind of implies something related with GUI because of the “enable” part. In a data structure the nodes are not enabled or disabled, but are required, optional or prohibited [/quote] I agree with this. [/quote] I have no strong opinions regarding the naming, I just used FHIR's name to point to the use-cases and design pattern. What we have an immediate need for in the multi-vendor project is a vendor netrual possibility to express if/then conditionals like the ones you both have discussed above (e.g like Thomas' "tobacco user Y/N"). It looks like the ADL _implies+exist_ rules or future expression language with _assert+implies_ might do the job if I understand you correctly above. One of the remaining questions: [quote="erik.sundvall, post:4, topic:2406"] Tooling support does matter though. Most current template tools do support annotations., what tools do support rules in **templates** (not only archetypes) in addition to the one I quoted @pieterbos mentioning? [/quote] Are there suitable (template?) authoring tools that can be used to explore the ADL rules approach? If not, could we (for practical test purposes) make some annotations using present tools with the rule syntax in the annotation data somehow? The template(s) with annotations could then easily be automatically post-processed and convert the annotations into for example either: * "proper" ADL rules and insert into the template or * current vendor specific if/then rules in openEHR-based form engines (like Betters's and Cambio's) Currently the national project is a "proof of concept", so it can be used to test the general mechanisms and no essential harm is done if a future official openEHR syntax would change later. --- ## Post #12 by @pablo [quote="thomas.beale, post:10, topic:2406"] Well it could, but then you are relying on functions from each RM to provide general semantics, e.g. finding nodes at paths. Each RM could easily have different functions for doing that. Worse, most RMs are not likely to have the complete set of functions defined that would be needed. [/quote] I understand your point, but I think any implementation, for any RM will need to have some node location by path function, isn't it? In other words, any reference to a node in a RM instance, openEHR or any other RM, in a expression language, needs to have an underlying API that will resolve the reference (path or another locator) to the right node from the instance, so I'm wondering if we still need to write that API for ANY RM so the expression language can be evaluated, why not making the expression language more openEHR friendly to reduce the burden for openEHR implementers if it will be the same work for other RM implementers? Note the language is only the syntax part, the complex part is the API that implements the language and executes/checks things then an expression is evaluated against an RM instance, and the syntax will indicate which operations are needed in the API, so we are still imposing the semantics of those operations for any RM, with an unavoidable node_at(path or locator) operation needed at the API. It just feels we are introducing a new language for every new requirement... --- ## Post #13 by @erik.sundvall [quote="pablo, post:12, topic:2406"] It just feels we are introducing a new language for every new requirement… [/quote] :slight_smile: Tom loves DSLs (and parsers?). But seriously isn't the ADL rule language ("matches" + "implies exists" above) already defined in spec and also implemented in some solutions. Does anybody have opinions on using helper annotations in templates for this functinality in tools that do not yet support rules? (that can then be post processed as described in [post #10 above](https://discourse.openehr.org/t/agreeing-on-optional-user-interface-hints-in-templates/2406/11?u=erik.sundvall)) ``` items +--- tobacco user: Y/N <-- ANNOTATION POSITION A +--- tobacco use details <-- ANNOTATION POSITION B +--- amount per week +--- cessation attempts | +--- xxxx +--- yyy ``` ### FOR RULE CAPABLE TOOLS: ``` rules /items[tobacco user] = 'Y' implies exists /items[tobacco use details] ``` ### ANNOTAIONS on one of the above marked nodes FOR RULE INCAPABLE TOOLS Perhaps using a "THIS" macro for current node so that a rule annotation on the marked nodes can be written as _either of_ the following table rows | Annotation position | Annotation Key | Annotation value | |---|---|---| | A | rule | THIS = 'Y' implies exists /items[tobacco use details]| | B | rule | /items[tobacco user] = 'Y' implies exists THIS | Alternative solutions are welcome. --- ## Post #14 by @thomas.beale [quote="pablo, post:12, topic:2406"] In other words, any reference to a node in a RM instance, openEHR or any other RM, in a expression language, needs to have an underlying API [/quote] There's not usually an API - the statements are normally parsed to an augmented AST (abstract syntax tree). That's what the AOM, BMM and similar models are in fact - special ASTs. Once you have the AST you validate anything that couldn't be validated at a syntax level, which is usually typing, semantic coherence etc. Then you can execute validated statements / expressions by traversing the AST and performing the computation. You can certainly build that as a class-level API, but it's not the kind of service API you'd expose through something like REST. In fact, the operation to get the value at a path within the wouldn't be handled by any of this, because archetype paths will be mapped to symbolic variables. The runtime system has to work out what data paths an archetype path mentioned in a binding possibly refers to (e.g. it might be 50 systolic BP values, or just one). To resolve an archetype path against data you could potentially rely on some API that talks to data, and contains path-resolving functions. But apart from resolving bindings, the language doesn't rely on an API as such to be executable at run time. [quote="pablo, post:12, topic:2406"] It just feels we are introducing a new language for every new requirement [/quote] I hope not - we are just trying to upgrade and consolidate a single expression language with a fairly standard syntax and semantics, as per [the draft spec](https://specifications.openehr.org/releases/LANG/latest/expression_language.html). --- ## Post #15 by @pablo [quote="erik.sundvall, post:13, topic:2406"] But seriously isn’t the ADL rule language (“matches” + “implies exists” above) already defined in spec and also implemented in some solutions. [/quote] I don't know about ADL2. `matches` is for sure there, then in AOM we have `existence` in the constraint model, but not sure if `implies exists` is something already defined. A related question would be if this is the only rule form we will have or if there are going to be more complex rules, just to check how syntax and underlying API would look like. --- ## Post #16 by @pablo [quote="thomas.beale, post:14, topic:2406"] There’s not usually an API - the statements are normally parsed to an augmented AST (abstract syntax tree). [/quote] With API I'm referring to the classes and functions that implement the logic, once parsed from the syntax in the AST. The ASW is acutally mapped to something that can be instantiated, invoked, and that `client` code can use the results for such invoked methods/functions. So I guess it is what is binded by the lexer from the parsed DSL if I didn't mess the terms :) --- ## Post #17 by @thomas.beale [quote="erik.sundvall, post:13, topic:2406"] Does anybody have opinions on using helper annotations in templates for this functinality in tools that do not yet support rules? [/quote] I think this is a reasonable short-term solution for non-rule-supporting systems. I need to think a bit on the details. It would still be better to get to a syntax that didn't have archetype paths inline (these greatly complicate the semantics) and used bindings for them instead, as per [this version of the older Expression Language](https://specifications.openehr.org/releases/AM/latest/ADL2.html#_rules_section). --- ## Post #18 by @thomas.beale [quote="pablo, post:16, topic:2406"] With API I’m referring to the classes and functions that implement the logic, once parsed from the syntax in the AST [/quote] Pretty much everything turns into calls to functions that are either defined on objects of the RM in question, or underlying primitive types available in the language of the execution engine implementation. For example, traversing a piece of AST representing the expression `systolic + 0.33 * (systolic - diastolic)` will resolve to calls to `Real.add()` etc. Normally you will replace that with calls to the built-in types. You can guess how it could be executed from the default generate AST: ![MAP-AST|654x500](upload://6CWpQrlakbT1vEMM5NPwgBsG6xC.png) The BMM AST is a bit smarter and allows more interesting things to be achieved, mainly to do with validation. Calls to external functions should also be supported, e.g. to enable function that computes e.g. BMI or pregnancy risk based on certain variables. In my proposed future EL, decision tables (aka if/then chains and case statements) will also be supported e.g.@ ``` Result := case ipi_raw_score in ======================================= |0..1| : #ipi_low_risk, |2| : #ipi_intermediate_low_risk, |3| : #ipi_intermediate_high_risk, |4..5| : #ipi_high_risk ======================================= ; ``` and its default AST: ![case_table-AST|463x500](upload://3c8PGj6fr52nQh3FVGWwBlECe8J.png) Also other nice structures: ``` score := Result.add ( --------------------------------------------- basic.gender = #male ? 1 : 0, age_score , has_congestive_heart_failure ? 1 : 0, has_hypertension ? 1 : 0, has_stroke_TIA_thromboembolism ? 2 : 0, has_vascular_disease ? 1 : 0, has_diabetes ? 1 : 0 --------------------------------------------- ) ; ``` I'm getting ahead of the original question here of course ;) --- ## Post #19 by @erik.sundvall [quote="thomas.beale, post:17, topic:2406"] It would still be better to get to a syntax that didn’t have archetype paths inline (these greatly complicate the semantics) and used bindings for them instead, as per [this version of the older Expression Language](https://specifications.openehr.org/releases/AM/latest/ADL2.html#_rules_section). [/quote] Good suggestion, it also matches the approach in Cambio's form editor (see screenshot below) where each node used in a form is assigned a short default id (based on the template's node name) that can be changed manually. ![image|690x423](upload://6C7V3wH5YK9AyS7KJSbwQ1OYuG5.png) Just as in ADL Cambio's rules (called actions) are collected in a single place (not attached to each node). **Edited at 18:00, adding info aboout Better:** In Better's form editor the rules are anchored to a specific node but can read and modify any node (see "Method code equals Auscultation" in screenshot below), not just the node it is anchored to, so I guess ther rules are actually as free-standing as in Cambio's solution ![image|690x341](upload://zWF4xcA1qMVBiJXfDAwG2HSiuAN.png) For template tools that do not handle rules (yet) we could then perhaps add an "id" annotation that will through post-processing create a symbol binding based on the path of the annotated node. *Edited: added the (namespace)prefix 'a.' to the examples below to reduce risk of name clashes and to make it work better in Ocean's template designer tool. The letter 'a' being the first in the word 'automation'* Example based on the structrue from post 13: ``` items +--- tobacco user: Y/N <-- ANNOTATION POSITION A +--- tobacco use details <-- ANNOTATION POSITION B +--- amount per week +--- cessation attempts | +--- xxxx +--- yyy ``` |Annotation position|Annotation Key|Annotation value| | --- | --- | --- | |A| a.id | tobacco_user | |B| a.rule | tobacco_user = ‘Y’ implies exists THIS| Or if choosing to manually giving an ID to both nodes, more like below. Below an alternative rule version using the ADL2 syntax desctibed in [https://specifications.openehr.org/releases/AM/latest/ADL2.html#_value_dependent_existence](https://section 7.11.2.2. (Value-dependent Existence)) and a cambio inspired one is also provided |Annotation position|Annotation Key|Annotation value| | --- | --- | --- | |A| a.id | tobacco_user | |B| a.id | tobacco_details | |root of template?|a.rule.adl | tobacco_user = ‘Y’ implies exists tobacco_details| |root of template?|a.rule.adl2 | check tobacco_user = 'Y' implies defined (tobacco_details) | |root of template?|a.rule.cambio-style| tobacco_user == 'Y' ASSIGN tobacco_details.hidden = false OTHERWISE tobacco_details.hidden = true |root of template?|a.rule.better-style| tobacco_user = ‘Y’ THEN tobacco_details show OTHERWISE tobacco_details hide | In the Cambio/Better-style rows above, the CAPITALIZED words correspond to the rule section headers in the rule editors, see screenshots above. I skipped the first (constant) "WHEN" in order to sugest shorter syntax. --- ## Post #20 by @thomas.beale [quote="thomas.beale, post:17, topic:2406"] It would still be better to get to a syntax that didn’t have archetype paths inline (these greatly complicate the semantics) and used bindings for them instead [/quote] Just to go a bit further on this: the reason it complicates things is that the mapping between archetype paths and data paths is in general 1:N, due to multiplicities in runtime data. The other thing to remember is that expression languages (at least typical ones) work with data, i.e. real values, not 'models'. So a symbolic variable like `heart_rate` mentioned in an expression has to be populated with an actual heart rate value at runtime. What will this be? Well the binding shows at what archetype path it can be found in openEHR data (nice!) but we still have the problem of dealing with there being e.g. 50 heart rate values over time, all at that same archetype path. Which one(s) does the expression execution engine use? In some cases, there is an implied 'for all' operator (as @pieterbos pointed out a long time ago), but that is not universal. That means the EL engine potentially has to execute an expression 50 times or do something else that is not at all obvious from the expression itself. The expression itself is clear however; the challenge lies in how it will be applied to data. I believe we want to separate that complication from the syntax and semantics of expressions, so that expressions are just like they are in other languages. I won't bore everyone with further details, hopefully this gives a clue as to why bindings are important. For the masochistic, a [long discussion here](https://discourse.openehr.org/t/rules-in-archetypes-a-migration-path/1252). --- ## Post #21 by @thomas.beale [quote="erik.sundvall, post:19, topic:2406"] For template tools that do not handle rules (yet) we could then perhaps add an “id” annotation that will through post-processing create a symbol binding based on the path of the annotated node [/quote] Something like the second suggestion in that post pretty closely simulates the bindings + symbolic approach I have advocated. It means that the rules are readable, which I think helps a lot. --- ## Post #22 by @pieterbos [quote="thomas.beale, post:20, topic:2406"] n some cases, there is an implied ‘for all’ operator (as @pieterbos pointed out a long time ago), but that is not universal. [/quote] A for_all and perhaps an exists block, rather than a for_all just in a statement, in which one can define variables as pointing to a path, would result in a small modification to the current grammar resulting in much more easy to read rules. Then rules could be written so that paths appear only in binding to variables, and assertions can be written only with variables, and nearly all variables could point to single values instead of lists or other collections. Without any complex 'operators have to be defined on lists as well as single values' logic, as we currently have. However, if data binding is made separate from the language, and you cannot use a path anywhere else in the language, this will complicate these issues very much - then you cannot easily express 'I want these rules to apply to this event in this observation only, even if the event occurs multiple times, but I still want to reference other data in the observation outside of the single event'. if data binding is separate, but sub-paths are still possible, and a for_all block is added, then the problem is also easily solved. --- ## Post #23 by @thomas.beale [quote="pieterbos, post:22, topic:2406"] However, if data binding is made separate from the language, and you cannot use a path anywhere else in the language, this will complicate these issues very much - then you cannot easily express ‘I want these rules to apply to this event in this observation only, even if the event occurs multiple times, but I still want to reference other data in the observation outside of the single event’. [/quote] Wouldn't you just create a more specific binding for that particular event, to a more specific variable, e.g. 'Apgar_heartrate_5_mins' or similar, when you might already have 'Apgar_heartrate'? Or you are talking about apply these rules in the sub-tree at this path? For the latter I think you would define a binding to the container object (HISTORY or whatever) under which you want a `for_all` or `there_exists` to execute. It's an interesting question generally as to whether the binding needs to be separate from the language. I have made the assumption that it does because the bindings in GDL, Task Planning and Archetypes are all completely different. [quote="pieterbos, post:22, topic:2406"] if data binding is separate, but sub-paths are still possible, and a for_all block is added, then the problem is also easily solved. [/quote] I am more inclined to this approach - because with only symbolic vars in the EL, EL texts are least is readable and maintainable. This goes back to our [discussion last year](https://discourse.openehr.org/t/rules-in-archetypes-a-migration-path/1252). --- ## Post #24 by @thomas.beale [quote="pieterbos, post:22, topic:2406"] and you cannot use a path anywhere else in the language, this will complicate these issues very much [/quote] I had another thought on this - I just realised you probably thought that I propose no path access method at all within a revised EL. The approach I propose is more like Xpath. Firstly it is access to nodes below some root object within data, i.e. instance level paths. In Xpath, as we all know, this is done with predicates in []. And predicates can be (nearly) any expression to get to the intended sub-node, including path-patterns, but also other expressions, e.g. the simple ones like [1] (the first item). If we treat an inline archetype path as a path pattern predicate we then achieve what you want (which I agree with of course ;) - but the semantics are now clearer - they are as in Xpath - if the path pattern matches 10 real paths in the current data instance, then that's what you get. The new proposed EL has this kind of functionality, [see here](https://specifications.openehr.org/releases/LANG/latest/expression_language.html#_container_item_selection_and_matching) (but no path example there yet). The paths by the way would have '.' separators rather than '/', indicating formal RM structure access. --- ## Post #25 by @erik.sundvall A side note: In Ocean Template designer 3.1 (from 2015?) you can add configuration of annotation types (in subcatefories called sets), and say what elements they apply to, and optionally what the allowed values are. As default on installation the Categories "Notes" and "GUI directives" are included, see screenshot. Does anybody remember what the "Group" annotation was intended for? Also, when trying to load templates with "plain" annotation names (like "fhir_mapping") the tool gives an error. So the annotation names have to be changed to be in a prefix.suffix format. (I assume that is to cater for the annotation sets. Prefixing the experimental annotations discussed in this thread may be a good thing anyway. ![image|690x481](upload://6gql5ty38xKltIQ3bDs19umYRWe.png) ![image|520x350](upload://oRN2B86CWZ5x9ArUSnQuNsw8t0d.png) --- ## Post #26 by @sebastian.garde [quote="erik.sundvall, post:25, topic:2406"] Does anybody remember what the “Group” annotation was intended for? Also, when trying to load templates with “plain” annotation names (like “fhir_mapping”) the tool gives an error. So the annotation names have to be changed to be in a prefix.suffix format. (I assume that is to cater for the annotation sets. [/quote] I don't know, but assume that *Group* may be a hint that several elements belong together in some way. Not sure this part was ever used much though. There is also a newer more advanced Annotation Designer in Template Designer nowadays, but independent of that I believe that the annotations were extended so that simple keys like *fhir_mapping* can be used (or at least read) as well without a prefix in the latest version. --- ## Post #27 by @thomas.beale Maybe it is [the 'group' constraint described here](https://specifications.openehr.org/releases/AM/Release-2.2.0/ADL2.html#_group_constraints). --- ## Post #28 by @pieterbos [quote="erik.sundvall, post:25, topic:2406"] A side note: In Ocean Template designer 3.1 (from 2015?) you can add configuration of annotation types (in subcatefories called sets), and say what elements they apply to, and optionally what the allowed values are. As default on installation the Categories “Notes” and “GUI directives” are included, see screenshot. [/quote] ADL 2/OPT 2 annotations have the same concept, called groups, although in the specification currently only 'documentation' is defined. See https://specifications.openehr.org/releases/AM/Release-2.2.0/ADL2.html#_annotations_section . @thomas.beale the RESOURCE_ANNOTATIONS class in the resource specification seems to have disappeared in the latest specification. I think with the current ADL 2 rules, plus a well defined set of annotations, it is possible to create interactive templates with quite a lot of user interface hints. Rules and annotations have a different purpose here: rules can be used for extended validations and interactive forms. Annotations can be used to define user interface hints, such as which UI element should be rendered. That means one is not an easy replacement for the other. --- ## Post #29 by @thomas.beale [quote="pieterbos, post:28, topic:2406"] @thomas.beale the RESOURCE_ANNOTATIONS class in the resource specification seems to have disappeared in the latest specification. [/quote] [ADL2 relies on the BASE Resource specification now](https://specifications.openehr.org/releases/BASE/Release-1.2.0/resource.html). --- ## Post #30 by @thomas.beale [quote="pieterbos, post:28, topic:2406"] I think with the current ADL 2 rules, plus a well defined set of annotations, it is possible to create interactive templates with quite a lot of user interface hints. Rules and annotations have a different purpose here: rules can be used for extended validations and interactive forms. Annotations can be used to define user interface hints, such as which UI element should be rendered. That means one is not an easy replacement for the other. [/quote] Agree - although annotations get used for other things unrelated to UI as well including pure documentation. --- ## Post #31 by @pieterbos [quote="thomas.beale, post:29, topic:2406"] [ADL2 relies on the BASE Resource specification now](https://specifications.openehr.org/releases/BASE/Release-1.2.0/resource.html). [/quote] Yes, thanks. But the definition of the RESOURCE_ANNOTATIONS class is missing from that specification. --- ## Post #32 by @thomas.beale Ah - I see a class include is missing from the spec - it's in the UML diagram. I'll fix that. EDIT: [Fixed now in latest version](https://specifications.openehr.org/releases/BASE/latest/resource.html#_resource_annotations_class). --- ## Post #33 by @erik.sundvall @thomas.beale regarding an elsewhere mentioned idea of a possible "ADL3" serialisation/variant of ADL2 semantics, perhaps something like the above mentioned... ![image|407x54](upload://fR1GIQecTNonLY36PFul1LzIa0W.png) ...could be used to have consistent mapping between at/id codes of nodes and "readable" IDs? --- ## Post #34 by @pieterbos [quote="erik.sundvall, post:33, topic:2406"] regarding an elsewhere mentioned idea of a possible “ADL3” serialisation/variant of ADL2 semantics, perhaps something like the above mentioned… ![image|407x54](upload://fR1GIQecTNonLY36PFul1LzIa0W) …could be used to have consistent mapping between at/id codes of nodes and “readable” IDs [/quote] I think that is a good idea. Such an annotation - or feature, if ADL 3 - could also be very useful for stable developer friendly 'simple' API generation, that remains the same even if the archetype gets textual changes. Which as far as I know is not really the case for the current json web templates plus APIs that often appear to be used. Also it could improve the field names in generated APIs. It makes it more complicated to design archetypes though, unless these values can be auto-generated from the textual descriptions. Now clinicians without technical experience can design archetypes, you may need a more technical person to design and maintain sensible textual ids. The improved developer-friendlyness could very well be worth it... --- ## Post #35 by @joostholslag I need a little help to understand the impact for clinical modellers. If something is very valuable for developers, that usually translates to value for users. So it may well be worth it indeed. But we need to check wether it’s possible for (current) modellers to perform this job. And to think of ways to help them if we agree the value is there. Could you give an example of what I would have to do differently for a specific archetype/template please? --- ## Post #36 by @pablo @joostholslag I think this area shouldn't be mixed with clinical modeling at all, IMHO this goes in a different semantic layer, so developers can add what they need to display data on top of the template, so clinical modelers are not affected by these extra things. If a specific company wants to extend what templates can do, that's OK, though that extension won't be standard, so don't expect portability of those artifacts. But if we separate visual stuff from clinical models, we can keep artifacts compatible between vendors, clinical modelers unaffected and developers can do what they need. Then we can standardize that new layer with metadata for visual artifacts. This opinion is not shared by many here, I just don't like to mix things and to apply the Separation of Concerns concept to our models. --- ## Post #37 by @ian.mcnicoll While I broadly agree, Pablo, as a clinical modeller, I do often have to communicate information to developers which are a little broader than just the current template content e.g use of RM attributes, data conditionality, use of local aliases for term lists etc. which is really part of the semantic layer and not user-interface directions as such. This is very much part of what I would regard as the in the scope of the 'clinical modeller', especially when working with non-specialist developers. However, I still think this is a better handled as a separate path-based layer over the top of templates and not part of the current template scope. --- ## Post #38 by @Seref [quote="ian.mcnicoll, post:37, topic:2406"] However, I still think this is a better handled as a separate path-based layer over the top of templates and not part of the current template scope [/quote] this, and I historically broadly had the side of @pablo on this one :) Formal downstream artefacts is potentially the direction with the most ROI for openEHR specs to go at the moment. Recent OMOP presentation and implementation from @SevKohler is just another example of it. --- ## Post #39 by @erik.sundvall [quote="joostholslag, post:35, topic:2406"] Could you give an example of what I would have to do differently for a specific archetype/template please? [/quote] In archetypes usually nothing. When it comes to many templates a use case is often known and the things expressible in ADL rules would be good to have an equivalent workaround for, as shown in examples in this thread, using template annotations until all major template- and form-building tools support ADL rules. Things like if user responded yes to X then show Y. These are things that the template modeller nowadays instead have to pass down to form develpers in separate non standardised documentation and such show/hide logic then needs to be recreated in several different vendors systems (up to three times in our current case).Those working in a monoculture of only one vendor's system stack or that always have the same persons/teams deveoping both template and form may never understand this problem/need and will keep saying it should only be done in a separate vendor specific layer. Also an annotation like "a.hide_on_form" would be very useful. Look at the "Screening purpose" and "Symptom/sign name" in the "Symptom/sign screening questionnaire" archetype for example. In a template we usually set them to default fixed values that should not be shown to patients filling out the form. An annotation like "a.id" for giving a short meaningful id to a node would be good to make rules refering to it more readable (as suggested by @thomas.beale and @pieterbos above). --- ## Post #40 by @erik.sundvall [quote="ian.mcnicoll, post:37, topic:2406"] However, I still think this is a better handled as a separate path-based layer over the top of templates and not part of the current template scope. [/quote] Well, in ADL2 I believe a specialised template (potentially containing only the discussed extra annotations) would be exactly a separate path based layer on top of another "pure" (non-annotated) tempate. In ADL/OET/OPT 1.4 I guess a template copy with added annotations would work in a similar way (but needs more disciplined refactoring of two files when changed) So there is no need to invent another formalism/format for the main things discussed in this thread - annotations (and, if anyone so wishes, another template layer via specialisation or copy) would do the trick. --- ## Post #41 by @pablo [quote="ian.mcnicoll, post:37, topic:2406"] While I broadly agree, Pablo, as a clinical modeller, I do often have to communicate information to developers which are a little broader than just the current template content e.g use of RM attributes, data conditionality, use of local aliases for term lists etc. which is really part of the semantic layer and not user-interface directions as such. This is very much part of what I would regard as the in the scope of the ‘clinical modeller’, especially when working with non-specialist developers. [/quote] 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. --- ## Post #42 by @thomas.beale [quote="pablo, post:41, topic:2406"] is conditional us of RM attributes is part of content semantics? or is in another layer? [/quote] 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. --- ## Post #43 by @erik.sundvall 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... [quote="thomas.beale, post:42, topic:2406"] standard reusable templates (e.g. ‘Swedish discharge summary’ and the like) [/quote] ...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 [quote="pablo, post:41, topic:2406"] 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? [/quote] 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. --- ## Post #44 by @thomas.beale [quote="erik.sundvall, post:43, topic:2406"] then let’s make that general templte *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** [/quote] 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. [quote="erik.sundvall, post:43, topic:2406"] Some way of giving a node a progamming-friendly short meaningful ID/alias so that you don’t need to refer to the entire path in rules etc. [/quote] See [discussion here](https://discourse.openehr.org/t/rules-in-archetypes-getting-it-right/1272). 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. [quote="erik.sundvall, post:43, topic:2406"] 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. [/quote] That was our thinking on that. --- ## Post #45 by @pablo [quote="thomas.beale, post:44, topic:2406"] 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. [/quote] 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. --- ## Post #46 by @erik.sundvall @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 --- ## Post #47 by @thomas.beale Nice thinking. I like this. --- ## Post #48 by @joostholslag [quote="erik.sundvall, post:39, topic:2406"] if user responded yes to X then show Y. [/quote] @nedap we use ‘rules’ for that. At archetype or template level. [quote="erik.sundvall, post:39, topic:2406"] if user responded yes to X then show Y. Also an annotation like “a.hide_on_form” would be very useful. [/quote] 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: https://archetype-editor.nedap.healthcare/advanced/Nedap%20Basis%20archetypen If you click “to basic editor”, and (from your own repository) create a new archetype there’s a ui for basic rules creation: ![image|349x500](upload://oG1SyCP7B7dyyJoZHdhzYYt9GvZ.png) --- ## Post #49 by @thomas.beale 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. --- ## Post #50 by @erik.sundvall 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. [quote="thomas.beale, post:49, topic:2406"] the form level tools / builders etc treat the *data conditional rule* as a proxy for some show-on-form logic. [/quote] 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` and 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](https://ckm.openehr.org/ckm/archetypes/1013.1.4432) 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|668x344](upload://z6kDRDwaTBaicjxyPp7i5jchHDT.png) --- ## Post #51 by @erik.sundvall [quote="erik.sundvall, post:50, topic:2406"] 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? [/quote] Note to self + @thomas.beale and others to remember before settling on syntax discussed above: In [SEC internal disucssions](https://discourse.openehr.org/t/towards-adl3/3930/21) 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)" --- ## Post #52 by @erik.sundvall Just a real world example update from Sweden regarding the need for vendor neutral ways to annotate template nodes so that we spped up form construction in several tools from several vendors. The same templates are reused in many systems that have their own form-creation mechanisms. ![image|690x388](upload://4NAPGlzt5gJUlEAji179d1PhcX3.jpeg) --- ## Post #53 by @erik.sundvall Note: When experimenting with GUI/rendering hints, do note the needs and suggestions in the thread https://discourse.openehr.org/t/screening-questionnaire-archetypes-and-simple-checkbox-lists/5546 too --- **Canonical:** https://discourse.openehr.org/t/agreeing-on-optional-user-interface-hints-in-templates/2406 **Original content:** https://discourse.openehr.org/t/agreeing-on-optional-user-interface-hints-in-templates/2406