Coding element and event names

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?

4 Likes

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

Hi Silje,
Reading the spec, I think you are correct. ELEMENT has a name attribute which is a DV_TEXT, this attribute is inherited from LOCATABLE 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?

2 Likes

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

2 Likes

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.

2 Likes

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.

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/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.

1 Like

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.

yeah, but you donā€™t know which one of the possible mappings completely describes the label

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).

1 Like

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:

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)

You are right but using Siljeā€™s example

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.

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?

1 Like

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?

Iā€™d say the intent of the current specs is pretty well-explained at Data Types Information Model

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.

2 Likes

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

1 Like

Do you have an example you can share?

Sure, a quick example
openEHR-EHR-CLUSTER.test_subset.v1.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)

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) 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 relationterm binding to a code in a terminology system (e.g. ["id26"] = <http://snomedct.info/id/249228009>). 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 <http://snomedct.info/id/24184005> as the code_string in a TERM_MAPPING in that DV_TEXTs mappings attribute.
  3. If the text (string) value is fully determined by the code (ā€˜multiple choice questionā€™) a code_stringin 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?

2 Likes