Source vs. Standard Concepts
Most OMOP CDM clinical event tables have two concept ID columns per coded field: *_concept_id for the analytics-ready standard concept, and *_source_concept_id for the OMOP concept that represents the original source code. Understanding which $translate returns — and why — prevents the most common F2O integration mistake.
Source concepts and standard concepts in OMOP
OMOP assigns a standard-concept flag to every concept (see the OMOP CDM concept table specification):
- Standard (S) — the authoritative concept for analytics queries and cohort definitions in its domain.
- Classification (C) — used in the OMOP concept hierarchy for grouping and browsing, but not written to patient-level CDM rows directly. Classification concepts will not appear as
$translateresults for typical clinical source codes. - Non-standard (NS) — preserved for provenance but not used for analytics. May carry a
Maps torelationship pointing to the standard concept; NS concepts with noMaps totarget have no standard mapping in the loaded release.
Every CDM row has a column for each kind:
| Column | What goes here |
|---|---|
*_source_concept_id | The OMOP concept that directly represents the original source code |
*_concept_id | The standard concept for analytics |
When the source code is already standard (standard-concept = S), both columns reference the same concept_id.
The standard-concept flag lives on the concept itself — not the vocabulary. Many ICD-10-CM concepts are non-standard, and many SNOMED concepts in the Condition domain are standard, but neither is universally true across all concepts in those vocabularies. The standard-concept property returned by $lookup is always the authoritative check.
What $translate returns
$translate returns the OMOP concept that directly represents the input code. Whether that concept is standard or non-standard depends on the concept itself:
- If the input code maps to a non-standard (NS) OMOP concept,
$translatereturns that NS concept. A$lookupstep is then needed to get the standard target viaMaps to. - If the input code maps to a standard (S) OMOP concept,
$translatereturns it directly — no further mapping step needed for*_concept_id.
For E11.9 (ICD-10-CM), the result is the non-standard source concept 35206882:
curl 'https://echidna.fhir.org/r4/ConceptMap/$translate?system=http://hl7.org/fhir/sid/icd-10-cm&code=E11.9&targetsystem=https://fhir-terminology.ohdsi.org'
Returns 35206882, relationship equivalent. This matches the pattern documented in the Vulcan F2O IG — the two-step translate → lookup flow is the intended recipe, not a workaround.
→ 35206882 goes into condition_source_concept_id.
Getting the standard concept via $lookup
For non-standard source codes, pass the source concept_id to $lookup requesting standard-concept, Maps to, and domain-id. For 35206882 the response returns standard-concept = NS, Maps to → 201826 (the standard SNOMED concept), and domain-id = Condition:
curl 'https://echidna.fhir.org/r4/CodeSystem/$lookup?system=https://fhir-terminology.ohdsi.org&code=35206882&property=standard-concept&property=Maps+to&property=domain-id'
See Quickstart → Step 2 for the full response and CDM column assignment.
OmopMapsTo — skip straight to the standard concept
Echidna provides a computed ConceptMap called OmopMapsTo that follows the Maps to relationship in a single $translate call, returning the standard concept directly. Pass the OmopMapsTo canonical URL as the url parameter alongside your source system and code:
curl 'https://echidna.fhir.org/r4/ConceptMap/$translate?url=https://tx.echidna.systems/ConceptMap/OmopMapsTo&system=http://hl7.org/fhir/sid/icd-10-cm&code=E11.9'
The response skips the source concept and returns 201826 directly:
{
"resourceType": "Parameters",
"parameter": [
{ "name": "result", "valueBoolean": true },
{
"name": "match",
"part": [
{ "name": "equivalence", "valueCode": "relatedto" },
{ "name": "concept", "valueCoding": {
"system": "https://fhir-terminology.ohdsi.org",
"version": "20260227",
"code": "201826",
"display": "Type 2 diabetes mellitus"
}
}
]
}
]
}
Use OmopMapsTo when you only need the standard concept — it works directly from the external source code, so no prior $translate step is needed. For the full CDM row you still need the two-step recipe from the Quickstart to get the source concept_id and domain-id.
Echidna returns the source concept from a plain $translate when the input is a non-standard code. This matches the pattern documented in the Vulcan F2O IG. If your engine was expecting the standard concept directly, use OmopMapsTo or add the $lookup step — the default is correct behaviour.
Non-standard concepts with no Maps to target
If $lookup returns standard-concept = NS and no Maps to property, the concept has no standard mapping in the loaded release. Write *_source_concept_id = <source_id> and *_concept_id = 0 (the OMOP convention for unmapped codes). This typically happens for codes that are retired, ambiguous, or from vocabularies not fully mapped in the loaded release.
Note that absence of Maps to alone is not sufficient to draw this conclusion — a standard-concept = S concept also has no Maps to (it is the mapping target, not the source). Always check the standard-concept flag first.