BFF to OMOP
bff2omop 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.35β
Output model: OMOP CDM
Entity: PERSON, CONDITION_OCCURRENCE, OBSERVATION, PROCEDURE_OCCURRENCE, MEASUREMENT, DRUG_EXPOSURE
Termsβ
PERSONβ
| Source field | Target field | Notes |
|---|---|---|
id | PERSON.person_id | Direct when numeric; otherwise convert-pheno allocates a surrogate integer and preserves the original value in person_source_value |
id | PERSON.person_source_value | Direct |
info.dateOfBirth | PERSON.birth_datetime | Direct |
info.dateOfBirth | PERSON.year_of_birth, month_of_birth, day_of_birth | Extracted from the ISO8601 timestamp |
missing info.dateOfBirth | PERSON.birth_datetime | Defaults to 1900-01-01T00:00:00Z |
missing info.dateOfBirth | PERSON.year_of_birth | Defaults to 1900 |
sex | PERSON.gender_concept_id, gender_source_value, gender_source_concept_id | Resolved as an OMOP Gender term |
ethnicity | PERSON.race_* or ethnicity_* | Resolved against the OMOP Race and Ethnicity domains; the target domain determines the destination fields |
geographicOrigin | PERSON.ethnicity_source_value | Established fallback when no true Ethnicity term resolved; geographic origin is not treated as an ethnicity concept |
missing ethnicity / geographicOrigin | PERSON.race_concept_id, ethnicity_concept_id | Default concept id 0 with empty source values |
CONDITION_OCCURRENCEβ
| Source field | Target field | Notes |
|---|---|---|
diseases[].diseaseCode | CONDITION_OCCURRENCE.condition_concept_id, condition_source_value, condition_source_concept_id | Resolved as an OMOP Condition term |
diseases[].ageOfOnset.age.iso8601duration + PERSON.year_of_birth | CONDITION_OCCURRENCE.condition_start_date | Converted with get_date_at_age(...) |
missing diseases[].ageOfOnset | CONDITION_OCCURRENCE.condition_start_date | Defaults to 1900-01-01 |
generated by convert-pheno | CONDITION_OCCURRENCE.condition_occurrence_id | Monotonic counter |
| default | CONDITION_OCCURRENCE.condition_type_concept_id | Currently forced to concept id 0 |
diseases[]._visit.occurrence_id | CONDITION_OCCURRENCE.visit_occurrence_id | Direct when numeric; otherwise a surrogate integer is allocated |
diseases[]._visit.detail_id | CONDITION_OCCURRENCE.visit_detail_id | Direct |
| current individual id | CONDITION_OCCURRENCE.person_id | Reuses PERSON.person_id |
OBSERVATION from exposuresβ
| Source field | Target field | Notes |
|---|---|---|
exposures[].exposureCode | OBSERVATION.observation_concept_id, observation_source_value, observation_source_concept_id | Resolved as an OMOP Observation term |
exposures[].date | OBSERVATION.observation_date | Direct |
exposures[].value | OBSERVATION.value_as_number | Direct |
missing exposures[].value | OBSERVATION.value_as_number | Defaults to -1 |
exposures[].unit | OBSERVATION.unit_concept_id, unit_source_value | Resolved as an OMOP Unit term |
generated by convert-pheno | OBSERVATION.observation_id | Monotonic counter |
| default | OBSERVATION.observation_type_concept_id | Currently forced to concept id 0 |
| default | OBSERVATION.value_as_concept_id, value_as_string | Currently emitted as empty strings |
exposures[]._visit.occurrence_id | OBSERVATION.visit_occurrence_id | Direct when numeric; otherwise a surrogate integer is allocated |
exposures[]._visit.detail_id | OBSERVATION.visit_detail_id | Direct |
| current individual id | OBSERVATION.person_id | Reuses PERSON.person_id |
OBSERVATION from phenotypicFeaturesβ
| Source field | Target field | Notes |
|---|---|---|
phenotypicFeatures[].featureType | OBSERVATION.observation_concept_id, observation_source_value, observation_source_concept_id | Resolved as an OMOP Observation term |
phenotypicFeatures[].onset.iso8601duration + PERSON.year_of_birth | OBSERVATION.observation_date | Converted with get_date_at_age(...) |
missing phenotypicFeatures[].onset | OBSERVATION.observation_date | Defaults to 1900-01-01 |
phenotypicFeatures[].value | OBSERVATION.value_as_number | Direct |
missing phenotypicFeatures[].value | OBSERVATION.value_as_number | Defaults to -1 |
phenotypicFeatures[].unit | OBSERVATION.unit_concept_id, unit_source_value | Resolved as an OMOP Unit term |
phenotypicFeatures[].excluded == true | none | Skipped entirely |
generated by convert-pheno | OBSERVATION.observation_id | Monotonic counter, appended to any existing exposure-derived observations |
| default | OBSERVATION.observation_type_concept_id | Currently forced to concept id 0 |
| default | OBSERVATION.value_as_concept_id, value_as_string | Currently emitted as empty strings |
phenotypicFeatures[]._visit.occurrence_id | OBSERVATION.visit_occurrence_id | Direct when numeric; otherwise a surrogate integer is allocated |
phenotypicFeatures[]._visit.detail_id | OBSERVATION.visit_detail_id | Direct |
| current individual id | OBSERVATION.person_id | Reuses PERSON.person_id |
PROCEDURE_OCCURRENCEβ
| Source field | Target field | Notes |
|---|---|---|
interventionsOrProcedures[].procedureCode | PROCEDURE_OCCURRENCE.procedure_concept_id, procedure_source_value, procedure_source_concept_id | Resolved as an OMOP Procedure term |
interventionsOrProcedures[].dateOfProcedure | PROCEDURE_OCCURRENCE.procedure_date | Direct |
interventionsOrProcedures[].dateOfProcedure | PROCEDURE_OCCURRENCE.procedure_datetime | Converted to YYYY-MM-DDTHH:MM:SSZ |
missing interventionsOrProcedures[].dateOfProcedure | PROCEDURE_OCCURRENCE.procedure_date, procedure_datetime | Defaults to 1900-01-01 and 1900-01-01T00:00:00Z |
generated by convert-pheno | PROCEDURE_OCCURRENCE.procedure_occurrence_id | Monotonic counter |
| default | PROCEDURE_OCCURRENCE.procedure_type_concept_id | Currently forced to concept id 0 |
interventionsOrProcedures[]._visit.occurrence_id | PROCEDURE_OCCURRENCE.visit_occurrence_id | Direct when numeric; otherwise a surrogate integer is allocated |
interventionsOrProcedures[]._visit.detail_id | PROCEDURE_OCCURRENCE.visit_detail_id | Direct |
| current individual id | PROCEDURE_OCCURRENCE.person_id | Reuses PERSON.person_id |
MEASUREMENTβ
| Source field | Target field | Notes |
|---|---|---|
measures[].assayCode | MEASUREMENT.measurement_concept_id, measurement_source_value, measurement_source_concept_id | Resolved as an OMOP Measurement term |
measures[].date | MEASUREMENT.measurement_date | Direct |
measures[].measurementValue (scalar) | MEASUREMENT.value_as_number | Direct |
measures[].measurementValue.quantity.value | MEASUREMENT.value_as_number | Used when the measurement value is a quantity object |
measures[].measurementValue.quantity.referenceRange.low | MEASUREMENT.range_low | Direct |
measures[].measurementValue.quantity.referenceRange.high | MEASUREMENT.range_high | Direct |
measures[].measurementValue (ontology term) | MEASUREMENT.value_as_concept_id, value_source_value | Resolved in the OMOP Meas Value domain, including Maps to value relationships |
measures[].measurementValue.quantity.unit | MEASUREMENT.unit_concept_id, unit_source_value, unit_source_concept_id | Resolved as an OMOP Unit term |
missing measures[].measurementValue | MEASUREMENT.value_as_number | Defaults to -1 |
MEASUREMENT.value_as_number | MEASUREMENT.value_source_value | Copied back as provenance/source payload |
measures[].procedure | none | Describes the assay method, not OMOP record provenance; measurement_type_concept_id remains 0 |
generated by convert-pheno | MEASUREMENT.measurement_id | Monotonic counter |
measures[]._visit.occurrence_id | MEASUREMENT.visit_occurrence_id | Direct when numeric; otherwise a surrogate integer is allocated |
measures[]._visit.detail_id | MEASUREMENT.visit_detail_id | Direct |
| current individual id | MEASUREMENT.person_id | Reuses PERSON.person_id |
DRUG_EXPOSUREβ
| Source field | Target field | Notes |
|---|---|---|
treatments[].treatmentCode | DRUG_EXPOSURE.drug_concept_id, drug_source_value, drug_source_concept_id | Resolved as an OMOP Drug term |
treatments[].doseIntervals[0].quantity.value | DRUG_EXPOSURE.quantity | Uses only the first dose interval |
missing treatments[].doseIntervals[].quantity.value | DRUG_EXPOSURE.quantity | Defaults to -1 |
treatments[].doseIntervals[0].quantity.unit.label | DRUG_EXPOSURE.dose_unit_source_value | Uses only the first dose interval |
treatments[].routeOfAdministration | DRUG_EXPOSURE.route_concept_id, route_source_value | Resolved as an OMOP Route term |
treatments[].doseIntervals[0].interval.start/end | DRUG_EXPOSURE.drug_exposure_start_date, drug_exposure_end_date | Preferred 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_birth | DRUG_EXPOSURE.drug_exposure_start_date | Used when no interval dates are present |
missing interval dates and missing ageOfOnset | DRUG_EXPOSURE.drug_exposure_start_date | Defaults to 1900-01-01 |
| missing explicit end date | DRUG_EXPOSURE.drug_exposure_end_date | Reuses the resolved start date |
treatments[].cumulativeDose.unit.label + cumulativeDose.value | DRUG_EXPOSURE.days_supply | Converted with convert_label_to_days(...) |
generated by convert-pheno | DRUG_EXPOSURE.drug_exposure_id | Monotonic counter |
| default | DRUG_EXPOSURE.drug_type_concept_id | Currently forced to 0 |
treatments[]._visit.occurrence_id | DRUG_EXPOSURE.visit_occurrence_id | Direct when numeric; otherwise a surrogate integer is allocated |
treatments[]._visit.detail_id | DRUG_EXPOSURE.visit_detail_id | Direct |
| current individual id | DRUG_EXPOSURE.person_id | Reuses PERSON.person_id |
Condition status: OMOP distinguishes admitting, preliminary and final
diagnoses. BFF-to-OMOP currently leaves condition_status_concept_id unset;
no default diagnostic status is assigned.
OMOP Concept Resolutionβ
Convert-Pheno searches ohdsi.db by identifier first, then by label.
Matches must resolve to a standard concept in the required OMOP domain.
Unresolved or ambiguous terms receive 0; source values are kept.
Search is exact by default. Mapping-file aliases can provide a reviewed label or identifier to look up. See Terminology Search for other modes and audit reports.