DSTU2 STU 3 Candidate
This page is part of the FHIR Specification (v1.0.2: DSTU 2). The current version which supercedes this version is

This page is part of the FHIR Specification (v1.4.0: STU 3 Ballot 3). The current version which supercedes this version is 5.0.0 . For a full list of available versions, see the Directory of published versions . For a full list of available versions, see the Directory of published versions . Page versions: . Page versions: R5 R4B R4 R3 R2

2.5.1 Terminology Service Terminology Service

This specification includes support for the provision of a terminology service - that is, a service that lets healthcare applications make use of codes and value sets without having to become experts in the fine details of the value set resource, and the underlying code systems. A server that supports all the functionality described here can be described as a "FHIR Terminology Service", and SHALL conform to this conformance statement .
FHIR Infrastructure FHIR Infrastructure Work Group Work Group Maturity Level : N/A Maturity Level : N/A Ballot Status : DSTU 2 Ballot Status : DSTU 2

This specification includes support for the provision of a terminology service - that is, a service that lets healthcare applications make use of codes and value sets without having to become experts in the fine details of the code system, value set and concept map resources, and the underlying code systems and terminological principles. A server that supports all the functionality described here can be described as a "FHIR Terminology Service", and SHALL conform to this conformance statement .

2.5.1.1 Security Security Generally, SSL SHOULD be used for all production health care data exchange. Even though terminology servers do not directly handle patient information, hackers may still be able to infer information about patients by observing the codes and concepts that the terminology service is asked about, so encryption is still recommended. A terminology server may choose not to authenticate the clients/users in any fashion, but can do so in order to limit or account for usage. For a value set maintenance server that allows terminologies to be edited, some form of authorization and/or authentication would be appropriate . This specification does not require any particular approach to security.

Generally, SSL SHOULD be used for all production health care data exchange. Even though terminology servers do not generally handle patient information directly, hackers may still be able to infer information about patients by observing the codes and concepts that the terminology service is asked about, so encryption is still recommended.

A terminology server may choose not to authenticate the clients/users in any fashion, but can do so in order to limit or account for usage. For a value set maintenance server that allows terminologies to be edited, some form of authorization and/or authentication would be appropriate . This specification does not require any particular approach to security.

2.5.1.2 Basic Concepts Basic Concepts A FHIR terminology service is simply a set of functions built on the definitions provided by a collection of

A FHIR terminology service is simply a set of functions built on the definitions provided by a collection of CodeSystem , ValueSet and and ConceptMap resources, with additional inherently known terminologies providing support. The terminology service builds on the basic principles for using terminologies in FHIR. Implementers should be familiar with: resources, with additional inherently known terminologies providing support.

The terminology service builds on the basic principles for using terminologies in FHIR. Implementers should be familiar with:

In addition, implementers should be familiar with the operations framework . Further useful information about terminologies may be found in:

