Observation
→
observation
implemented
Qualitative clinical findings: social history, lifestyle factors, survey responses, activity data. One FHIR Observation (or one component) maps to one OMOP observation row. Also receives data from AllergyIntolerance and FamilyMemberHistory.
Conversion profile
omop-observation-observation
A FHIR instance converts to observation iff it validates against this profile.
| Path | Card | Type | Binding / Fixed | Comment |
|---|---|---|---|---|
| Observation.status | fhir/observation-statusrequired | |||
| Observation.code | 1..*MS | omop-observation-codesrequired | ||
| Observation.subject | 1..* | Reference | ||
| Observation.effective[x] | 1..*MS |
ViewDefinition (Stage 1 flattener)
omop-observation-observation
19 columns · resource Observation
| column name | FHIRPath | type |
|---|---|---|
| id | Observation.id | id |
| code_loinc | Observation.code.coding.where(system='http://loinc.org').first().code | code |
| code_snomed | Observation.code.coding.where(system='http://snomed.info/sct').first().code | code |
| code_text | Observation.code.text | string |
| value_code_snomed | Observation.valueCodeableConcept.coding.where(system='http://snomed.info/sct').first().code | code |
| value_code_loinc | Observation.valueCodeableConcept.coding.where(system='http://loinc.org').first().code | code |
| value_code_text | Observation.valueCodeableConcept.text | string |
| subject_id | Observation.subject | Reference(Patient) |
| observation_date | Observation.effectiveDateTime | dateTime |
| observation_datetime | Observation.effectiveDateTime | dateTime |
| value_as_number | Observation.valueQuantity.value | decimal |
| value_as_string | Observation.valueString | string |
| qualifier_text | Observation.interpretation[0].coding[0].code | code |
| qualifier | Observation.interpretation | CodeableConcept |
| unit_text | Observation.valueQuantity.unit | string |
| unit | Observation.valueQuantity.code | code |
| performer_id | Observation.performer[0] | Reference(Practitioner) |
| encounter_id | Observation.encounter | Reference(Encounter) |
| value_text | computed | string |
Condition: category is social-history, survey, or activity
Implementation:
src/mapper/observation.tsFields (21)
-
observation_id←Observation.idinteger · idPKrequiredGenerated deterministically from Observation.id + -comp-N suffix for component rows -
person_id←Observation.subjectinteger · Reference(Patient)FK→PERSONrequired -
observation_concept_id←Observation.code | Observation.component.codeinteger · CodeableConceptFK→CONCEPTrequiredLOINC/SNOMED mapped to OMOP standard concept. Placeholder: 0.3 sources ▾
-
LOINC-priority vocab lookup; 0 placeholder when not found
- omoponfhir(java) refs/refs/omoponfhir-omopv5-r4-mapping/src/main/java/edu/gatech/chai/omoponfhir/omopv5/r4/mapping/OmopObservation.java:1142-1159 — constructOmopObservation code lookup
- fhir-omop-ig(fml) refs/refs/fhir-omop-ig/input/maps/Observation.fml
-
Domain-based routing: LOINC looked up in OMOP vocabulary for domain_id before mapping concept
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java:542-605 — LoincStandardDomainLookup; Observation domain case line 692
- fhir-to-omop-demo(jq) refs/refs/fhir-to-omop-demo/demo/translate/map/Observation.jq:31-44 — domain-based routing excluding Condition/Drug/Measurement/Procedure
-
type_concept_id varies by code system (LOINC=32817, SNOMED=32818), concept lookup depends on code system
- fhir-x-omop(python) refs/refs/fhir-x-omop/fhir_x_omop/to_omop/observation.py:21-24
-
-
observation_date←Observation.effectiveDateTime | Observation.effectivePeriod.startdate · dateTimerequiredtransform:dateTime -> date2 sources ▾
-
effectivePeriod.start fallback; skip when both absent
- fhir-omop-ig(fml) refs/refs/fhir-omop-ig/input/maps/Observation.fml:29-33 — dateTime, instant, Period.start
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java
-
issued used as date fallback when effectiveDateTime absent
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java — issued fallback (same as measurement)
-
-
observation_datetime←Observation.effectiveDateTime | Observation.effectivePeriod.startdatetime · dateTime -
observation_type_concept_id← constant integerrequired=32817EHR3 sources ▾
-
32817 (EHR) constant for all rows
- fhir-omop-ig(fml) refs/refs/fhir-omop-ig/input/maps/Observation.fml
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java
-
Category-sensitive: survey→45905771, exam→44818701 (OMOP→FHIR direction only)
- omoponfhir(java) refs/refs/omoponfhir-omopv5-r4-mapping/src/main/java/edu/gatech/chai/omoponfhir/omopv5/r4/mapping/OmopObservation.java:1082-1104 — Category → type concept mapping
-
type_concept_id varies by code system: LOINC=32817, SNOMED=32818
- fhir-x-omop(python) refs/refs/fhir-x-omop/fhir_x_omop/to_omop/observation.py:21-24
-
-
value_as_number←Observation.valueQuantity.valuefloat · decimalUncommon for qualitative observations -
value_as_string←Observation.valueString | Observation.valueCodeableConcept.textvarchar(60) · stringvalueString first; fall back to CodeableConcept source text3 sources ▾
-
valueString → value_as_string directly
- fhir-omop-ig(fml) refs/refs/fhir-omop-ig/input/maps/Observation.fml:49-49 — valueString → value_as_string
- fhir-to-omop-demo(jq) refs/refs/fhir-to-omop-demo/demo/translate/map/Observation.jq:160-160 — valueString → value_as_string
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java
-
CodeableConcept text used as value_as_string fallback
- HealthcareLakeETL(pyspark) refs/refs/HealthcareLakeETL/mappings/observation.py:31-31 — value_as_string from CC text
-
valueString mapped via FObservationView entity (indirect path)
-
-
value_as_concept_id←Observation.valueCodeableConceptinteger · CodeableConceptFK→CONCEPTRequires vocab lookup. Placeholder: null.2 sources ▾
-
Full vocabulary lookup to resolve coded result to OMOP standard concept
- omoponfhir(java) refs/refs/omoponfhir-omopv5-r4-mapping/src/main/java/edu/gatech/chai/omoponfhir/omopv5/r4/mapping/OmopObservation.java:1232-1280 — valueCodeableConcept mapping
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java
-
Passthrough of coding[0].code without vocabulary lookup
- fhir-omop-ig(fml) refs/refs/fhir-omop-ig/input/maps/Observation.fml:44-48
- fhir-x-omop(python) refs/refs/fhir-x-omop/fhir_x_omop/to_omop/observation.py:14-39
-
-
qualifier_source_value←Observation.interpretation[0].coding[0].codevarchar(50) · codeE.g. H for High, L for Low. Falls back to interpretation[0].text -
qualifier_concept_id←Observation.interpretationinteger · CodeableConceptFK→CONCEPTmap:interpretationRequires vocab lookup. Placeholder: null. -
unit_source_value←Observation.valueQuantity.unitvarchar(50) · string -
unit_concept_id←Observation.valueQuantity.codeinteger · codeFK→CONCEPTUCUM code mapped to OMOP unit concept. Placeholder: null.2 sources ▾
-
UCUM → OMOP vocabulary lookup performed at runtime
- omoponfhir(java) refs/refs/omoponfhir-omopv5-r4-mapping/src/main/java/edu/gatech/chai/omoponfhir/omopv5/r4/mapping/OmopObservation.java:1197-1230 — valueQuantity mapping including unit
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java
- fhir-to-omop-demo(jq) refs/refs/fhir-to-omop-demo/demo/translate/map/Observation.jq — pre-joined vocabulary lookup
-
Unit passthrough (code value, not vocab lookup) or 0 constant
- fhir-omop-ig(fml) refs/refs/fhir-omop-ig/input/maps/Observation.fml — unit passthrough per Implementation Comparison
- fhir-x-omop(python) refs/refs/fhir-x-omop/fhir_x_omop/to_omop/observation.py — hardcoded 0
-
-
provider_id←Observation.performer[0]integer · Reference(Practitioner)FK→PROVIDER -
visit_occurrence_id←Observation.encounterinteger · Reference(Encounter)FK→VISIT_OCCURRENCE -
visit_detail_id← — integerFK→VISIT_DETAILNot mapped -
observation_source_value←Observation.code.coding[best].codevarchar(50) · code4 sources ▾
-
Best vocabulary priority (LOINC > SNOMED > first coding code)
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java — LOINC code
-
issued or note text used instead of code
- fhir-omop-ig(fml) refs/refs/fhir-omop-ig/input/maps/Observation.fml — issued or note → observation_source_value per Implementation Comparison
-
identifier.value used as source value
- omoponfhir(java) refs/refs/omoponfhir-omopv5-r4-mapping/src/main/java/edu/gatech/chai/omoponfhir/omopv5/r4/mapping/OmopObservation.java:1111-1390 — identifier.value per Implementation Comparison
-
coding[0].code (first coding, no priority)
- fhir-x-omop(python) refs/refs/fhir-x-omop/fhir_x_omop/to_omop/observation.py:14-39
-
-
observation_source_concept_id← constant integer=0 -
value_source_value←computedvarchar(50) · stringtransform:comparator+value+unit | valueString | valueCodeableConcept.textComposite of comparator, numeric value, and unit; or valueString; or CodeableConcept text -
observation_event_id← — integerNot mapped. fhir-to-omop-demo sets to encounter.id1 source ▾
-
Set to encounter.id to link observation row to the encounter event
- fhir-to-omop-demo(jq) refs/refs/fhir-to-omop-demo/demo/translate/map/Observation.jq:172-172 — observation_event_id = encounter.id
-
-
obs_event_field_concept_id← — integerNot mapped
Vocabularies
interpretation
| Source | Display | Concept ID | Concept Name |
|---|---|---|---|
| H | High | - | |
| L | Low | - | |
| N | Normal | - | |
| A | Abnormal | - | |
| HH | Critical high | - | |
| LL | Critical low | - |
social_history_loinc
| Source | Display | Concept ID | Concept Name |
|---|---|---|---|
| 72166-2 | Tobacco smoking status | - | |
| 11367-0 | History of tobacco use | - | |
| 74013-4 | Alcoholic drinks per day | - | |
| 11331-6 | History of alcohol use | - | |
| 76689-9 | Sex assigned at birth | - |
domain_routing
| Source | Display | Concept ID | Concept Name |
|---|---|---|---|
| social-history | - | ||
| survey | - | ||
| activity | - | ||
| laboratory | - | ||
| vital-signs | - | ||
| (absent) | Absent or unknown category | - |
Edge Cases
valueString present
Maps directly to value_as_string.
valueCodeableConcept with no matching OMOP concept
value_as_concept_id=null. Text goes to value_as_string.
valueBoolean
Not mapped. Could use value_as_string='true'/'false' or concept IDs 4188539/4188540.
interpretation with multiple codings
Only first coding used for qualifier_source_value.
Status not in {final, amended, corrected}
Skip entire observation.
Missing effectiveDateTime
Skip -- observation_date is required.
effectivePeriod instead of dateTime
Use period.start.
Categories not in routing set (exam, imaging, therapy)
Route to measurement (default). HL7 IG routes these to observation.
LOINC code with Observation domain but lab category
Category wins (routes to measurement). ETL-German: domain wins.
Reference Implementations
- fhir-omop-ig(fml) refs/refs/fhir-omop-ig/input/maps/Observation.fml — 52 lines
- omoponfhir(java) refs/refs/omoponfhir-omopv5-r4-mapping/src/main/java/edu/gatech/chai/omoponfhir/omopv5/r4/mapping/OmopObservation.java:1-2164
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/ObservationMapper.java
- fhir-to-omop-demo(jq) refs/refs/fhir-to-omop-demo/demo/translate/map/Observation.jq