Skip to content

OMOP terminology discussion

Reuben Daniels edited this page Jul 6, 2023 · 3 revisions

OMOP terminology

From TI minutes:

  • OMOP record "cases" defined & example OMOP records can be found here
  • Davera provided an overview as Discussed in New Orleans
  • OMOP brings in external vcabularies and "recasts" them Link to PP presentation in minutes (above)
  • Seeking to provide guidance to the community
  • A way to approach this may be code system supplements to pass both the source and OMOP concept id?
  • Grahame - seems like a concept id per domain - not a single concept id
  • From Michael Lawley to Grahame - the idea of only one concept id for an item per domain was aspirational - but this is historical and is being cleaned up
  • List of concept domains is finite - and (very) slowly changing (most are currently on 5.3.1)
  • Solutions - need to have a concept id per domain
  • Could define code system supplements to add these as additional properties
  • Could define an OMOP code system for each domain
  • Could use a ConceptMap
  • Grahame - would like a terminology server to be able to give the OMOP concept id for each domain
  • Given the OMOP concept id the server should return the original source concept id
  • Need to consider "standard" vs. "non-standard" in OMOP
  • Have reached the allotted time - Grahame will take the requirements and will come back with a proposal for how to manage this in the terminology server
  • Can come back with this in 2 weeks

