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?
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?
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
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.
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.
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).
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 aDV_TEXT
and aTERM_MAPPING
to aCODE_PHRASE
.
Iām struggling to understand all the different bindings, so please tell me if Iām wrong
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?
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.
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
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
(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). ADV_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 aDV_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).
- Design time guidance that a value, valueset or node has a relation
term 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. - Mapping of a text (string) in a
DV(_CODED)_TEXT.value
to a code in acode_string
in aCODE_PHRASE
in theDV(_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 aDV_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 thecode_string
in aTERM_MAPPING
in thatDV_TEXT
smappings
attribute. - If the text (string) value is fully determined by the code (āmultiple choice questionā) a
code_string
in aCODE_PHRASE
can be selected to aDV_CODED_TEXT.defining_code
and theDV_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 theDV_CODED_TEXT
is used to constrain possible values for anELEMENT.value
by setting thedefining_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?