2.5.1.2.1 External Code Systems External Code Systems In order to be used with a value set, code systems must be defined somewhere. They can be defined as part of an inline code system definition , or they can be defined elsewhere, and then used in a value set by quoting the correct namespace. The FHIR specification defines a set of namespaces for commonly encountered code systems, and defines how some work with FHIR (e.g. SNOMED CT ,

In order to be used with a value set, code systems and their content must be defined somewhere. They can be defined explicitly using the code system resource , or they can be defined elsewhere, and then used in a value set by quoting the correct system url. The FHIR specification defines a set of namespaces for commonly encountered code systems, and defines how some work with FHIR (e.g. SNOMED CT , LOINC , , RxNorm ). These code systems are often large, and have many internally defined properties that are part of their formal definitions. Inline code systems in Value Set resources are not an appropriate way to define these code systems; FHIR does not provide a formal representation at all. Instead, these terminologies provide their own distribution formats, and it is assumed that they are externally known to the terminology server. Most useful terminology servers will make one or more of these external code systems available for use within the value sets that they manage. The list of additional terminologies that a terminology server supports beyond those defined in its value sets is published to clients by (still to figure out how this works). A server SHOULD publish the additional code systems that it supports through intrinsic knowledge using the http://hl7.org/fhir/StructureDefinition/conformance-supported-system extension: ). These code systems are often large, and have many internally defined properties that are part of their formal definitions. The code systems resource is not an appropriate way to distribute the contents of these code systems; the standard FHIR code system resource simply represents the properties of the code system. Instead, these terminologies provide their own distribution formats, and it is assumed that the content of these code systems are externally known to the terminology server.

Most useful terminology servers will make one or more of these external code systems available for use within the value sets that they manage. The list of additional terminologies that a terminology server supports beyond those defined in its value sets is published to clients by referencing code system resources in the server's Conformance Statement .

{
 "resourceType" : "Conformance",
 "extension" : [
   { 
     "url" : "http://hl7.org/fhir/StructureDefinition/conformance-supported-system",
     "valueUri" : "http://loinc.org" 
   }]  
}
This
extension
is
added
to
the
root
Conformance
Statement
.

This extension is added to the root Conformance Statement .

2.5.1.2.2 Implementation Note Implementation Note When a terminology server exposes an external code system, it makes a set of services available internally that serve the operational interfaces below. The internal server depends on the following logical information for a terminology: its URL (namespace, and how versioning works) what codes are valid what properties can be used to select codes what implicit value sets exist The FHIR specification itself defines these things for common terminologies (including SNOMED CT ,

When a terminology server exposes an external code system, it makes a set of services available internally that serve the operational interfaces below. The internal server depends on the following logical information for a terminology:

  • its URL (namespace, and how versioning works)
  • what codes are valid
  • what properties can be used to select codes
  • what implicit value sets exist

The FHIR specification itself defines these things for common terminologies (including SNOMED CT , LOINC , , RxNorm ), and provides the ), and provides the ValueSet infrastructure for supporting typical relatively simple small code systems. Implementers Note: Implementers interested in working with existing published terminologies for which the Value Set infrastructure is not suitable should discuss their needs with HL7 to get the list above extended. Note: A terminology service may choose to expose additional external code system specific related functionality such as exploration, or structured search, but these services are outside the scope of the FHIR terminology service. infrastructure for supporting typical relatively simple small code systems.

Implementers Note: Implementers interested in working with existing published terminologies for which the Value Set infrastructure is not suitable should discuss their needs with HL7 to get the list above extended.

Note: A terminology service may choose to expose additional external code system specific related functionality such as summation, or structured search, but these services are outside the scope of the FHIR terminology service.

2.5.1.2.3 Operations across all value sets Operations across all value sets For some of the operations below, it can be useful to perform them across all value sets known to the system. For example, $expand using a text filter, and searching all value sets at once. A special value set is defined that means "all value sets known to the server":

For some of the operations below, it can be useful to perform them across all value sets known to the system. For example, $expand using a text filter, and searching all value sets at once. A special value set is defined that means "all value sets known to the server":

http://hl7.org/fhir/ValueSet/@all
Technically,
this
value
set
automatically
imports
all
the
existing
value
sets
on
the
server.
Note
that
this
URL
has
no
fixed
meaning
-
its
interpretation
is
server
specific.
This
URL
can
only
be
used
as
a
parameter
to
the
operations
described
on
this
page.

Technically, this value set automatically imports all the existing value sets on the server. Note that this URL has no fixed meaning - its interpretation is server specific. This URL can only be used as a parameter to the operations described on this page.

2.5.1.2.4 Terminology Maintenance Terminology Maintenance The terminology service uses the value set resources defined on the system - both the implicit ones associated with the external code systems and those explicitly available at the /ValueSet endpoint - to serve the operational interface defined below. As value sets are created, updated or deleted, the outcomes of the operational services change. A terminology server should validate incoming resources, and ensure integrity of the terminology services. Typically, servers would provide a test and production environment, but there is no explicit notion of this in the interface itself.

The terminology service uses the code systems and value set resources defined on the system - both the implicit ones associated with the external code systems and those explicitly available at the /CodeSystem and /ValueSet endpoints - to serve the operational interface defined below. As code systems and value sets are created, updated or deleted, the outcomes of the operational services change. A terminology server should validate incoming resources, and ensure integrity of the terminology services. Typically, servers provide a test and production environment, but there is no explicit notion of this in the interface itself.

2.5.1.3 Value Set Expansion Value Set Expansion A value set describes a set of rules for what codes or concepts are considered to be in the value set. These rules might be simple (e.g. a direct list of codes from a specified version of a code system), or they might be quite complex (e.g. all codes with a particular property from an unspecified version of a code system). A FHIR enabled application can simply ask the server to figure out all the details, and return it a list of the current codes in the value set. This is known as "expanding" the valueset . As a summary, the client passes the server the following information: the value set (either by its URL on the RESTful interface, by its logical identifier

A value set describes a set of rules for what codes or concepts are considered to be in the value set. These rules might be simple (e.g. a direct list of codes from a specified version of a code system), or they might be quite complex (e.g. all codes with a particular property from an unspecified version of a code system).

A FHIR enabled application can simply ask the server to figure out all the details, and return it a list of the current codes in the value set. This is known as "expanding" the valueset . As a summary, the client passes the server the following information:

The server returns a value set that contains the current list of codes that meet the filter criteria (or an OperationOutcome with an error if the expansion fails). Note that some value sets expand to many thousands of codes, or even an infinite number, and for these, the server SHOULD return an error code with an error if the expansion fails). Note that some value sets expand to many thousands of codes, or even an infinite number, and for these, the server SHOULD return an error code too-costly . In these cases the client can try again with a more specific text filter to reduce the number of codes returned. For further information, consult the definition of the operation . The $expand operation has support for paging - for a client to retrieve a big expansion in a set of partial views, in order to present the most optimal user experience. The client specifies both an offset and a count - how many codes per page, and where in the sequence to start. The return expansion specifies the number of concepts in the expansion, and the offset at which this partial view starts. Note that all expansions SHOULD include the total code count, but the offset element SHALL only exist when paging is being used. Expansions that are hierarchical trees of concepts are not subject to paging and the server simply returns the entire expansion. Some example uses for the expansion operation: get a list of codes to display in a User interface (e.g. a drop down interface) a variation on this is to offer the user a text box to type in. As the user types, call the expand operation to provide the user with a list of matching codes/concepts (like a browser search) fetch a list of codes to use when generating software programming instructions get a list of codes so that software can check whether a code is valid or not in a particular context . In these cases the client can try again with a more specific text filter to reduce the number of codes returned - this may result in a valid expansion.

For further information, consult the definition of the operation .

The $expand operation has support for paging - for a client to retrieve a big expansion in a set of partial views, in order to present the most optimal user experience. The client specifies both an offset and a count - how many codes per page, and where in the sequence to start. The return expansion specifies the number of concepts in the expansion, and the offset at which this partial view starts. Note that all expansions SHOULD include the total code count, but the offset element SHALL only exist when paging is being used. Expansions that are hierarchical trees of concepts are not subject to paging and the server simply returns the entire expansion.

Some example uses for the expansion operation:

  • get a list of codes to display in a User interface (e.g. a drop down interface)
  • a variation on this is to offer the user a text box to type in. As the user types, call the expand operation to provide the user with a list of matching codes/concepts (like a browser search)
  • fetch a list of codes to use when generating software programming instructions
  • get a list of codes so that software can check whether a code is valid or not in a particular context

Examples Expanding a value set that is already registered on the server as "23", with a text filter of "abdo":

Expanding a value set that is already registered on the server as "23", with a text filter of "abdo":

GET [base]/ValueSet/23/$expand?filter=abdo
Expanding
a
value
set
that
is
specififed
by
the
client
(using
JSON):


Expanding a value set that is specififed by the client (using JSON):

POST [base]/ValueSet/23/$expand
[other headers]

{
  "resourceType" : "Parameters",
  "parameter" : [
     {
     "name" : "valueSet",
     "resource" : {
       "resourceType" : "ValueSet",
     [value set details]
     }
   }
  ]
}
The
server
responds
with
a
value
set
(this
example
in
XML):


The server responds with a value set (this example in XML):

HTTP/1.1 200 OK
[other headers]

<ValueSet xmlns="http://hl7.org/fhir">
  <!-- the server SHOULD populate the id with a newly created UUID
    so clients can easily track a particular expansion  -->
  <id value="43770626-f685-4ba8-8d66-fb63e674c467"/>
  <!-- no need for meta, though it is allowed for security labels, profiles -->

  <!-- other value set details -->
  <expansion>
    <!-- when expanded -->
    <timestamp value="20141203T08:50:00+11:00"/>
  <contains>
    <!-- expansion contents -->
  </contains>
  </expansion>
</ValueSet>

2.5.1.4 Concept Lookup Concept Lookup A system can ask a terminology server to return a set of information about a particular system/code combination using the lookup operation . The server returns information for both display and processing purposes. The client passes the server the following information: the code value (either a code + system, or a Coding data type) (Optionally) a date at which the code information should be returned (usually, this is the current date/time, but there are circumstances where that is not appropriate) The server returns the following information: a human description of the system a recommended display for the code whether the code is abstract or not other designations for the code (a value, optionally with language and/or a use code) The recommended display for the code is a text representation of the code that the terminology server recommends as the default choice to show to the user, though a client may choose out of the other designations if it has reason to.

A system can ask a terminology server to return a set of information about a particular system/code combination using the lookup operation . The server returns information for both display and processing purposes. The client passes the server the following information:

  • the code value (either a code, or a Coding data type)
  • (Optionally) the id or the url of the code system in which the code is being checked
  • (Optionally) a date at which the code information should be returned (usually, this is the current date/time, but there are circumstances where that is not appropriate)
  • (Optionally) a set of properties to return about the code

The server returns some or all of the following information:

  • a human description of the system
  • a recommended display for the code
  • properties of the code
  • other designations for the code (a value, optionally with language and/or a use code)
  • relationships between this code and other codes

The recommended display for the code is a text representation of the code that the terminology server recommends as the default choice to show to the user, though a client may choose out of the other designations if it has reason to.

If the client does not ask for any particular properties to be returned, it is at the discretion of the server to decide which properties to return.

Examples Looking up a code/system: GET [base]/ValueSet/$lookup?system=http://loinc.org&code=1963-8 Lookup using a Coding (this example in XML): POST [base]/ValueSet/$lookup

Looking up a code in a code system:

GET [base]/CodeSystem/loinc/$lookup?code=1963-8

Note that the logical id "loinc" is not a reliable identifer across systems; each server assigns logical ids to code system resources however it sees fit. A more reliable query is this:


GET [base]/CodeSystem/$lookup?url=http://loinc.org&code=1963-8&properties=code,display,designations

Lookup the code system using a Coding (this example in XML):


POST [base]/CodeSystem/$lookup

[other headers]

<Parameters xmlns="http://hl7.org/fhir">
  <parameter>
    <name value="coding"/>
  <valueCoding>
    <system value="http://loinc.org"/>
    <code value="1963-8"/>
  </valueCoding>

    <valueCoding>
      <system value="http://loinc.org"/>
      <code value="1963-8"/>
    </valueCoding>

  </parameter>
</Parameters>
The
server
responds
with
a
set
of
information
(JSON
this
time):


The server responds with a set of information (JSON this time):

HTTP/1.1 200 OK
[other headers]

{
  "resourceType" : "Parameters",
  "parameter" : [
    {
    "name" : "name",
    "valueString" : "LOINC"
  },
  {
    "name" : "version",
    "valueString" : "2.48"
  },
  {
    "name" : "designation",

    "name" : "display",

    "valueString" : "Bicarbonate [Moles/volume] in Serum"
  },
  {
    "name" : "abstract",
    "valueString" : "false"
  },
  {
      "name" : "designation",
    "part" : [
    {
      "name" : "value",
      "valueString" : "Bicarbonate [Moles/volume] in Serum "
    }
    ]

  }
  ]
}

Thie following properties are defined:

Name Usage
system The name of the code ssystem
version The version of the code system used for the look up operation
display The recommended display for the code, if one is known
definition The definition for the code
designation Other designations for the code
parent Parent codes for this code (for code systems with a defined heirarchy)
child child codes of this code (for code systems with a defined heirarchy)

In addition, any property codes defined by the code system (CodeSysem.property.code) can be used.

2.5.1.5 Value Set Validation Value Set Validation One of the ways to determine whether a code is in a value set is to expand the value set (as described above), and then look at the returned codes to see if the code is in the expansion. However this is not an efficient way to test whether a code is valid, and for some value sets (e.g. with infinite number of members), it cannot work. Instead, a FHIR terminology server provides a "validate-code" operation . The client passes the server the following information: the value set (either by its URL on the RESTful interface, by its logical identifier

One way to determine whether a code is in a value set is to expand the value set (as described above), and then look at the returned codes to see if the code is in the expansion. However this is not an efficient way to test whether a code is valid, and for some value sets (e.g. with infinite number of members), it cannot work. Instead, a FHIR terminology server provides a "validate-code" operation . The client passes the server the following information:

The server returns a true/false indicating whether the code/concept is valid, and a list of errors and warnings associated with it. The server should also return an appropriate display for the concept for use in a UI context.

Note that if the server is passed a CodeableConcept, the server is able to check whether any of the codes are valid against the value set, and also check whether multiple codings are allowed and/or the codings provided are consistent with each other.

Every code system has an implicit value set that is "all the concepts defined in the code system" (CodeSystem.valueSet). For some code systems, these value set URIs are defined in advance (e.g. for LOINC , it is , it is http://loinc.org/vs ). However for some code systems, they are not known. Clients can refer to these implicit value sets by providing the URI for the code system itself. ). However for some code systems, they are not known. Clients can refer to these implicit value sets by providing the URI for the code system itself.

Examples Simple validation of a code/system against a known value set:

Simple validation of a code/system against a known value set:

GET [base]/ValueSet/23/$validate-code?system=http://loinc.org&code=1963-8&display=test
Validate
a
CodeableConcept
against
a
client
specified
value
set
(this
example
in
JSON):


Validate a CodeableConcept against a client specified value set (this example in JSON):

POST [base]/ValueSet/$validate-code
[other headers]

{
  "ResourceType" : "Parameters",
  "parameter" : [
    {
    "name" : "coding",
    "valueCodeableConcept" : {
      "coding" : {
        "system" : "http://loinc.org",
          "code" : "1963-8",
      "display" : "test"
      }
    }
  },
  {
    "name" : "valueSet",
    "resource": {
      "resourceType" : "ValueSet",
    [etc]
    }
  }
  ]
}
The
server
responds
with
validation
information
(JSON
this
time):


The server responds with validation information (JSON this time):

HTTP/1.1 200 OK
[other headers]

{
  "resourceType" : "Parameters",
  "parameter" : [
    {
    "name" : "result",
    "valueBoolean" : "false"
  },
  {
    "name" : "message",
    "valueString" : "The display \"test\" is incorrect"
  },
  {
    "name" : "display",
    "valueString" : "Bicarbonate [Moles/volume] in Serum"
  }
  ]
}

2.5.1.6 Subsumption testing Subsumption testing The Expand and Validate operations can be used to perform subsumption testing. To test whether code A subsumes code B , perform a validate specifying a value set built of all the codes that are subsumed by code A , and test whether code B is subsumed by it. Note that a server is allowed to (and SHOULD, but is not required to) consider concept maps when doing subsumption testing. For example if A is a LOINC code, and it has a precise mapping to a SNOMED CT code that subsumes B, with an appropriate scope, then the server can indicate that this it is true that LOINC code A subsumes SNOMED CT code B. In order to make it convenient to perform this subsumption testing, code systems that define subsumption hierarchies should define simple URLs to express a value set that includes all the codes subsumed by a code.

The Expand and Validate operations can be used to perform subsumption testing. To test whether code A subsumes code B , perform a validate specifying a value set built of all the codes that are subsumed by code A , and test whether code B is subsumed by it. Note that a server is allowed to (and SHOULD, but is not required to) consider concept maps when doing subsumption testing. For example if A is a LOINC code, and it has a precise mapping to a SNOMED CT code that subsumes B, with an appropriate scope, then the server can indicate that this it is true that LOINC code A subsumes SNOMED CT code B.

In order to make it convenient to perform this subsumption testing, code systems that define subsumption hierarchies should define simple URLs to express a value set that includes all the codes subsumed by a code.

Examples Test whether a SNOMED CT Concept 399211009 (History of myocardial infarction) is subsumed by 22298006 (Myocardial infarction):

Test whether a SNOMED CT Concept 399211009 (History of myocardial infarction) is subsumed by 22298006 (Myocardial infarction):

GET [base]/ValueSet/$validate-code?system=http://snomed.info/sct&code=399211009&identifier=http://snomed.info/sct?fhir_vs%3Disa/22298006
Server
response:


Server response:

HTTP/1.1 200 OK
[other headers]

{
  "resourceType" : "Parameters",
  "parameter" : [
    {
    "name" : "result",
    "valueBoolean" : "false"
  },
  ]
}

2.5.1.7 Batch Validation Batch Validation It is also possible to validate a set of concepts against their relevant value sets by using the

It is also possible to validate a set of concepts against their relevant value sets by using the $validate-code operation in a operation in a Batch interaction. interaction.

Example A request to validate 2 concepts from a CDA

A request to validate 2 concepts from a CDA document, with OIDs for value set identifiers: document, with OIDs for value set identifiers:

POST [base]
[other headers]

{
  "ResourceType": "Bundle",
  "type": "batch",
  "entry": [{
    "request": {
      "method": "Get",
      "url": "ValueSet?system=http://loinc.org&code=2324-4&uri=urn:oid:1.2.3.4.6"
    }
  },
  {
    "request": {
      "method": "GET",
      "url": "ValueSet?system=http://snomed.info/sct&codes=22298006&uri=urn:oid:1.2.3.4.7"
    }
  }]
}
The
server
responds
with
a
series
of
validation
outcomes
(JSON
this
time):


The server responds with a series of validation outcomes (JSON this time):

HTTP/1.1 200 OK
[other headers]

{
  "ResourceType": "Bundle",
  "type": "batch-response",
  "entry": [{
    "resource": {
      "resourceType": "Parameters",
      "parameter": [{
        "name": "result",
        "valueBoolean": "false"
      },
      {
        "name": "message",
        "valueString": "'2324-4' is not a valid LOINC code"
      }]
    }
  },
  {
    "resource": {
      "resourceType": "Parameters",
      "parameter": [{
        "name": "result",
        "valueBoolean": "false"
      },
      {
        "name": "message",
        "valueString": "The concept is not in the specified value set (\"Organisms\")"
      },
      {
        "name": "display",
        "valueString": "Myocardial infarction"
      }]
    }]
  }

2.5.1.8 Translations Translations A client can ask a server to translate a concept from one value set to another. Typically, this is used to translate between code systems (e.g. from LOINC to SNOMED CT, or from a HL7 V3

A client can ask a server to translate a concept from one value set to another. Typically, this is used to translate between code systems (e.g. from LOINC to SNOMED CT, or from a HL7 V3 code to a HL7 V2 code to a HL7 V2 code). The client calls the translate operation and passes the following parameters: a code + system, Coding, or CodeableConcept a Concept Map to use for the translation the value set for the context of the source the value set for the destination The client passes either a concept map, or the value sets for the source and destination context. If there is no concept map, then the server may determine the appropriate map to use from context provided in the value sets. If there is no particular context, the appropriate value sets would be the value sets for the entire coding system at question (e.g. from http://snomed.info/sct to http://loinc.org/vs). The server performs the translation as it is able based on the concept maps that it knows about. If no single mapping can be determined then the server returns an error. Some servers may require a concept map to use for the translation. code). The client calls the translate operation and passes the following parameters:

  • a code + system, Coding, or CodeableConcept
  • a Concept Map to use for the translation
  • the value set for the context of the source
  • the value set for the destination

The client passes either a concept map, or the value sets for the source and destination context. If there is no concept map, then the server may determine the appropriate map to use from context provided in the value sets. If there is no particular context, the appropriate value sets would be the value sets for the entire coding system at question (e.g. from http://snomed.info/sct to http://loinc.org/vs). The server performs the translation as it is able based on the concept maps that it knows about. If no single mapping can be determined then the server returns an error. Some servers may require a concept map to use for the translation.

Example Translate from FHIR Composition status to HL7 v3

Translate from FHIR Composition status to HL7 v3 Act Status (based on this defined concept map : Act Status (based on this defined concept map :

GET [base]/ConceptMap/$translate?system=http://hl7.org/fhir/composition-status
  &code=preliminary&valueSet= http://hl7.org/fhir/ValueSet/composition-status
  &target=http://hl7.org/fhir/ValueSet/v3-ActStatus
The
server
responds
with
validation
information:


The server responds with validation information:

HTTP/1.1 200 OK
[other headers]

{
  "resourceType" : "Parameters",
  "parameter" : [
    {
    "name" : "result",
    "valueBoolean" : "true"
    },
    {
      "name" : "outcome",
      "valueCoding" : {
        "system" : "http://hl7.org/fhir/v3/ActStatus",
        "code" : "active",
      }
    }
  ]
}

2.5.1.9 Batch Translation Batch Translation It is also possible to validate a set of concepts against their relevant value sets by using the

It is also possible to validate a set of concepts against their relevant value sets by using the $translate operation in a operation in a Batch interaction. interaction.

Example A request to translate 2 concepts from a CDA

A request to translate 2 concepts from a CDA document, with OIDs for value set identifiers: document, with OIDs for value set identifiers:

POST [base]
[other headers]

{
  "ResourceType": "Bundle",
  "type": "batch",
  "entry": [{
    "resource": {
      "ResourceType": "Parameters",
      "parameter": [{
        "name": "concept",
        "valueCodeableConcept": {
          "system": "http://loinc.org",
          "code": "2324-4"
        }
      },
      {
        "name": "target",
        "valueUri": "urn:oid:1.2.3.4.6"
      }]
    },
    "request": {
      "method": "POST",
      "url": "ConceptMap/$translate"
    }
  },
  {
    "resource": {
      "ResourceType": "Parameters",
      "parameter": [{
        "name": "concept",
        "valueCodeableConcept": {
          "system": "http://snomed.info/sct",
          "code": "22298006"
        }
      },
      {
        "name": "target",
        "valueUri": "urn:oid:1.2.3.4.7"
      }]
    },
    {
      "request": {
        "method": "POST",
        "url": "ConceptMap/$translate"
      }
    }]
  }
The
server
responds
with
a
series
of
translation
outcomes:


The server responds with a series of translation outcomes:

HTTP/1.1 200 OK
[other headers]

{
  "ResourceType": "Bundle",
  "type": "batch-response",
  "entry": [{
    "resource": {
      "resourceType": "Parameters",
      "parameter": [{
        "name": "result",
        "valueBoolean": "false"
      },
      {
        "name": "message",
        "valueString": "'2324-4' is not a valid LOINC code"
      }]
    }
  },
  {
    "resource": {
      "resourceType": "Parameters",
      "parameter": [{
        "name": "result",
        "valueBoolean": "false"
      },
      {
        "name": "outcome",
        "valueCodeableConcept": {
          "coding": {
            "system": "http://example.com/codesystems/example",
            "code": "xxxx"
          }
        }
      }]
    }
  }]
}

2.5.1.10 Maintaining a Closure Table Maintaining a Closure Table The 4 operations Expand, Lookup, Validate, and Translate account for most operational requirements associated with terminology use. However there is one difficult but important use case that they do not address, which is integrating terminologically based logic into application searches. A typical example of this is a user that wants to find any observations for male patients over the age of 50 who attended a particular clinic within a particular 2 week period, with a diagnosis of gout, and who had an elevated serum creatinine. In this case, both "diagnosis of gout" and "serum creatinine" involve value set and/or subsumption queries (e.g. against SNOMED CT and LOINC respectively). This search has to be executed by some logical processing engine that knows how to find this data in a given persistence store. Often, this is some kind of SQL query, though many other technological choices are available. However this is done, the challenge with an operation like this is to integrate the terminological knowledge into a search execution that also covers other relationships expressed in the search criteria. One approach to this problem would be to using the expand operation above, so that the system executing the search could generate expansions, and then search for these expansions. This has a couple of problems: the list of subsumed codes could be very long, and the search operation becomes correspondingly inefficient the expansion of the subsumption might not be closed, and so the search operation cannot be correct An alternative approach is to generate a subsumption closure table

The 4 operations Expand, Lookup, Validate, and Translate account for most operational requirements associated with terminology use. However there is one difficult but important use case that they do not address, which is integrating terminologically based logic into application searches.

A typical example of this is a user that wants to find any observations for male patients over the age of 50 who attended a particular clinic within a particular 2 week period, with a diagnosis of gout, and who had an elevated serum creatinine.

In this case, both "diagnosis of gout" and "serum creatinine" involve value set and/or subsumption queries (e.g. against SNOMED CT and LOINC respectively). This search has to be executed by some logical processing engine that knows how to find this data in a given persistence store. Often, this is some kind of SQL query, though many other technological choices are available. However this is done, the challenge with an operation like this is to integrate the terminological knowledge into a search execution that also covers other relationships expressed in the search criteria.

One approach to this problem would be to using the expand operation above, so that the system executing the search could generate expansions, and then search for these expansions. This has a couple of problems:

  • the list of subsumed codes could be very long, and the search operation becomes correspondingly inefficient
  • the expansion of the subsumption might not be closed, and so the search operation cannot be correct

An alternative approach is to generate a subsumption closure table , which lists all the possible relationships, and allows for rapid execution of these kind of queries. However this has other problems: the subsumption table can be very large (>500000 records for SNOMED CT), even though very few of the codes are used subsumption tables are generally built up front, and do not deal with new codes as they are encountered very well they still do not offer a solution for non-closed expansions This is the main reason why most systems do not support post-coordination or other forms of coded expressions. In FHIR, this problem is solved by building a closure table on the fly as new codes are seen. This technique leaves the FHIR terminology server responsible for the terminological reasoning, and the client responsible for the closure table maintenance. To the client, it doesn't matter whether the concept is post-coordinated or not. Here's a description of how the process works: the client defines a name associated with a particular context in which it wishes to maintain a subsumption based closure table the client registers this name with the FHIR Terminology server using the $closure operation (described below), with only one parameter, the name of the context any time the client system encounters a new Coding that is not entered in the closure table, it calls the $closure operation with the context name, and the Coding value it has encountered the server returns a ConceptMap resource with a list of new entries (code : system -> code : system) that the client should add to its closure table the server can indicate that entries should be removed from the table by providing a (code : system -> code : system) with equivalence "unmatched" (though it's not known why that would be needed) the client makes these entries into its closure table to facilitate the initialization process, a client can call $closure with multiple Coding values The $closure operation takes 2 parameters: closure table context name concepts to enter into the table (0 or more - 0 codings is a request to (re-)initialise the table) The operation returns a concept map which has a list of mappings that represent new entries to make in the closure table. The closure table can be resynchronized by passing an additional "version" parameter, which is a value taken from the version in one of the delta responses. This is a request to replay all the mapping changes since that delta was sent. , which lists all the possible relationships, and allows for rapid execution of these kind of queries. However this has other problems:

  • the subsumption table can be very large (>500000 records for SNOMED CT), even though very few of the codes are used
  • subsumption tables are generally built up front, and do not deal with new codes as they are encountered very well
  • they still do not offer a solution for non-closed expansions

This is the main reason why most systems do not support post-coordination or other forms of coded expressions.

In FHIR, this problem is solved by building a closure table on the fly as new codes are seen. This technique leaves the FHIR terminology server responsible for the terminological reasoning, and the client responsible for the closure table maintenance. To the client, it doesn't matter whether the concept is post-coordinated or not. Here's a description of how the process works:

  1. the client defines a name associated with a particular context in which it wishes to maintain a subsumption based closure table
  2. the client registers this name with the FHIR Terminology server using the $closure operation (described below), with only one parameter, the name of the context
  3. any time the client system encounters a new Coding that is not entered in the closure table, it calls the $closure operation with the context name, and the Coding value it has encountered
  4. the server returns a ConceptMap resource with a list of new entries (code : system -> code : system) that the client should add to its closure table
    • the server can indicate that entries should be removed from the table by providing a (code : system -> code : system) with equivalence "unmatched" (though it's not known why that would be needed)
  5. the client makes these entries into its closure table
  6. to facilitate the initialization process, a client can call $closure with multiple Coding values

The $closure operation takes 2 parameters:

  • closure table context name
  • concepts to enter into the table (0 or more - 0 codings is a request to (re-)initialise the table)

The operation returns a concept map which has a list of mappings that represent new entries to make in the closure table.

The closure table can be resynchronized by passing an additional "version" parameter, which is a value taken from the version in one of the delta responses. This is a request to replay all the mapping changes since that delta was sent.

Example The client sees a new SNOMED CT concept "22298006" in a data element it is tracking as "patient-problems":

The client sees a new SNOMED CT concept "22298006" in a data element it is tracking as "patient-problems":

POST [base]/$closure

{
  "resourceType" : "Parameters",
  "parameter" : [
    {
      "name" : "name",
      "valueId : "patient-problems"

      "valueString" : "patient-problems"

    },
    {
      "name" : "concept",
      "valueCoding" : {
        "system" : "http://snomed.info/sct",
        "code" : "22298006",
      }
    }
  ]
}

The
server
responds
with
a
set
of
new
entries
to
add
to
the
concept
map.
It
provides
one
important
piece
of
metadata
-
the
version,
which
the
client
can
use
to
resynchronize
the
closure
table:


The server responds with a set of new entries to add to the concept map. It provides one important piece of metadata - the version, which the client can use to resynchronize the closure table:

HTTP/1.1 200 OK
[other headers]

{
  "resourceType": "ConceptMap",
  "identifier": "49088976-d54d-4d19-b868-3d4c18cebabb",
  "version": "8",
  "status": "active",
  "experimental": true,
  "date": "2012-06-13",
  "element": [
    {
      "codeSystem": "http://snomed.info/sct",
      "code": "22298006",
      "map": [
        {
          "codeSystem": "http://snomed.info/sct",
          "code": "128599005",
          "equivalence": "wider"
        }
      ]
    },
  ]
}
Notes:
In
this
simple
example,
the
addition
of
a
single
new
SNOMED
CT
concept
created
one
existing
subsumption
relationship.
In
general
clinical
use,
more
than
one
relationship
would
be
expected
For
the
purposes
of
the
closure
table,
the
relationships
are
considered
to
be
bi-directional;
e.g.
if
A
subsumes
B,
then
B
is
subsumed
by
A
As
well
as
entering
codes
that
are
actually
used,
the
client
also
enters
search
terms
into
the
closure
table
The
combination
of
the
system
and
code
is
the
key
to
the
closure
table;
if
the
server
encounters
two
different
codes
that
have
the
same
meaning
(e.g.
syntactical
variation),
it
should
create
an
"equals"
relationship
between
them
The
client
uses
the
result
of
the
closure
operation
to
maintain
a
closure
table.
Simplistically,
it
might
look
like
this:

Notes:

  • In this simple example, the addition of a single new SNOMED CT concept created one existing subsumption relationship. In general clinical use, more than one relationship would be expected
  • For the purposes of the closure table, the relationships are considered to be bi-directional; e.g. if A subsumes B, then B is subsumed by A
  • As well as entering codes that are actually used, the client also enters search terms into the closure table
  • The combination of the system and code is the key to the closure table; if the server encounters two different codes that have the same meaning (e.g. syntactical variation), it should create an "equals" relationship between them

The client uses the result of the closure operation to maintain a closure table. Simplistically, it might look like this:

Scope Source Target
patient-problems http://snomed.info/sct|22298006 http://snomed.info/sct|128599005
patient-problems http://snomed.info/sct|24595009 http://snomed.info/sct|90560007
obs-code http://loinc.org|14682-9 http://loinc.org|LP41281-4 The client can then use a table like this as part of its general search conditions. Using the example from above: "Find any observations for male patients over the age of 50 who attended a particular clinic within a particular 2 week period, with a diagnosis of gout, and who had an elevated serum creatinine." This query could be done, for instance, with an SQL query like this:

The client can then use a table like this as part of its general search conditions. Using the example from above: "Find any observations for male patients over the age of 50 who attended a particular clinic within a particular 2 week period, with a diagnosis of gout, and who had an elevated serum creatinine." This query could be done, for instance, with an SQL query like this:

 Select * from Observations, Patients, Encounters, Conditions, Observations as Obs2 where
   Observations.patient = Patients.Key and Patients.Age > 50 and 
   Observations.encounter = Encounters.Key and Encounter.clinic = [key] 
     and encounter.date >= [date] and encounter.date <= [date] and
   Conditions.patient = Patients.Key and Conditions.code 
     in (select Source From ClosureTable 
       where Scope = "patient-problems" and Target = "http://snomed.info/sct|90560007") and
   Obs2.patient = Patients.Key and Obs2.value > 0.19 and Obs2.code 
     in (select Source From ClosureTable 
       where Scope = "obs-code" and Target = "http://loinc.org|LP41281-4")
Note
that
in
real
clinical
systems,
tables
are
usually
far
more
structured
than
this
example
implies,
and
the
query
is
correspondingly
more
complex.
The
closure
table
would
usually
be
normalised
-
this
example
is
kept
simple
to
demonstrate
the
concept.

Note that in real clinical systems, tables are usually far more structured than this example implies, and the query is correspondingly more complex. The closure table would usually be normalised - this example is kept simple to demonstrate the concept.

2.5.1.11 Functional Operations Functional Operations In order to support terminology operations in FHIR a minimal set of terminology operations would be necessary. These operations are a sub set of the available terminology service operations defined in the [http://www.omg.org/spec/CTS2/1.0/ Common Terminology Services - Release 2 (CTS2) specification] and can be categorized as: Administrative Operations Search/Query Operations Authoring/Maintenance Operations Functional operations within these categories support the access and management of terminology objects such as Code Systems, Concepts, Value Sets and Concept Mappings. The functional operations necessary to support a FHIR terminology service are outlined here.

In order to support terminology operations in FHIR a minimal set of terminology operations would be necessary. These operations are a sub set of the available terminology service operations defined in the [http://www.omg.org/spec/CTS2/1.0/ Common Terminology Services - Release 2 (CTS2) specification] and can be categorized as:

  • Administrative Operations
  • Search/Query Operations
  • Authoring/Maintenance Operations

Functional operations within these categories support the access and management of terminology objects such as Code Systems, Concepts, Value Sets and Concept Mappings. The functional operations necessary to support a FHIR terminology service are outlined here.

2.5.1.11.1 Administrative Operations Administrative Operations be able to load a standard or local code system

  • be able to load a standard or local code system

2.5.1.11.2 Search/Query Operations Search/Query Operations Concepts retrieve the concept details (display name, qualifiers, associations, etc.) for a given code/code system return possible concept matches based on search criteria validate whether a code is valid within a given code system (content) retrieve a list of codes (for example, to populate a user interface) return the decedents of a given concept Code System retrieve the metadata for a code system Value Set retrieve the metadata for a value set return a value set based on search criteria determine if a code is valid in a value set generate the Value set Expansion from the Value Set Definition. Mapping retrieve the metadata for map set retrieve a translation (mapping) of concept(s) from a given source code system to target concept(s) from a target code system

Concepts

  • retrieve the concept details (display name, qualifiers, associations, etc.) for a given code/code system
  • return possible concept matches based on search criteria
  • validate whether a code is valid within a given code system (content)
  • retrieve a list of codes (for example, to populate a user interface)
  • return the decedents of a given concept

Code System

  • retrieve the metadata for a code system

Value Set

  • retrieve the metadata for a value set
  • return a value set based on search criteria
  • determine if a code is valid in a value set
  • generate the Value set Expansion from the Value Set Definition.

Mapping

  • retrieve the metadata for map set
  • retrieve a translation (mapping) of concept(s) from a given source code system to target concept(s) from a target code system

2.5.1.11.3 Authoring/Maintenance Operations Authoring/Maintenance Operations

Concepts maintain a closure table Value Set create/editing a value set Mapping translate (map) from a source code system to a target code system © HL7.org 2011+. FHIR DSTU2 (v1.0.2-7202) generated on Sat, Oct 24, 2015 07:44+1100. Links: Search

  • maintain a closure table

Value Set

  • create/editing a value set

Mapping

  • translate (map) from a source code system to a target code system