Coding element and event names

I have another use case. Archetypes like Spirometry result 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:

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?

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/<71388002 (which is any snomed procedure). I agree that observable entity seems to be the incorrect snomed hierarchy

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?

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.

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 (Clinical Knowledge Manager) but you could use that URI as is to point to the defined valueset, and evolve it at it’s own pace.

Do you want to define something like this? I’m not sure that AD will let you do that
imagen

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)

2 Likes

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.

1 Like

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"] = <terminology://fhir.hl7.org/ValueSet/$expand?url=http://hl7.org/fhir/vs/snomed-example-vs>

There are some example archetypes around this in the HiGHmed CKM - which is backed by a Terminology Server - for example:

Mostly, used in templates though by them, see e.g. for some examples linking to Snomed as well as LOINC Value Sets.

You’ll find more examples by searching for ValueSet in CKM’s Find Resources tab with the “Complete Search” option activated.

2 Likes

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.

1 Like

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.

  1. 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.
1 Like

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.

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

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

2 Likes

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. 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. :slight_smile:

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:

3 Likes

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 :beer: too.

4 Likes

Thanks, this is very helpful. Fees earned in full (pints).

Very good question criteria, in face of the reality @ian.mcnicoll described. Fees earned in full also.

2 Likes

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)

5 Likes

Four likes and no comments my previous post two weeks ago :sweat_smile:

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?

1 Like

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

Respectfully, are you sure this can’t be done with ADL1.4?

I’ve tried hacking a test archetype like this:

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 <existence /> and <occurrences /> for readability):

<rm_type_name>EVENT</rm_type_name>
<node_id>at0002</node_id>
<attributes xsi:type="C_SINGLE_ATTRIBUTE">
    <rm_attribute_name>name</rm_attribute_name>
    <match_negated>false</match_negated>
    <children xsi:type="C_COMPLEX_OBJECT">
        <rm_type_name>DV_CODED_TEXT</rm_type_name>
        <node_id></node_id>
        <attributes xsi:type="C_SINGLE_ATTRIBUTE">
            <rm_attribute_name>defining_code</rm_attribute_name>
            <match_negated>false</match_negated>
            <children xsi:type="C_CODE_PHRASE">
                <rm_type_name>CODE_PHRASE</rm_type_name>
                <node_id></node_id>
                <terminology_id>
                    <value>SNOMED-CT</value>
                </terminology_id>
                <code_list>10987654321</code_list>
            </children>
        </attributes>
    </children>
</attributes>

This also works if I use an archetype with the element name unconstrained, and hack the template instead:

ELEMENT[at0004] occurrences matches {0..1} matches {    -- DV_TEXT
	value matches {
		DV_TEXT matches {*}
	}
}
{
    "@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": []
            }
        ]
    }
}
<node_id>at0004</node_id>
<attributes xsi:type="C_SINGLE_ATTRIBUTE">
    <rm_attribute_name>name</rm_attribute_name>
    <match_negated>false</match_negated>
    <children xsi:type="C_COMPLEX_OBJECT">
        <rm_type_name>DV_CODED_TEXT</rm_type_name>
        <node_id></node_id>
        <attributes xsi:type="C_SINGLE_ATTRIBUTE">
            <rm_attribute_name>defining_code</rm_attribute_name>
            <match_negated>false</match_negated>
            <children xsi:type="C_CODE_PHRASE">
                <rm_type_name>CODE_PHRASE</rm_type_name>
                <node_id></node_id>
                <terminology_id>
                    <value>SNOMED-CT</value>
                </terminology_id>
                <code_list>10987654321</code_list>
            </children>
        </attributes>
    </children>
</attributes>
1 Like

Any thoughts/opinions about this? @ian.mcnicoll @borut.fabjan @sebastian.garde ? :smile:

1 Like