Starting point:

  • OMOP defines concept domains and concept ids, At present the Athena schema makes concept ids unique across all domains
  • External concepts (codes defined in other code systems) - ideally one entry per concept domain, but may be more than one for historical reasons (but I can't find any)
  • terminology operations we want the servers to provide:
    • given an external code, get a concept id in a concept domain
    • given a concept domain and concept id, get a list of external concepts

Example Data

Type Concept ID Description Domain External Mapping Code System External Mapping Concept ID Alternative Display 1 Alternative Display 2
Concept 381591 Cerebrovascular disease Condition SNOMED CT 62914000 CVD - Cerebrovascular disease Cerebrovascular disease (disorder)
Internal Relationship Standard to Non-standard map (OMOP) 1568361 Vascular syndromes of brain in cerebrovascular diseases Condition ICD10CM G46

This structure (which is a tiny subset of the relationships defined for 381591) says that the concept id 381591 represents the SNOMED CT code 62914000, and there's also a concept id 1568361 that maps to ICD10CM code G46.

Versioning

Both the OMOP concepts and the external code systems are versioned. The versions aren't included in the examples, but they could be. We need to determine the versioning scheme for the OMOP concepts; probably the most compelling is to use date of download from Athena (yyyy-mm-dd).

OMOP Concepts Code System

All the approaches below assume that there is a single FHIR CodeSystem for all the OMOP concepts (all FHIR Concept IDs are unique within the whole space). In these examples, this code system is assigned the URL http://fhir.ohdsi.org/CodeSystem/concepts. This would need to be formally agreed. The ConceptMap would include properties, designations, and there would also be value sets and concepts.

The content of these resources is derived directly and algorithmically from the OMOP terminology content; all the is required for this is agree on the URLs and codes that represent the properties. The appropriate properties depends on which of the approaches below is chosen.

Possible Approaches to Consider

The committee identified 3 approaches to consider:

  • Provide supplements (as FHIR CodeSystem resources) to external coding systems that define the OMOP concept ID using properties
  • Provide OMOP Concepts as a FHIR CodeSystem, with external mappings as a property
  • Provide OMOP Concepts as a FHIR CodeSystem, with external mappings as a concept map

Possible Approach one: Code System supplements

In this case, we would publish supplements like this, that add the OMOP concept ids as properties to the existing code systems:

{
  "resourceType" : "CodeSystem",
  "url" : "http://fhir.ohdsi.org/CodeSystem/snomed-mappings",
  "supplements" : "http://snomed.info/sct",
  "property" : [{
    "code" : "omop",
    "uri" : "http://fhir.ohdsi.org/CodeSystem/properties#snomed-mappings",
    "description" : "An OMOP Concept ID for the SNOMED code",
    "type" : "Coding"
  }]
  "concept" : [
    "code" : "62914000",
    "property" : [{
      "code" : "omop",
      "valueCoding" : {
        "system" : "http://fhir.ohdsi.org/CodeSystem/concepts",
        "code" : "381591"
      }
    }]
  ]
}

To find the OMOP code for the SNOMED CT Code:

http://{tx-server}/CodeSystem/$lookup?system=http://snomed.info/sct&code=62914000&property=omop&useSupplement=http://fhir.ohdsi.org/CodeSystem/snomed-mappings

return:

{
  "resourceType" : "Parameters",
  "parameter" : [{
    "name" : "property",
    "part" : [{
      "code" : "code",
      "valueCode" : "omop"
    },{
      "code" : "value",
      "valueCoding" : {
        "system" : "http://fhir.ohdsi.org/CodeSystem/concepts",
        "code" : "381591"
      }
    }]
  }]
}

Determining the SNOMED CT Code for the OMOP concept

POST http://{tx-server}/ValueSet/$expand?useSupplement=http://fhir.ohdsi.org/CodeSystem/snomed-mappings
{
  "resourceType" : "ValueSet",
  "compose" : {
    "include" : [{
      "system" : "http://snomed.info/sct",
      "filter" : [{
        "property" : "omop",
        "op": "=",
        "value" : "381591"
      }]
    }]
  }
}

return:

{
  "resourceType" : "ValueSet",
  "expansion" : {
    "parameter" : [{
      "name" : "useSupplement",
      "valueUri" : "http://fhir.ohdsi.org/CodeSystem/snomed-mappings"
    }],
    "contains" : [{
      "system" : "http://snomed.info/sct",
      "code" : "62914000"
    }]
  }
}

Pros:

  • .. can't think of any

Cons:

  • I don't know why you'd do this when you really have to define a FHIR code system in order to refer to the OMOP concepts anyway
  • There's no easy way to properly represent OMOP versions this way

Possible Approach two: OMOP Code System with properties

In this case, we would publish a CodeSystem like this:

{
  "resourceType" : "CodeSystem",
  "url" : "http://fhir.ohdsi.org/CodeSystem/concepts",
  "property" : [{
    "code" : "sct",
    "uri" : "http://fhir.ohdsi.org/CodeSystem/properties#snomed-mappings",
    "description" : "A SNOMED CT code for the OMOP Concept ID",
    "type" : "Coding"
  }]
  "concept" : [
    "code" : "381591",
    "display" : "Cerebrovascular disease",
    "property" : [{
      "code" : "sct",
      "valueCoding" : {
        "system" : "http://snomed.info/sct",
        "code" : "62914000"
      }
    }]
  ]
}

To find the OMOP code for the SNOMED CT Code:

POST http://{tx-server}/ValueSet/$expand? 
{
  "resourceType" : "ValueSet",
  "compose" : {
    "include" : [{
      "system" : "http://fhir.ohdsi.org/CodeSystem/concepts",
      "filter" : [{
        "property" : "sct",
        "op": "=",
        "value" : "62914000"
      }]
    }]
  }
}

return:

{
  "resourceType" : "ValueSet",
  "expansion" : {
    "contains" : [{
      "system" : "http://fhir.ohdsi.org/CodeSystem/concepts",
      "code" : "381591"
    }]
  }
}

Determining the SNOMED CT Code for the OMOP concept

http://{tx-server}/CodeSystem/$lookup?system=http://fhir.ohdsi.org/CodeSystem/concepts&code=381591&property=sct

return:

{
  "resourceType" : "Parameters",
  "parameter" : [{
    "name" : "property",
    "part" : [{
      "code" : "code",
      "valueCode" : "sct"
    },{
      "code" : "value",
      "valueCoding" : {
        "system" : "http://snomed.info/sct",
        "code" : "62914000"
      }
    }]
  }]
}

Pros:

  • .. well, at least time we leverage the fact that we've defined a code system for OMOP

Cons:

  • but the query method is still ungainly, because these things aren't really properties
  • There's no easy way to properly represent external code system versions this way

Possible Approach three: OMOP Code System with ConceptMaps

In this case, we would publish a CodeSystem like this:

{
  "resourceType" : "CodeSystem",
  "url" : "http://fhir.ohdsi.org/CodeSystem/concepts",
  "property" : [{
    "code" : "domain",
    "uri" : "http://fhir.ohdsi.org/CodeSystem/properties#domain",
    "description" : "The OMOP Domain for this concept ID",
    "type" : "code"
  }]
  "concept" : [{
    "code" : "381591",
    "display" : "Cerebrovascular disease",
    "property" : [{
      "code" : "domain",
      "valueCode" : "19"
    }]
  },{
    "code" : "19",
    "display" : "Condition"
  }]
}

ValueSets like this:

{
  "resourceType" : "ValueSet",
  "url" : "http://fhir.ohdsi.org/ValueSet/Condition",
  "compose" : [
    "include" : [{
      "system" : "http://fhir.ohdsi.org/CodeSystem/concepts",
      "filter" : [{
        "property" : "domain",
        "op": "=",
        "value" : "19"
      }]
    }]
  ]
}

and a pair of concept maps like this:

{
  "resourceType" : "ConceptMap",
  "url" : "http://fhir.ohdsi.org/ConceptMap/ConditionToSCT",
  "sourceScopeUri" : "http://fhir.ohdsi.org/ValueSet/Condition",
  "targetScopeUri" : "http://snomed.info/sct?fhir_vs",
  "group" : [{
    "source" : "http://fhir.ohdsi.org/CodeSystem/concepts",
    "target" : "http://snomed.info/sct",
    "element: " [{
      "code" : "381591",
      "target" : [{
        "code" : "62914000",
        "relationship" : "equivalent"
      }]
    }]
  }]
}

and

{
  "resourceType" : "ConceptMap",
  "url" : "http://fhir.ohdsi.org/ConceptMap/SCTToCondition",
  "sourceScopeUri" : "http://snomed.info/sct?fhir_vs",
  "targetScopeUri" : "http://fhir.ohdsi.org/ValueSet/Condition",
  "group" : [{
    "source" : "http://snomed.info/sct",
    "target" : "http://fhir.ohdsi.org/CodeSystem/concepts",
    "element: " [{
      "code" : "62914000",
      "target" : [{
        "code" : "381591",
        "relationship" : "equivalent"
      }]
    }]
  }]
}

To find the OMOP code for the SNOMED CT Code:

POST http://{tx-server}/ConceptMap/$translate?system=http://snomed.info/sct&code=62914000&targetSystem=http://fhir.ohdsi.org/CodeSystem/concepts

return:

{
  "resourceType" : "Parameters",
  "parameter" : [{
    "name" : "result",
    "valueBoolean" : true
  },{
    "name" : "match",
    "part" : [{
      "code" : "relationship",
      "valueCode" : "related-to"
    },{
      "code" : "concept",
      "valueCoding" : {
        "system" : "http://fhir.ohdsi.org/CodeSystem/concepts",
        "code" : "381591"
      }
    }]
  }]
}

Determining the SNOMED CT Code for the OMOP concept

POST http://{tx-server}/ConceptMap/$translate?system=http://fhir.ohdsi.org/CodeSystem/concepts&code=381591&targetSystem=http://snomed.info/sct

return:

{
  "resourceType" : "Parameters",
  "parameter" : [{
    "name" : "result",
    "valueBoolean" : true
  },{
    "name" : "match",
    "part" : [{
      "code" : "relationship",
      "valueCode" : "related-to"
    },{
      "code" : "concept",
      "valueCoding" : {
        "system" : "http://snomed.info/sct",
        "code" : "62914000"
      }
    }]
  }]
}

Pros:

  • Proper use of the terminology subsystem for OMOP concepts as CodeSystems + ValueSets
  • leverage the OMOP code system and value sets in the concept maps
  • There'll be lots of OMOP concept maps - there's a rich set of relationships defined for OMOP
  • The exchange is the same pattern in either direction, and includes the right set of metadata

Cons:

  • ? none

Additional Notes about the OMOP terminology

  • because the OMOP terminology has a highly regular database structure, it's particularly amenable to defining implicit value sets and concept maps, and we should do this

e.g. we would define:

  1. CodeSystem http://fhir.ohdsi.org/CodeSystem/concepts - entirely generated from a template and the OMOP CONCEPT and CONCEPT_SYNONYM tables
  2. ValueSets http://fhir.ohdsi.org/ValueSet/{Domain} - implicit value sets with a template generated from a list of the domains in the OMOP DOMAIN table
  3. ConceptMaps for the external mappings in the OMOP CONCEPT table - implicit value concept maps generated from the contents of the database

(note that this point applies to all of the possible approaches: the semantics of all of them are implicit in the OMOP tables, all we do is assign some fixed identifiers to them)

  • the set of relationships defined in OMOP would be useful outside of OMOP - e.g. it would be possible to derive an SCT/ICD10 cross-map for general use.
    • Any issues with that would likely be issues in OMOP itself so wider eyeballs on this would be good from OMOP perspective

indirect relationships

We haven't clarified in these approaches, or in the general case, whether the $translate operation does multi-hop translations. e.g. if we're looking for OMOP concept Ids for SNOMED CT 62914000, we get back 381591, but do we also get 1568361? Do we assume that we could, or should? What about translating from SNOMED CT to ICD10 via these relationships in a single $translate?

Clone this wiki locally