Skip to content

Instantly share code, notes, and snippets.

@lawley
Last active February 28, 2021 08:42
Show Gist options
  • Save lawley/3a59cf669d29a6d62e2948bc51e101a3 to your computer and use it in GitHub Desktop.
Save lawley/3a59cf669d29a6d62e2948bc51e101a3 to your computer and use it in GitHub Desktop.
ConceptMap reforms for R5

ConceptMap moving from R4 to R5

ConceptMap Resource

As of FHIR R4, ConceptMap is still a relatively immature resource. Some evidence of this is in the current state of the proposed R5 changes that:

  1. refine the set of valid relationship codes,
  2. explicitly broaden its scope beyond equivalence relationships, and
  3. re-structure handling of noMap.

There is more to be done, however, and given the extent and breaking-nature of the currently proposed changes, now is the opportune time to clean things up. Accordingly, this document brings together a number of related tracker items pertaining to clarity and consistency.

A close inspection of the current R5 proposal shows modelling choices that reflect the early state of FHIR and that have not caught up with recent improvements to FHIR's core modelling capabilities and approaches.

Specifcially, this includes the introduction of canonical, and the more prevalent use of choice types.

Additionally, there certain properties have names that lead to confusion for both implementers and consumers. In particular, the use of source and target to refer to either a CodeSystem or a ValueSet in different places.

There are also outstanding gaps with respect to semantics and the associated bahviour of $translate. Many of these (e.g., the handling of dependsOn and product when reverse=true is specified) are not dealt with here.

1. Confusion with source and target

See https://jira.hl7.org/browse/FHIR-31386 and https://confluence.hl7.org/pages/viewpage.action?pageId=35718826#GuidetoDesigningResources-NamingRules&Guidelines

ConceptMap.source[x] and ConceptMap.target[x] are used to indicate the "source value set that contains the concepts that are being mapped" and "target value set which provides context for the mappings". These correspond to the notions of Domain and Codomain (not Range, since that is the set of actual target codes in the map). Furthermore, there is no good reason to support both uri and canonical as types in this context.

Proposal: Replace ConceptMap.source[x] and ConceptMap.target[x] with ConceptMap.inputScope and ConceptMap.outputScope respectively.

Note, we have selected inputScope and outputScope over the terms domain and codomain since the latter, while technically accurate, are not widely recognized and understood beyond academic circles.

2. Use canonical types where relevant rather than separate version properties

See https://jira.hl7.org/browse/FHIR-25925

Proposal: ConceptMap.group.source and ConceptMap.group.target have companion properties ConceptMap.group.sourceVersion and ConceptMap.group.targetVersion. These should be replaced by ConceptMap.group.source and ConceptMap.group.target with the type canonical(CodeSystem).

3. Use explicit choice type with the dependsOn (and product) elements

See https://jira.hl7.org/browse/FHIR-28284

The value of ConceptMap.group.element.target.dependsOn.value can be the "Identity (code or path) or the element/item/ValueSet/text". However, there is nothing other than (implicit) knowledge about the ConceptMap.group.element.target.dependsOn.property that disambiguates the type. Furthermore, for the product use-case, the $translate operation can only surface Codings.

Proposal: Use a choice type for the value in dependsOn and product. This would replace:

dependsOn: {
  property: uri,
  system: canonical(CodeSystem),
  value: string,
  display: string
}

with:

dependsOn: {
  property: uri,
  value[x]: (code | Coding | string | integer | boolean | dateTime | decimal | uri),
}

Note, this proposal has explicitly omitted two options:

  1. canonical(ValueSet), and
  2. path

since it is not clear from the current specification what the meaning of these values should be.

4. Missing information in the unmapped element

See https://jira.hl7.org/browse/FHIR-22129

The unmapped element has no current mechanism to specifiy a value for the mapping relationship in the cases where mode is fixed or provided.

Proposal:

  1. Add optional property relationship: code with required binding to ConceptMapRelationship.
  2. Add/updates constraint(s) equivalent to capture: (mode != 'other-map') implies relationship.exists()

5. $translate align parameters with ConceptMap property changes

See https://jira.hl7.org/browse/FHIR-31386 and https://confluence.hl7.org/pages/viewpage.action?pageId=35718826#GuidetoDesigningResources-NamingRules&Guidelines

Proposal: Change source and target to inputScope and outputScope to match ConceptMap.inputScope and ConceptMap.outputScope.

6. $translate dependsOn values

See https://jira.hl7.org/browse/FHIR-28284

The parameter dependency.concept does not allow for values that are not code-typed such as string, integer, boolean, etc.

Proposal: Replace dependency.concept with dependency.value[x] where [x] is aligned with change #3 above.

7. $translate parameter naming consistency

See https://jira.hl7.org/browse/FHIR-31386 and https://confluence.hl7.org/pages/viewpage.action?pageId=35718826#GuidetoDesigningResources-NamingRules&Guidelines

targetsystem does not conform to naming guidelines (lowerCamelCase).

Proposal: Replace targetsystem with targetSystem.

8. $translate OUT parameters

See https://jira.hl7.org/browse/FHIR-30515

match.product.concept has the same problem as dependency.concept

Proposal: Replace match.product.concept with match.product.value[x] where [x] is aligned with change #5 above.

There is no clear way to inform the client of any relevant dependsOn conditions in a map when, for example, the corresponding dependency.* paramaters have not been supplied.

Proposal: Add optional match.dependsOn.* to the OUT parameters aligned with change #5 above.

9. Overloading of source (again)

See https://jira.hl7.org/browse/FHIR-28577

match.source refers to a ConceptMap, not a CodeSystem or ValueSet - see #1 above.

Proposal: Change from match.source to match.conceptMap (or match.origin?) of type canonical(ConceptMap).

10. reverse=true "...reverses the meaning..."

match.concept may be the target Coding (deafult case and when reverse=false) or the source Coding (when reverse=true).

Proposal: rename to match.targetCoding and introduce match.sourceCoding so that the pair is always present in the result and it is not necessary to be aware of the calling parameters to interpret the result.

The current definition of the reverse parameter says:

if this is true, then the operation should return all the codes that might be mapped to this code. This parameter reverses the meaning of the source and target parameters

It is not clear what is intended by the second sentence.

Proposal: re-word the documentation as follows:

if this is true, then the operation should return all the codes that are mapped to this code. In this case, the input code or coding(s) must belong to the outputScope ValueSet rather than the inputScope ValueSet. Furthermore, any provided dependency parameters are matched against ConceptMap.group.element.target.product rather than ConceptMap.group.element.target.dependsOn.

@johngrimes
Copy link

Why do you need uri | canonical(CodeSystem) in 2?

Isn't a canonical a URI with an optional version?

@lawley
Copy link
Author

lawley commented Feb 3, 2021

That was really just replicating the existing type options. Agreed it looks like uri is redundant and just canonical(CodeSystem) would be sufficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment