Skip to main content

BFF to OMOP

Information

This table reflects the current bff2omop implementation in convert-pheno. The conversion maps one Beacon individual into OMOP PERSON and expands repeated Beacon fields into OMOP row arrays such as CONDITION_OCCURRENCE, OBSERVATION, PROCEDURE_OCCURRENCE, MEASUREMENT, and DRUG_EXPOSURE.

Version 0.34​

Output model: OMOP CDM

Entity: PERSON, CONDITION_OCCURRENCE, OBSERVATION, PROCEDURE_OCCURRENCE, MEASUREMENT, DRUG_EXPOSURE

OMOP Concept Resolution​

For each mapped BFF ontology term, Convert-Pheno checks the identifier before the label. An active standard concept in the expected OMOP domain is used directly; a non-standard source concept is resolved through its active Maps to relationship (Maps to value for categorical measurement values). Only then can the configured exact, mixed, or fuzzy search use the label, and that search remains restricted to active standard concepts in the expected domain.

If no unique eligible target exists, the target concept is 0 rather than an unrelated same-label concept. Source values are preserved, and source concept ids are populated when the BFF identifier exists in Athena. This behavior requires the current enriched ohdsi.db; see Terminology Search for the label-search modes and audit output.

Terms​

PERSON​

Source fieldTarget fieldNotes
idPERSON.person_idDirect when numeric; otherwise convert-pheno allocates a surrogate integer and preserves the original value in person_source_value
idPERSON.person_source_valueDirect
info.dateOfBirthPERSON.birth_datetimeDirect
info.dateOfBirthPERSON.year_of_birth, month_of_birth, day_of_birthExtracted from the ISO8601 timestamp
missing info.dateOfBirthPERSON.birth_datetimeDefaults to 1900-01-01T00:00:00Z
missing info.dateOfBirthPERSON.year_of_birthDefaults to 1900
sexPERSON.gender_concept_id, gender_source_value, gender_source_concept_idResolved as an OMOP Gender term
ethnicityPERSON.race_* or ethnicity_*Resolved against the OMOP Race and Ethnicity domains; the target domain determines the destination fields
geographicOriginPERSON.ethnicity_source_valueEstablished fallback when no true Ethnicity term resolved; geographic origin is not treated as an ethnicity concept
missing ethnicity / geographicOriginPERSON.race_concept_id, ethnicity_concept_idDefault concept id 0 with empty source values

CONDITION_OCCURRENCE​

Source fieldTarget fieldNotes
diseases[].diseaseCodeCONDITION_OCCURRENCE.condition_concept_id, condition_source_value, condition_source_concept_idResolved as an OMOP Condition term
diseases[].ageOfOnset.age.iso8601duration + PERSON.year_of_birthCONDITION_OCCURRENCE.condition_start_dateConverted with get_date_at_age(...)
missing diseases[].ageOfOnsetCONDITION_OCCURRENCE.condition_start_dateDefaults to 1900-01-01
generated by convert-phenoCONDITION_OCCURRENCE.condition_occurrence_idMonotonic counter
defaultCONDITION_OCCURRENCE.condition_type_concept_idCurrently forced to concept id 0
diseases[]._visit.occurrence_idCONDITION_OCCURRENCE.visit_occurrence_idDirect when numeric; otherwise a surrogate integer is allocated
diseases[]._visit.detail_idCONDITION_OCCURRENCE.visit_detail_idDirect
current individual idCONDITION_OCCURRENCE.person_idReuses PERSON.person_id

OBSERVATION from exposures​

Source fieldTarget fieldNotes
exposures[].exposureCodeOBSERVATION.observation_concept_id, observation_source_value, observation_source_concept_idResolved as an OMOP Observation term
exposures[].dateOBSERVATION.observation_dateDirect
exposures[].valueOBSERVATION.value_as_numberDirect
missing exposures[].valueOBSERVATION.value_as_numberDefaults to -1
exposures[].unitOBSERVATION.unit_concept_id, unit_source_valueResolved as an OMOP Unit term
generated by convert-phenoOBSERVATION.observation_idMonotonic counter
defaultOBSERVATION.observation_type_concept_idCurrently forced to concept id 0
defaultOBSERVATION.value_as_concept_id, value_as_stringCurrently emitted as empty strings
exposures[]._visit.occurrence_idOBSERVATION.visit_occurrence_idDirect when numeric; otherwise a surrogate integer is allocated
exposures[]._visit.detail_idOBSERVATION.visit_detail_idDirect
current individual idOBSERVATION.person_idReuses PERSON.person_id

OBSERVATION from phenotypicFeatures​

Source fieldTarget fieldNotes
phenotypicFeatures[].featureTypeOBSERVATION.observation_concept_id, observation_source_value, observation_source_concept_idResolved as an OMOP Observation term
phenotypicFeatures[].onset.iso8601duration + PERSON.year_of_birthOBSERVATION.observation_dateConverted with get_date_at_age(...)
missing phenotypicFeatures[].onsetOBSERVATION.observation_dateDefaults to 1900-01-01
phenotypicFeatures[].valueOBSERVATION.value_as_numberDirect
missing phenotypicFeatures[].valueOBSERVATION.value_as_numberDefaults to -1
phenotypicFeatures[].unitOBSERVATION.unit_concept_id, unit_source_valueResolved as an OMOP Unit term
phenotypicFeatures[].excluded == truenoneSkipped entirely
generated by convert-phenoOBSERVATION.observation_idMonotonic counter, appended to any existing exposure-derived observations
defaultOBSERVATION.observation_type_concept_idCurrently forced to concept id 0
defaultOBSERVATION.value_as_concept_id, value_as_stringCurrently emitted as empty strings
phenotypicFeatures[]._visit.occurrence_idOBSERVATION.visit_occurrence_idDirect when numeric; otherwise a surrogate integer is allocated
phenotypicFeatures[]._visit.detail_idOBSERVATION.visit_detail_idDirect
current individual idOBSERVATION.person_idReuses PERSON.person_id

PROCEDURE_OCCURRENCE​

Source fieldTarget fieldNotes
interventionsOrProcedures[].procedureCodePROCEDURE_OCCURRENCE.procedure_concept_id, procedure_source_value, procedure_source_concept_idResolved as an OMOP Procedure term
interventionsOrProcedures[].dateOfProcedurePROCEDURE_OCCURRENCE.procedure_dateDirect
interventionsOrProcedures[].dateOfProcedurePROCEDURE_OCCURRENCE.procedure_datetimeConverted to YYYY-MM-DDTHH:MM:SSZ
missing interventionsOrProcedures[].dateOfProcedurePROCEDURE_OCCURRENCE.procedure_date, procedure_datetimeDefaults to 1900-01-01 and 1900-01-01T00:00:00Z
generated by convert-phenoPROCEDURE_OCCURRENCE.procedure_occurrence_idMonotonic counter
defaultPROCEDURE_OCCURRENCE.procedure_type_concept_idCurrently forced to concept id 0
interventionsOrProcedures[]._visit.occurrence_idPROCEDURE_OCCURRENCE.visit_occurrence_idDirect when numeric; otherwise a surrogate integer is allocated
interventionsOrProcedures[]._visit.detail_idPROCEDURE_OCCURRENCE.visit_detail_idDirect
current individual idPROCEDURE_OCCURRENCE.person_idReuses PERSON.person_id

MEASUREMENT​

Source fieldTarget fieldNotes
measures[].assayCodeMEASUREMENT.measurement_concept_id, measurement_source_value, measurement_source_concept_idResolved as an OMOP Measurement term
measures[].dateMEASUREMENT.measurement_dateDirect
measures[].measurementValue (scalar)MEASUREMENT.value_as_numberDirect
measures[].measurementValue.quantity.valueMEASUREMENT.value_as_numberUsed when the measurement value is a quantity object
measures[].measurementValue.quantity.referenceRange.lowMEASUREMENT.range_lowDirect
measures[].measurementValue.quantity.referenceRange.highMEASUREMENT.range_highDirect
measures[].measurementValue (ontology term)MEASUREMENT.value_as_concept_id, value_source_valueResolved in the OMOP Meas Value domain, including Maps to value relationships
measures[].measurementValue.quantity.unitMEASUREMENT.unit_concept_id, unit_source_value, unit_source_concept_idResolved as an OMOP Unit term
missing measures[].measurementValueMEASUREMENT.value_as_numberDefaults to -1
MEASUREMENT.value_as_numberMEASUREMENT.value_source_valueCopied back as provenance/source payload
measures[].procedurenoneDescribes the assay method, not OMOP record provenance; measurement_type_concept_id remains 0
generated by convert-phenoMEASUREMENT.measurement_idMonotonic counter
measures[]._visit.occurrence_idMEASUREMENT.visit_occurrence_idDirect when numeric; otherwise a surrogate integer is allocated
measures[]._visit.detail_idMEASUREMENT.visit_detail_idDirect
current individual idMEASUREMENT.person_idReuses PERSON.person_id

DRUG_EXPOSURE​

Source fieldTarget fieldNotes
treatments[].treatmentCodeDRUG_EXPOSURE.drug_concept_id, drug_source_value, drug_source_concept_idResolved as an OMOP Drug term
treatments[].doseIntervals[0].quantity.valueDRUG_EXPOSURE.quantityUses only the first dose interval
missing treatments[].doseIntervals[].quantity.valueDRUG_EXPOSURE.quantityDefaults to -1
treatments[].doseIntervals[0].quantity.unit.labelDRUG_EXPOSURE.dose_unit_source_valueUses only the first dose interval
treatments[].routeOfAdministrationDRUG_EXPOSURE.route_concept_id, route_source_valueResolved as an OMOP Route term
treatments[].doseIntervals[0].interval.start/endDRUG_EXPOSURE.drug_exposure_start_date, drug_exposure_end_datePreferred source; timestamps are truncated to dates and a single bound is reused for both fields when the other is missing
treatments[].ageOfOnset.age.iso8601duration + PERSON.year_of_birthDRUG_EXPOSURE.drug_exposure_start_dateUsed when no interval dates are present
missing interval dates and missing ageOfOnsetDRUG_EXPOSURE.drug_exposure_start_dateDefaults to 1900-01-01
missing explicit end dateDRUG_EXPOSURE.drug_exposure_end_dateReuses the resolved start date
treatments[].cumulativeDose.unit.label + cumulativeDose.valueDRUG_EXPOSURE.days_supplyConverted with convert_label_to_days(...)
generated by convert-phenoDRUG_EXPOSURE.drug_exposure_idMonotonic counter
defaultDRUG_EXPOSURE.drug_type_concept_idCurrently forced to 0
treatments[]._visit.occurrence_idDRUG_EXPOSURE.visit_occurrence_idDirect when numeric; otherwise a surrogate integer is allocated
treatments[]._visit.detail_idDRUG_EXPOSURE.visit_detail_idDirect
current individual idDRUG_EXPOSURE.person_idReuses PERSON.person_id