The following is a straw-man proposal to aid discussion with the group. This is a limited, happy-path scenario, including expression creation and querying. Many other operations could be performed using expressions.
- SOMETHING ABOUT R4 because of our delivery timelines-
Use Case
- An orthopaedic clinician wants to record the procedure "Closed reduction of fracture of left radius"
- We assume the EHR system supports searching precoordinated codes and, if necessary, creating postcoordinated codes
- However, this EHR can only store codes up to 18 digits in length
- The clinician selects the 87971000 |Closed reduction of fracture of radius (procedure)| with 272741003 |Laterality (attribute)| = 7771000 |Left (qualifier value)|
- Then the orthopaedic department wants to report on the number of closed reduction vs. open reduction procedures.
Solution Overview
- A CodeSystem supplement will be used to act as an expression library
- A ConceptMap will be used to translate expressions to (and from) shorter codes for systems with restricted code lengths
Create Expression Repository
Create Code System Supplement for Expressions
Create the CodeSystem supplement. This supplements a specific module and version of SNOMED CT. 1234007
is the identifier of the module that contains the postcoordination content.
PUT /CodeSystem/snomed-exp
{
"resourceType": "CodeSystem",
"url": "http://snomed.info/sct", /* This system holds (combinations of) published codes */
"version": "http://snomed.info/xsct/1234007", /* The supplement includes the unpublished content in this module */
"content": "supplement",
"supplements": "http://snomed.info/sct|http://snomed.info/sct/900000000000207008/version/20220131", /* Supplements a specific module and version */
"valueSet": "http://snomed.info/xsct/1234007?fhir_vs" /* Is this correct? */
}
The PUT operation can be used to create a resource with a specific id. Using POST would generate an id.
Create Code System for Expression Identifiers
This is only needed if EHR cannot store expressions: Create a CodeSystem for expression identifiers, specifying the CodeSystem.valueSet url.
PUT /CodeSystem/snomed-exp-id
{
"resourceType": "CodeSystem",
"url": "http://snomed.info/snomed/exp-id/1101234",
"valueSet": "http://snomed.info/snomed/exp-id/1101234?fhir_vs"
}
Create Expression to Identifier Concept Map
Create the ConceptMap to map expressions to expression identifiers. This will be populated manually.
PUT /ConceptMap/snomed-exp-id-map
{
"resourceType": "ConceptMap",
"url": "http://snomed.info/snomed/exp-id-map",
"source": {
"sourceUri": "http://snomed.info/xsct/1234007?fhir_vs"
},
"target": {
"targetUri": "http://snomed.info/snomed/exp-id/1101234?fhir_vs"
}
}
Add Expressions to Repository
The EHR system attempts to update the CodeSystem supplement with the expression, using either classifiable-form or close-to-user form depending on what is supported by the terminology server.
Example expression in close-to-user form: 87971000 |Closed reduction of fracture of radius (procedure)| : 272741003 |Laterality (attribute)| = 7771000 |Left (qualifier value)|
Add CTU form Expression to CodeSystem Supplement
- Use the PATCH operation to update the existing CodeSystem supplement resource, adding an expression that combines existing codes.
PATCH /CodeSystem/snomed-exp
{
"concept": [{
"code": "87971000:272741003=7771000"
}]
}
The terminology server must perform MRCM domain-attribute and attribute-range validation. If close-to-user form is supported, then the expression should be transformed to classifiable form before MRCM validation. The terminology server may also classify the expression at this point to reduce the processing required during subsequent operations that use the hierarchy.
Use Translate to Generate an Expression Identifier
Use an algorithmic concept map to generate an SCTID for the expression. This is similar to Ontoserver's algorithmic automap strategies. A SNOMED Namespace is required for identifier generation, this is included in the map URI.
The Implementation Support Team has ideas about how to simplify the process of namespace assignment for postcoordination.
GET /ConceptMap/$translate?
url=http://snomed.info/xsct/101101234112/pce-id-gen/1101234
&system=http://snomed.info/xsct/1234007
&code=87971000:272741003=7771000
- The URI format for the SCTID generation automap is http://snomed.info/xsct/{module}/pce-id-gen/{namespace}
- The expression system and code must also be provided so that the automap can return the existing identifier for an expression if one already exists
- Translate operation returns newly generated identifier (SCTID or UUID)
Response example:
{
"resourceType": "Parameters",
"parameter": [
{
"name": "result",
"valueBoolean": true
},
{
"name": "match",
"part": [
{
"name": "source",
"valueString": "http://snomed.info/xsct/101101234112/pce-id-gen/1101234"
},
{
"name": "equivalence",
"valueCode": "equal"
},
{
"name": "concept",
"valueCoding": {
"system": "http://snomed.info/xsct",
"code": "101101234165"
}
}
]
}
]
}
Feedback from group (moved from earlier version)
- ML
- I would generate UUIDs for expressions rather than using SCTIDs
- Type 5? UUID could take expression as the seed to create deterministic ids
- If short identifier could be generated within the EHR (Type 5 UUID) then this could be included as an alternate identifier when inserting the expression in the supplement.
- KK
- Expression id generation could be implementation specific
- SCTID may be the only option in some cases
- These can still be clearly identified as expressions by the fact that they only exist in the supplement and that they use the 16 partition id (third from last and second from last digits).
Create Map Entry from Expression to Identifier
Create a map record from expression to the generated code using PATCH.
PATCH /ConceptMap/snomed-exp-id-map
{
"group": [{
"source": "http://snomed.info/sct",
"sourceVersion": "http://snomed.info/xsct/1234007",
"target": "http://snomed.info/snomed/exp-id/1101234","element": [
"code": "87971000:272741003=7771000",
"target": {
"code": "101101234165",
"equivalence": "equivalent"
}
]
}]
}
The generated identifier "101101234165
" should be used as a whole. (It contains item identifier "10", namespace "1101234", partition identifier "16", and check digit "5".)
The generated identifier, from CodeSystem "http://snomed.info/snomed/exp-id/1101234", can be stored in the EHR record. The code system is derivable from the code, within the bounds of SNOMED CT codes, because of the 16 partition identifier and the fact that the code contains the namespace.
Use Expression Repository
Lookup Expression Identifier from Expression
GET /ConceptMap/snomed-exp-id-map/
$translate?
system=http://snomed.info/xsct/1234007
&code=87971000:272741003=7771000
This returns an equivalent match to the expression identifier and its system.
Lookup Expression from Expression Identifier
GET /ConceptMap/snomed-exp-id-map/
$translate?
reverse=true &system=http://snomed.info/snomed/exp-id/1101234
&code=101101234165
This returns an equivalent match to the expression itself and its system.
Query Expression
The department would like to report on the number of closed reduction procedures performed. All codes representing this type of procedure must be fetched so that they can be matched against the EHR records.
- Expand an intentional ValueSet using the expression library (and the Code System it supplements) with ECL "< 86052008 |Closed reduction of fracture (procedure)|"
- GET /ValueSet/$expand?url=
http://snomed.info/xsct/1234007?fhir_vs=ecl/<86052008
- GET /ValueSet/$expand?url=
- Expand an intentional ValueSet using the expression library, the Code System it supplements and a derivative (module 98763002)
- GET /ValueSet/$expand?url=
http://snomed.info/xsct/1234007;module/98763002?fhir_vs=ecl/<86052008
- GET /ValueSet/$expand?url=
---------------------
Previous Feedback
- ML - this syntax would not work today. Perhaps use a POST with a ValueSet def based on a SNOMED CT code system, including the code system supplement.. there is a ticket related to referencing supplements
- The code system and supplement in the definition would need to match (inc version)
The terminology server will expand the ECL using the current version of the CodeSystem supplement and the precoordinated SNOMED CT Edition and the version that the supplement is dependent on. The results will contain a mixture of simple codes and expressions:
{
"resourceType": "ValueSet",
"url": "/ValueSet/$expand?http://example.org/snomed-pce-library?fhir_vs=ecl/<86052008",
...
"expansion": {
"id": "c770c558-57a3-4512-9099-a4c7e39bb618",
"total": 23,
"offset": 0,
"parameter": [
{
"name": "version",
"valueUri": "?"
}
],
"contains": [
{
"system": "http://snomed.info/sct",
"code": "440143005",
"display": "Closed reduction of closed nondisplaced rib fracture"
},
{
"system": "http://snomed.info/sct",
"code": "311446006",
"display": "Closed reduction of fracture and traction"
},
{
"system": "http://snomed.info/sct",
"code": "87971000:272741003=7771000",
"display": "Closed reduction of fracture of radius:Laterality=Left"
}
....
The last code in the results is our expression. It includes a term generated using the expression.
Feedback
- ML
- In R5 the alternate id could be requested during expand
- the alternate identifier could be kept within the EHR, there may be no need to have that in FHIR.
- POST to $expand could be used for translation of alternate id to expression
- the alternate identifier could be kept within the EHR, there may be no need to have that in FHIR.
3 Comments
Ulrich Andersen
Thank you for a brilliant solution -suggestion. The codesystem PATCH part will be challanging for many systems. Such extensions could also become a patchwork of content and a challenge for semantic interoperability between systems? A more terminology near solution could be to store expressions as Expression type reference set/Post coordination type reference set on a terminology server (Snowstorm). FHIR valuesets could be defined with ECL v 2.0 expressions, querying pre and postcoordinated meanings (predicates) - using memberfilters of the reference set.
Systems could reference the predicate be reusing the refset member id (UUID).
# valueset display Why use a semi machine readable display in stead of human readable -?
Kai Kewley
Hi Ulrich Andersen , thank you for sharing your thoughts on this.
Yes I agree that using PATCH on a code system containing a published edition is not desirable. The recommendation above uses a code system supplement which extends the published content to keep the expressions in a separate code system. That way expressions can be optionally included in query results by using either the published code system or the supplement containing the expressions (and the published content).
To ensure semantic interoperability between systems it is essential that the expression itself is sent, rather than any identifier that may only have local meaning. It will be up to the receiving system to interpret the expression or the generated display term sent with it.
Expressions should be classified before use in ECL and data analytics, so an expression refset could work but I think there would need to be at least two refsets. The first refset for expressions that users created and a second for the same expressions after classification (inferred parents and necessary-normal-form attributes). SNOMED International is working on a Postcoordination Practical Guide which includes some of these ideas (I didn't include them here because it's a FHIR oriented discussion). This is somewhat aligned with our thinking!
The suggestion that expression display terms should always be generated is to support the idea that the meaning of an expression must be limited to what is represented in its modelling. An expression is not a concept, so it should only be given a label that can be unambiguously derived from the modelling of the expression. Expressions should be taken literally. Expressions that use the same combination of concepts should be considered equivalent, they are the same thing. Using only generated display terms supports and enforces this understanding. This is in contrast to precoordination where thousands of concepts can have the same modelling and still be considered unique because they have a different identifier and term.
If human readable terms can be generated from expressions that would be awesome! Alternatively if humans are able to assign terms to expressions that exactly reflect the content of the expression, with no more and no less meaning, that would also work. To me the later seems less likely. Rough generated terms seem like a good compromise for now.
I very much look forward to seeing the Norwegian postcoordination presentation at the Expo and comparing thoughts in this new and interesting area!
Karol Harsaker
Thank you for sharing excellent ideas and questions on this page, about terminology implementation.
Just a short notice to mention that the suggestions that Ulrich is referring to will be presented by the Norwegian Directorate of e-health, at the SNOMED Expo 2022.