# Coding element and event names **Category:** [Specifications](https://discourse.openehr.org/c/specifications/6) **Created:** 2021-10-28 11:14 UTC **Views:** 1158 **Replies:** 56 **URL:** https://discourse.openehr.org/t/coding-element-and-event-names/1998 --- ## Post #1 by @siljelb In a lot of cases, it would be useful to be able to code the names of elements and events, when creating templates (and possibly also archetypes). If I understand it correctly, element and event names are of the DV_TEXT data type, which we should be able to specialise to DV_CODED_TEXT. How do we do this? --- ## Post #2 by @yampeku I would say that it's completely legal (in the same way you can specialize an EVENT into a POINT_EVENT or INTERVAL_EVENT). I'm assuming it's a tooling limitation --- ## Post #3 by @joostholslag Hi Silje, Reading the spec, I think you are correct. [ELEMENT](https://specifications.openehr.org/releases/RM/latest/data_structures.html#_element_class) has a name attribute which is a DV_TEXT, this attribute is inherited from [LOCATABLE](https://specifications.openehr.org/releases/RM/latest/common.html#_locatable_class) via ITEM. What I'm used to is the name is defined in the terminology section by binding the idcode of the element to a value in a language. from respiration archetype (adl2): `> definition` ... `> ELEMENT[id5] occurrences matches {0..1} matches { -- Rate` ... `terminology` ... ``` ["id5"] = < text = <"Rate"> description = <"The frequency of spontaneous breathing."> > ``` Specialising this to a DV_CODED_TEXT would look like: ELEMENT[id5.1] matches { -- Specialised rate name matches { DV_CODED_TEXT[id0.2] } } Our adl2 editor supports this. And archie is used to validate this without errors. So I suppose Diego is correct. But I'm struggling to understand the usecase. Letting the name of an element be different at runtime independent of the value feels strange to me. Why would you pick a different name for something like rate? Could you please explain a bit more about your usecase for coding the ELEMENT name? --- ## Post #4 by @yampeku I can see it being useful if you were to add codes to it, as they could serve as justification for some questions in a questionnaire for example (even end up somehow on the user interface). Apart from that, would probably ease multilinguality (by using the codes for translation), although that should be achievable with simple_text alternatives I believe --- ## Post #5 by @joostholslag What do you mean with codes? ID codes are already there for elements in adl2 and term bindings as well. And (term) mappings are already an attribute of a DV_TEXT. --- ## Post #6 by @siljelb My most clearly formed use case is events. Most OBSERVATION archetypes have the 'Any event', which in reality could be any situation. As an example, for a functionality I'm building right now, I'm renaming the events "since last encounter". What I'd like to do is to give it the SNOMED CT code "Since last encounter (qualifier value)" instead of this free text label. --- ## Post #7 by @ian.mcnicoll I think there main use-case is likely to be using an external terminology like SNOMED CT to precisely label some of these nodes. Now in theory you can make the sub-classed ELEMENT/name DV_CODED_TEXT be constrained to e.g. a SNOMED-CT rather than an internal id/atcode but I think this collides with ADL2 templating, and when I discussed this in the past with @borut.fabjan as a requirement, he was not keen on AD supporting that. One argument is that the text rubrics of external codes can be pretty messy, especially in SNOMED. however at run-time you can do something like this (in ADL1,4) ``` { "lab_test_report/lab_test/laboratory_result:0/result_value/_name|value": "Urea", "lab_test_report/lab_test/laboratory_result:0/result_value/_name|code": "365755003", "lab_test_report/lab_test/laboratory_result:0/result_value/_name|terminology": "SNOMED-CT" } ``` The alternative (and DIPS many have done this) is to carry any external coding as a DV_CODED_TEXT.mapping So in data this would look like ``` "vitals/vitals/body_temperature:0/any_event:0/symptoms:0/_name|value/_mapping:0|match": "=", "vitals/vitals/body_temperature:0/any_event:0/symptoms:0/_name|value/_mapping:0/target|terminology": "SNOMED-CT", "vitals/vitals/body_temperature:0/any_event:0/symptoms:0/_name|value/_mapping:0/target|code": "21794005", ``` TBH although this would work in canonical JSON, I'm not sure it is actually supported in FLAT/STRUCTURED but you should get the end result!! I think that is probably a safer option and probably lines up with some of the merging requirement for constraining 'mappings' in values as well. We are just working through a project that is bringing these quite clearly to light, and We'll share ASAP. So my suggestion for now is to use mappings but right now you cannot define/constrain those mappings in tooling - needs to be run-time implementation guidance. --- ## Post #8 by @joostholslag Hi Silje, specialising the event to include a snomed code should be legal. If I understand bindings in openEHR correctly, they should be term binding in archetypes, to indicate design guidance. If you want to record the binding as part of the stored composition, usually in a template, you should use the (term) mapping by setting the values in the adl definition section. I can try to help by generating the syntax if you tell me which one you're interested in. --- ## Post #9 by @yampeku [quote="joostholslag, post:5, topic:1998, full:true"] What do you mean with codes? ID codes are already there for elements in adl2 and term bindings as well. And (term) mappings are already an attribute of a DV_TEXT. [/quote] yeah, but you don't know which one of the possible mappings completely describes the label --- ## Post #10 by @ian.mcnicoll Yup - term bindings are just 'advisory' they do not (and should not IMO) find there way automatically into mappings, but we do need to work on making it possible to specify how mappings should be implemented at template-level (which not be the same as the bindings in the parent archetype, if they exist at all). --- ## Post #11 by @joostholslag [quote="ian.mcnicoll, post:7, topic:1998"] The alternative (and DIPS many have done this) is to carry any external coding as a DV_CODED_TEXT.mapping [/quote] The term mapping is in DV_TEXT right, you don't need the DV_CODED_TEXT specialisation complexity for that right? The spec on DV_CODED_TEXT says on this: > Misuse: If the intention is to represent a term code attached in some way to a fragment of plain text, `DV_CODED_TEXT` should not be used; instead use a `DV_TEXT` and a `TERM_MAPPING` to a `CODE_PHRASE` . I'm struggling to understand all the different bindings, so please tell me if I'm wrong :sweat_smile: --- ## Post #12 by @yampeku I think the key part is the "fragment", because dv_coded_text assumes that the value is the rubric from the code. I've always assumed that if you have a free text with several diagnosis you should use simple_text for that (and a term mapping for each one of the 'fragment'/found codes) --- ## Post #13 by @ian.mcnicoll You are right but using Silje's example [quote="siljelb, post:6, topic:1998"] What I’d like to do is to give it the SNOMED CT code “Since last encounter (qualifier value)” instead of this free text label. [/quote] You might want to name the event 'Since last visit' in the template but code it with SNOMED CT 12345| Since last encounter (qualifier value)|. Actually I think all of this needs another look as I think the technology and related requirements have changed a bit since the spec was first created, both for Locatable.name and text/coded_text values themselves as we have similar confusions/ collisions on that side too. Part of the issue seems to be that implementers (at least in the UK) are wary about querying on SNOMED-CT synonyms directly. Certainly policy in UK is to record the SNOMED concept code, alongside any synonym descriptor, presumably because of worries about performance issues. Also multi-lingual templates start to get tricky. I don't think I have a clear picture or answer but I think I'm tending to side with Fabio and (for now) use mappings to carry external terminologies against LOCATABLE.name. --- ## Post #14 by @ian.mcnicoll I think that has been a decent assumption but now that we carry preferred_term in CODE_PHRASE, I think we can 'liberate' /value in a DV_CODED text to be the text value that was entered or seen by the clinician, which may well be different from the formal rubric of the associated defining_code. Sorry a slight diversion from the original thread but I think the issues are pretty well identical whether we are trying to associate an external terminology with /value or /name/value. It might be good to start a new thread to discuss external terms and mappings more generally? --- ## Post #15 by @joostholslag I’m still struggling to understand the different code bindings tech in the specs. Is there any resource for me (and others) to read up on? --- ## Post #16 by @ian.mcnicoll I'd say the intent of the *current* specs is pretty well-explained at https://specifications.openehr.org/releases/RM/Release-1.1.0/data_types.html#_text_package The main thing to understand is that 'bindings' only exist in archetypes are design-time suggestions only. If you want to apply a 'binding' to appear in the patient data you need to put the code in a 'mapping' in the DV+TEXT/CODED_TEXT data structure. Right now this cannot be specified in tooling i.e in templates, and in practice the required 'mapping' in a particular locality or application might be quite different from anything in an archetype binding,, if that exists at all. Also there are different patterns of mapping and often not a straight single atCode-> SNOMED mapping. It might be conditional based on the content of other nodes. I think this is an area where we should sit down and revisit the requirements as they are now more apparent as SNOMED CT gets more traction and some of the more exotic promises like post-coordination and seamless synonyms have receded from practical implementation. --- ## Post #17 by @yampeku we use that kind of constraints using snomed subsets over term-based objects for data quality purposes. As you say it doesn't really end in templates, but it probably should --- ## Post #18 by @ian.mcnicoll Do you have an example you can share? --- ## Post #19 by @yampeku Sure, a quick example [openEHR-EHR-CLUSTER.test_subset.v1.adl|attachment](upload://njyEmJrEjp43gJ0fH24G4DRVr4S.adl) (2.4 KB) The uri is used to validate archetype-based data against the archetype. We actually modified the parser to support uri-based definitions across the archetype, which was really needed to these kind of snomed ecl definitions. So yeah, I think we should revisit the requirements :smiley: (Example contains atcodes in data types, which can break some parsers) --- ## Post #20 by @joostholslag I just had a study of the Data Types information Model. This indeed helps a lot. The key paragraph to me to understand mapping is: > The model of `DV_CODED_TEXT` is designed to capture the *actual* term chosen by the user or software at runtime, i.e. preferred term or synonym (for terminologies supporting synonyms), or a post-coordination of underlying distinct terms if an expression was chosen as the term (such as an expression supported by SNOMED CT). A `DV_CODED_TEXT` instance is used if the final textual value chosen by the user is the exact term text (preferred or other) returned by the terminology service for the key (i.e. `code_string` value). If the user makes even the slightest modification during data entry, a mapping (see [Section 5.1.5](https://specifications.openehr.org/releases/RM/latest/data_types.html#_mappings)) to a `DV_TEXT` should be used instead. So as I now understand it there is three levels of connecting text (string) to a code (e.g. SNOMED, LOINC etc). 1. Design time guidance that a value, valueset or node has a relation`term binding` to a code in a terminology system (e.g. `["id26"] = `). These codes should not directly end up in the EHR of an individual. 2. Mapping of a text (string) in a `DV(_CODED)_TEXT.value` to a code in a `code_string` in a `CODE_PHRASE` in the `DV(_CODED)_TEXT.term_mapping` to classify the meaning of the content of that text. But the original text is self standing and the coding is more of an enrichment of the original text. This can be used either to classify a text in an archetype. E.g. when designing an archetype indicate the archetype name matches a SNOMED code. For information that is about the archetype itself, not the content of the information that is stored as an instance of the model in the EHR. More often it is useful to map a template to classify it's nodes e.g. an element.name.value ("systolic blood pressure") at implementation time. And finally at run time the content of an element.value e.g. "Clinical interpretation" containing a `DV_TEXT` text string "elevated blood pressure" which can be coded post hoc by the user by selecting a classifying code (supplied by a terminology server). This code should then be stored in the EHR in DV_TEXT that holds the text string. By recording `` as the `code_string` in a `TERM_MAPPING` in that `DV_TEXT`s `mappings` attribute. 3. If the text (string) value is fully determined by the code ('multiple choice question') a `code_string`in a `CODE_PHRASE` can be selected to a `DV_CODED_TEXT.defining_code` and the `DV_CODED_TEXT.value` text string will be set automatically from the recorded terminology code, using a terminology server. So the user will only be able to select (a textual representation of) a code. And not make any edits or additions to that textual representation. Often in CKM *archetypes* the `DV_CODED_TEXT` is used to constrain possible values for an `ELEMENT.value` by setting the `defining_code` to an archetype local valueset containing coded values that are also local to the archetype, right? I'm still struggling to understand how the archetype's adl derives from the above described specification. Since the adl looks like: ``` ...ELEMENT[id9] occurrences matches {0..1} matches { -- Position value matches { DV_CODED_TEXT[id9015] matches { defining_code matches {[ac9061]} -- Position (synthesised) ... value_sets = < ["ac9061"] = < id = <"ac9061"> members = <"at1001", "at1002", "at1003", "at1004", "at1015"> ... terminology term_definitions = < ["en"] = < ["at1001"] = < text = <"Standing"> description = <"Standing at the time of blood pressure measurement."> > ``` As I don't see any syntax like `CODE_PHRASE.code_string` while the attribute of `DV_CODED_TEXT.defining_code` should be of that type. I'm also eager to see the contents of stored compositions from the examples under 2 and 3 from an example EHR to learn more about the syntax. Sorry Silje for hijacking your thread. Can somebody please split off this part of the topic, so we can go further in depth on Ian's proposal? --- ## Post #21 by @siljelb I have another use case. Archetypes like [Spirometry result](https://ckm.openehr.org/ckm/archetypes/1013.1.1414) are modelled using an internal cluster containing a "Test name" and a "Result" element due to the large number of possible tests which would make the archetype huge if every single one was modelled as a separate static element. The possible test names are included in the archetype as a value set of the "Test name" element: ![image|690x499](upload://qWbhHNW4fHUbFrl5UKr51FiTTdW.png) This looks forgivable in the picture, but when we want to start adding SNOMED CT bindings to the value set it breaks down a bit. The correct SNOMED CT code for these test names would be "observable entity" ones, like `50834005 |Forced vital capacity (observable entity)|`. At least to me, it's weird to put "observable entity" terms as the value set of a text element. It should really be the name of the "Result" element, which leads us back to the question: How do we utilise the DV_TEXT of the element names, and archetype them as DV_CODED_TEXT? Is this a tooling issue? Could we ask @borut.fabjan and @sebastian.garde to implement this in AD and CKM, and it'd work in implementations? Or are there larger issues? --- ## Post #22 by @yampeku If I understood it properly it would be solved in ADL1.4 with an acxxxx code that points to a snomed expression in URI form such as this http://snomed.info/ecl/%3c71388002 (which is any snomed procedure). I agree that observable entity seems to be the incorrect snomed hierarchy --- ## Post #23 by @siljelb [quote="yampeku, post:22, topic:1998"] snomed expression in URI form [/quote] Can I do this in AD? And what if I want to specify a set of SNOMED codes in the archetype, without a single value set URI to point to? [quote="yampeku, post:22, topic:1998"] I agree that observable entity seems to be the incorrect snomed hierarchy [/quote] I think it's the *correct* hierarchy, but it should be naming the actual data element of the result value (the "Result" DV_QUANTITY in the image above), and not be sitting in a DV_TEXT value set in another data element. --- ## Post #24 by @yampeku I would say that for sets of codes we should use the termset mechanism (available in CKM) to define valuesets that live outside the archetypes themselves. When having a defined valueset that way you could point them from the archetypes as URI. Currently there is only one termset defined in CKM (https://ckm.openehr.org/ckm/termsets/1013.29.9) but you could use that URI as is to point to the defined valueset, and evolve it at it's own pace. [quote="siljelb, post:23, topic:1998"] I think it’s the *correct* hierarchy, but it should be naming the actual data element of the result value (the “Result” DV_QUANTITY in the image above), and not be sitting in a DV_TEXT value set in another data element [/quote] Do you want to define something like this? I'm not sure that AD will let you do that ![imagen|369x107](upload://wyTWoM0MWgekxMaGNq5FH58Ab67.png) PS: just checked in athena vocabulary browser and observation entities would end up as measurements in OMOP, so I think they are the right codes for this (procedures would end up in other tables) --- ## Post #25 by @siljelb [quote="yampeku, post:24, topic:1998"] Do you want to define something like this? I’m not sure that AD will let you do that ![imagen|369x107](upload://wyTWoM0MWgekxMaGNq5FH58Ab67) [/quote] Yes, if I understand the components here correctly, something like this is what I want. :star_struck: And no, I don't think AD currently supports this either. --- ## Post #26 by @sebastian.garde CKM can be linked to a terminology server with support for FHIR Value Sets. Then, in archetypes you could use ac constraints as Diego has said, but link them to the value set, for example like this: `["ac0001"] = ` There are some example archetypes around this in the HiGHmed CKM - which is backed by a Terminology Server - for example: * [https://ckm.highmed.org/ckm/archetypes/1246.145.1481/](https://ckm.highmed.org/ckm/archetypes/1246.145.1481/) * [https://ckm.highmed.org/ckm/archetypes/1246.145.1478](https://ckm.highmed.org/ckm/archetypes/1246.145.1478) Mostly, used in templates though by them, see e.g. for some examples linking to Snomed as well as LOINC Value Sets. * [https://ckm.highmed.org/ckm/templates/1246.169.1047](https://ckm.highmed.org/ckm/templates/1246.169.1047) * [https://ckm.highmed.org/ckm/templates/1246.169.1134](https://ckm.highmed.org/ckm/templates/1246.169.1134) * [https://ckm.highmed.org/ckm/templates/1246.169.1516](https://ckm.highmed.org/ckm/templates/1246.169.1516) You'll find more examples by searching for ValueSet in CKM's Find Resources tab with the "Complete Search" option activated. --- ## Post #27 by @siljelb [quote="sebastian.garde, post:26, topic:1998"] CKM can be linked to a terminology server with support for FHIR Value Sets. [/quote] In most cases we want the archetype to be self-contained, so that it can be used both with and without a terminology server or a licence to for example SNOMED. So just linking to a value set in a terminology server isn't enough, we need to be able to do this internally in the archetype. --- ## Post #28 by @ian.mcnicoll I think there are two different issues here. 1. In the case where we have multiple 'names' for an observation, should we use name constraints in the same element, or should we carry the name of the observation in a separate element. Name constraints does feel like a more natural approach, and is a more 'openEHR' way of doing things but is quite confusing to integrators coming from other disciplines- that was why in the Lab analyte discussions, we moved (after a lot of discussion) from using name constraints on the Analyte result element, to adding a Analyte value element, which lines up with HL72 and FHIR. And I guess the same pattern has been adopted here. I understand what you mean when you say that it seems odd to have an observable as a value but that is exactly how it is used almost everywhere else outside openEHR. 2. Whether we use one approach or the other, we have an identical problem in how we represent the bindings and (in templates) the actual deployed mappings, especially as we will find situations whee the actual text recorded via the UI may differ from either our internal codes or the terminology rubrics, and we need to be able to constrain what might be quite complex structures. --- ## Post #29 by @ian.mcnicoll I agree but I think we should look at being able to use a FHIR Valueset inside the archetype, as an option. Controversy alert!! And that does not solve the problem of how we would express the constraints on that Valueset but I think it might be a good place to start. This whole area is definitely a tricky area and I think we should take a good look at what works and what does not, both in openEHR and FHIR. The 'use name constraint or not' issue is more one of style I suspect, though it might be easier to argue for name constraints if we go the mapping constraint challenge sorted and enabled in tools. --- ## Post #30 by @yampeku I think the key is, when coding result if the binding should point to the test code or to a code telling something like " 423100009 | results section (registry element) |" when doing "test name" as an element the codes go explicitly as data, while when putting in the result you will end up saying that a "result" (with semantics of registry) is mapped to a measurement code which could also cause their own set of problems --- ## Post #31 by @sebastian.garde Yes - where possible that seems very reasonable. Just saying that *if* we make external references to archetypes, nowadays it should likely be by referencing FHIR value sets rather than the original CKM (OTS) termsets. (Do I need to duck and cover?) Re support for TERM_MAPPING Diego also mentions above (and I agree with): I don't think these mappings would currently be displayed in CKM...but if someone can write them to the ADL, we should be able to extract and display these mappings as well. (Although the exact display may be a challenge and may need some discussion). --- ## Post #32 by @Seref [quote="siljelb, post:27, topic:1998"] In most cases we want the archetype to be self-contained, so that it can be used both with and without a terminology server or a licence to for example SNOMED. [/quote] That's interesting. What does the terminology policy in Norway look like? My observation is that in most countries (especially in ones with access to SNOMED), there're initiatives that parallel openEHR and FHIR modelling, but using terminologies, [like this one](https://www.datadictionary.nhs.uk/supporting_information/snomed_ct_refset.html). Would not it be a challenge to keep archetypes synchronised to this type of work if you *embed* (if I may call it that) the subset of terminologies into Archetypes instead of referencing them? I won't speculate further in case I'm completely clueless, you and/or @ian.mcnicoll can educate me on this one. :) --- ## Post #33 by @ian.mcnicoll Typically these national terminology efforts create large thematic lists based on SNOMED hierarchies that are often othogonal to the detailed requirements inside archetypes (or indeed FHIR resources). In other words the exact codes you need are often very contextual to the specific archetype e.g. body position codes for pulse vs. body site codes for blood pressure measurement. Added to that , if you look at e,g the Dutxh ZIBS standards they often have mixes of SNOMED and other terminolgies very specific to the 'archetypes'. Traditional refsets have not been an option However the advent of FHIR Vsaluesets has made things a bit more blurry and I can imagine use-cases for managing some highly contextual codelists internally vs others referencing out to nationally managed Valuesets. Both approaches have validity depending on circumstances. @Seref - schooling fees applicable as-usual :beers: :wink: --- ## Post #34 by @sebastian.garde In the end, to me the decision boils down down to a variety of factors, e.g. - how large is it and likely is it to change/ evolve over time - how well is the coverage for this in the (agreed) target terminology/-ies - who can coordinate/govern the (external/fhir) value sets (and how) - how can you provide access to them, possibly over a long time. Some of it may also be easier to realize in a national setting than internationally. Really just looking for some 🍺 too. --- ## Post #35 by @Seref [quote="ian.mcnicoll, post:33, topic:1998"] In other words the exact codes you need are often very contextual to the specific archetype e.g. body position codes for pulse vs. body site codes for blood pressure measurement. Added to that , if you look at e,g the Dutxh ZIBS standards they often have mixes of SNOMED and other terminolgies very specific to the ‘archetypes’. Traditional refsets have not been an option [/quote] Thanks, this is very helpful. Fees earned in full (pints). [quote="sebastian.garde, post:34, topic:1998"] who can coordinate/govern the (external/fhir) value sets (and how) [/quote] Very good question criteria, in face of the reality @ian.mcnicoll described. Fees earned in full also. --- ## Post #36 by @siljelb Picking this thread up again two years later... :sweat_smile: Talking with @bna about this today made me realise that using DV_CODED_TEXT as an element name is essentially what we do when we apply a run-time name constraint to an element in an archetype, whether we use internal (at) codes or an external terminology. If we could apply (external terminology) run-time name constraints to elements at the template level, this issue would be solved. Incidentally, this could also solve the issue of paths prone to change whenever a typo is discovered, by using paths like ``` [openEHR-EHR-OBSERVATION.problem_screening.v1]/data[at0001]/events[at0002]/data[at0003]/items[at0022, and name/defining_code/code_string='5' and name/defining_code/terminology_id/value='my_local_terminology']/items[at0005] ``` instead of ``` [openEHR-EHR-OBSERVATION.problem_screening.v1]/data[at0001]/events[at0002]/data[at0003]/items[at0022, and name/value='Have you ever had any had a lung or heart disese or any other thing we shuld know about?']/items[at0005] ``` ( ^ this is a made up example, but unfortunately this kind of question (typos and all) is all too common in questionnaires) --- ## Post #37 by @siljelb Four likes and no comments my previous post two weeks ago :sweat_smile: [quote="siljelb, post:36, topic:1998"] If we could apply (external terminology) run-time name constraints to elements at the template level [/quote] Would this work? What would it take to implement this? Spec changes, or just (modelling) tooling changes? I guess existing CDRs should support it, since it terms of persistence and querying it's already supported through DV_TEXT -> DV_CODED_TEXT? --- ## Post #38 by @ian.mcnicoll Yes- we can already by 'renaming' the event/name/value/defining_code as a CODED_TEXT. And ADL2 will give us 'proper' coded renames. It is just that we cannot do this in AD/ ADL1.4 - it would need to be applied at run-time. There is also a good argument for using event/name/value/mappings to carry external terminologies like SNOMED CT rather than defining_code --- ## Post #39 by @siljelb [quote="ian.mcnicoll, post:38, topic:1998"] It is just that we cannot do this in AD/ ADL1.4 - it would need to be applied at run-time. [/quote] Respectfully, are you sure this can't be done with ADL1.4? I've tried hacking a test archetype like this: ```adl events cardinality matches {1..*; unordered} matches { EVENT[at0002] occurrences matches {0..*} matches { -- Any event name matches { DV_CODED_TEXT matches { defining_code matches { [SNOMED-CT::10987654321] } } } data matches { ITEM_TREE[at0003] matches { -- Tree ``` ...and it seems like it's producing a perfectly valid OPT (I've removed all instances of `` and `` for readability): ```xml EVENT at0002 name false DV_CODED_TEXT defining_code false CODE_PHRASE SNOMED-CT 10987654321 ``` This **also works** if I use an archetype with the element name unconstrained, and hack the template instead: ```adl ELEMENT[at0004] occurrences matches {0..1} matches { -- DV_TEXT value matches { DV_TEXT matches {*} } } ``` ```json { "@type" : "C_COMPLEX_OBJECT", "rmTypeName" : "ELEMENT", "occurrences" : "0..1", "nodeId" : "at0004.1", "attributes" : [ { "@type": "C_ATTRIBUTE", "rmAttributeName": "name", "children": [ { "@type": "C_COMPLEX_OBJECT", "rmTypeName": "DV_CODED_TEXT", "attributes": [ { "@type": "C_ATTRIBUTE", "rmAttributeName": "defining_code", "children": [ { "@type": "C_TERMINOLOGY_CODE", "rmTypeName": "TERMINOLOGY_CODE", "occurrences": "1..1", "terminologyId": { "value": "SNOMED-CT" }, "constraint": [ "10987654321" ], "selectedTerminologies": [] } ] } ], "attributeTuples": [] } ] } } ``` ```xml at0004 name false DV_CODED_TEXT defining_code false CODE_PHRASE SNOMED-CT 10987654321 ``` --- ## Post #40 by @siljelb Any thoughts/opinions about this? @ian.mcnicoll @borut.fabjan @sebastian.garde ? :smile: --- ## Post #41 by @ian.mcnicoll Yes sure - that is valid ADL1.4 but that's overriding the .name attribute by sub-classing it to a DV_CODED_TEXT, rather than specialising the archetypeId itself , which is what will happens in ADL2 So conceptually more like ``` EVENT[at0002.1] occurrences matches {0..*} matches { -- Any event name matches { DV_CODED_TEXT matches { defining_code matches { [SNOMED-CT::10987654321] } } } ``` The approach you are suggesting, I did try in the past as a way of 'labelling' lab tests with LOINC or other external terms. I took this it @borut.fabjan and he was not keen on the idea, though accepted it is technically acceptable from an RM Pov. His argument (I think) was that esp with AD2, things start to get messy , especially if we are using run-time name constraints, and then perhaps having to add external codings. He did persuade me that it may be cleaner to use term_mappings , and leave the original defining_code as whatever was defined in the archetype. That has its own issues of course in terms of tooling support. --- ## Post #42 by @siljelb [quote="ian.mcnicoll, post:41, topic:1998"] So conceptually more like [/quote] If I understand correctly, your example is conceptually different from what I've hacked together? If so, in what way is it different? :smile: --- ## Post #43 by @ian.mcnicoll @yampeku -could you send me through the ADL that sits behind your Linkehr archetype snippet - basically we need the same structure but associated with LOCATABLE.name . I am tryintg to edit manually and getting confused, especially handling multiple mapping constraintse.g a LOINC mapping and a SNOMED mapping. ```yaml EVENT[at0006] occurrences matches {0..*} matches { -- Any event data matches { ITEM_TREE[at0003] matches { -- blood pressure items cardinality matches {0..*; unordered} matches { ELEMENT[at0004] occurrences matches {0..1} matches { -- Systolic name matches { DV_TEXT matches { mappings = matches matches TERM_MAPPING .... > > } --- ## Post #44 by @yampeku Something like this? > ELEMENT[at0005] occurrences matches {0..1} matches { -- Código SPREC > value existence matches {0..1} matches { > DV_TEXT[at0006] occurrences matches {0..1} matches { -- DV_TEXT > value existence matches {1..1} matches {/.*/} > } > } > name existence matches {1..1} matches { > DV_TEXT[at0002] occurrences matches {0..1} matches { -- DV_TEXT > mappings existence matches {0..1} cardinality matches {0..*; unordered; unique} matches { > TERM_MAPPING[at0025] occurrences matches {0..*} matches { -- TERM_MAPPING > target existence matches {1..1} matches { > [ac0001] > } > } > } > } > } > } Probably remove the at code in TERM_MAPPING as that will make it to not parse on AD --- ## Post #45 by @ian.mcnicoll Can you take it down a level under `target existence matches {1..1} matches { [ac0001]` to use something like target existence matches {1..1} matches { CODE_PHRASE occurrences matches {1..1} matches { code_string existence matches {1..1} matches {"123445678"} } However, I can see that this is setting a constraint, when what we really want is to set a default value?? Help!! --- ## Post #46 by @siljelb So if I understand this correctly, since this is a `/name/mappings/target/code_string` instead of `name/defining_code/code_string`, it's easier to handle technically? And an AQL path for this would be something like `[openEHR-EHR-OBSERVATION.problem_screening.v1]/data[at0001]/events[at0002]/data[at0003]/items[at0022, and name/mappings/target/code_string='5' and name/mappings/target/terminology_id/value='my_local_terminology']/items[at0005]`? --- ## Post #47 by @ian.mcnicoll `[openEHR-EHR-OBSERVATION.problem_screening.v1]/data[at0001]/events[at0002]/data[at0003]/items[at0022, and name/mappings/target/code_string='5' and name/mappings/target/terminology_id/value='my_local_terminology']/items[at0005]` MY Terminology` Yes. There are some discussion about making this a bit easier with something like OBSERVATION.problem_screening.v1]/data[at0001]/events[at0002]/data[at0003]/items[at0022].CODE_PHRASE_MATCHES("5:MY Terminology)" which would also check in both the name.defining_code and mappings.target for a matching CODE_PHRASE, though this is more helpful when check for matches on the value side I've been trying to explain to myself the challenge with the name-> DV_CODED_TEXT approach, and it mainly comes down to the fact that in ADL2, name becomes associated with the atCode introduced by the template. Then if you (legally) sub-class /name/value to a DV_CODED_TEXT the name/value becomes associated with the defining_code in name. Archetype - level ```EVENT .archetype_node_id = 'at0002' .name .value = 'Any Event' ``` ADL2 Template - level ```EVENT .archetype_node_id = 'at0002.1' .name .value = 'My Template atCode term' ``` ADL2 Template - level with name -> DV_CODED_TEXT ```EVENT .archetype_node_id = 'at0002.1' .name .value = 'SNOMED CT term' -defining_code .code_string = '1234567' .terminology_id 'SNOMED-CT' ``` It is all legal but it is starting to get pretty convoluted to explain and implement in comparison with using term mappings. ```EVENT .archetype_node_id = 'at0002.1' .name .value = 'My template atCode term' .mapping . target .code_string = '1234567' .terminology_id = 'SNOMED-CT' .preferred_term'' = 'SNOMED Term' ``` which more nicely maps into FHIR CodableConcept and avoids sub-classing which is elegant in modelling terms but a pain technically. ``` .value = 'My Template atCode term' .coding[0] code = 'at0002.1' system = 'local' display ='My Template atCode term' .coding[0] code = '123456' system = 'SNOMED-CT' display ='SNOMED term' ``` The downside of mappings is that they are not supported in tooling well but we really need to solve that problem in any case, for all sorts of other reasons. --- ## Post #48 by @yampeku Wouldn't that be the assumed value of the string? This is supported in strings > name existence matches {1..1} matches { > DV_TEXT[at0002] occurrences matches {0..1} matches { -- DV_TEXT > mappings existence matches {0..1} cardinality matches {0..*; unordered; unique} matches { > TERM_MAPPING[at0025] occurrences matches {0..*} matches { -- TERM_MAPPING > target existence matches {1..1} matches { > CODE_PHRASE[at0026] occurrences matches {1..1} matches { -- CODE_PHRASE > code_string existence matches {1..1} matches {/.*/; "123445678"} > } > } > } > } > } > } --- ## Post #49 by @ian.mcnicoll I don't think 'assumed_value' is correct - that is not intended to be a 'default' it is a design_time suggestion that if e.g 'Position' is missing then you might possibly assume that the patient is 'lying down'. However, thanks, this has clarified for me that containing mappings is not the way to go in terms of 'asserting' bindings to be carried into the record (however we do it). --- ## Post #50 by @yampeku Could it mean "if no code is present then we can assume this one"? As we want recommendations probably is the closest we can get without introducing a constraint without the ability of putting the new keywords --- ## Post #51 by @ian.mcnicoll [quote="yampeku, post:50, topic:1998"] “if no code is present then we can assume this one” [/quote] For me that is a 'default value' i.e it is safe to populate the record with this value, if now is given. 'Assumed' is much softer - it just means at a human level you might be safe to assume that the 'patient was lying down' but TBH, I don't think we use that now at all, as IMO it is unhelpfully confused with 'default' and would be better just expressed in description or comment as narrative. --- ## Post #52 by @sebastian.garde [quote="ian.mcnicoll, post:51, topic:1998"] ‘Assumed’ is much softer [/quote] We should probably deprecate this assumed value...You have given the main, maybe even the only example for it that I have ever heard, and even there it seems of dubious value to me. --- ## Post #53 by @thomas.beale [quote="sebastian.garde, post:52, topic:1998"] We should probably deprecate this assumed value…You have given the main, maybe even the only example for it that I have ever heard, and even there it seems of dubious value to me. [/quote] It was an idea of Sam's (and maybe Dipak), from close to 20y ago. It was something I think they thought would generalise across medicine, but over time the only examples that have ever emerged always seem to have been patient position during BP measurement and exertion during heart rate measurement. For good or bad, we have engineered the capability to have 'assumed values' in any primitive data type. This could potentially be used as is to implement some sort of default values, but since default values need to be definable for larger granularity objects (potentially even up to whole Observations) it might be better to deprecate it. --- ## Post #54 by @yampeku [quote="sebastian.garde, post:52, topic:1998"] We should probably deprecate this assumed value…You have given the main, maybe even the only example for it that I have ever heard, and even there it seems of dubious value to me. [/quote] I think nowadays we use annotations for this extra info By the way, if I remember correctly there are archeytpes in CKM with assumed values --- ## Post #55 by @sebastian.garde [quote="yampeku, post:54, topic:1998"] By the way, if I remember correctly there are archeytpes in CKM with assumed values [/quote] Definitely the v1's of Blood pressure and Pulse/Heart beat, but both have been superseeded by v2 without any assumed_values. There are few others in drafts, e.g. *Swallowing* in https://ckm.openehr.org/ckm/archetypes/1013.1.250 ``` ELEMENT[at0011] occurrences matches {0..1} matches { -- Swallowing value matches { 0|[local::at0012], -- Unable to swallow 1|[local::at0013], -- Some ability to swallow 2|[local::at0014], -- Reduced swallow 3|[local::at0015]; -- Normal 0 -- assumed value } } ``` where the assumed_value is "Unable to Swallow". --- ## Post #56 by @varntzen That OBS.infant_feeding archetype is really old, in draft and also a mix of volume and the infants "feeding function", and the archetype should most likely be deprecated or moved to the "Archetype graveyard" incubator. It would be interesting to know if there are any *assumed value* in published archetypes. --- ## Post #57 by @sebastian.garde [quote="varntzen, post:56, topic:1998"] It would be interesting to know if there are any *assumed value* in published archetypes. [/quote] Yes - assumed values are quite hard to search for (due to the common syntax where the assumed value is just separated with a "; "). I have found 13 active archetypes where the current revision has at least one assumed value. All of them have a DRAFT or INITIAL status: ``` [ { "cid": "1013.1.250", "resourceMainDisplayName": "Feeding", "resourceMainId": "openEHR-EHR-OBSERVATION.infant_feeding.v0", "status": "DRAFT", "projectName": "Common resources" }, { "cid": "1013.1.1370", "resourceMainDisplayName": "Visual field measurement", "resourceMainId": "openEHR-EHR-OBSERVATION.visual_field_measurement.v0", "status": "DRAFT", "projectName": "Ophthalmology domain" }, { "cid": "1013.1.1677", "resourceMainDisplayName": "Audiogram test result", "resourceMainId": "openEHR-EHR-OBSERVATION.audiogram_result.v0", "status": "DRAFT", "projectName": "Hearing" }, { "cid": "1013.1.1689", "resourceMainDisplayName": "Acquisition details on eye fundus images", "resourceMainId": "openEHR-EHR-CLUSTER.acquisition_details_on_eye_fundus_images.v0", "status": "INITIAL", "projectName": "AMD, Diabetic Retinopathy & Glaucoma" }, { "cid": "1013.1.1823", "resourceMainDisplayName": "Recommendation on the treatment of AMD", "resourceMainId": "openEHR-EHR-EVALUATION.recommendation-amd_treatment.v0", "status": "INITIAL", "projectName": "AMD, Diabetic Retinopathy & Glaucoma" }, { "cid": "1013.1.1845", "resourceMainDisplayName": "Tympanogram test result - 226Hz", "resourceMainId": "openEHR-EHR-OBSERVATION.tympanogram_226hz.v0", "status": "DRAFT", "projectName": "Hearing" }, { "cid": "1013.1.2015", "resourceMainDisplayName": "Central corneal thickness details", "resourceMainId": "openEHR-EHR-CLUSTER.corneal_thickness_details.v0", "status": "INITIAL", "projectName": "AMD, Diabetic Retinopathy & Glaucoma" }, { "cid": "1013.1.2159", "resourceMainDisplayName": "Recommended treatment for glaucoma", "resourceMainId": "openEHR-EHR-EVALUATION.recommendation-glaucoma_treatment.v0", "status": "INITIAL", "projectName": "AMD, Diabetic Retinopathy & Glaucoma" }, { "cid": "1013.1.2350", "resourceMainDisplayName": "Hearing screening test result", "resourceMainId": "openEHR-EHR-OBSERVATION.hearing_screening_result.v0", "status": "DRAFT", "projectName": "Hearing" }, { "cid": "1013.1.2512", "resourceMainDisplayName": "Mydriasis application", "resourceMainId": "openEHR-EHR-CLUSTER.mydriasis_application.v0", "status": "INITIAL", "projectName": "AMD, Diabetic Retinopathy & Glaucoma" }, { "cid": "1013.1.2859", "resourceMainDisplayName": "Microscopy renal biopsy non neoplastic", "resourceMainId": "openEHR-EHR-CLUSTER.microscopy_renal_biopsy_non_neoplastic.v0", "status": "DRAFT", "projectName": "Norwegian referenced archetypes" }, { "cid": "1013.1.3556", "resourceMainDisplayName": "Jugular venous pressure", "resourceMainId": "openEHR-EHR-OBSERVATION.jugular_venous_pressure.v0", "status": "DRAFT", "projectName": "Common resources" }, { "cid": "1013.1.3358", "resourceMainDisplayName": "Histoimmunogenetic typing", "resourceMainId": "openEHR-EHR-CLUSTER.histoimmunogenetic_typing.v0", "status": "INITIAL", "versionAsset": 1, "versionAssetLatest": 1, } ] ``` --- **Canonical:** https://discourse.openehr.org/t/coding-element-and-event-names/1998 **Original content:** https://discourse.openehr.org/t/coding-element-and-event-names/1998