def yield_kfdrc_vital_statuses(eng, table, study_id, kfdrc_patients): for row in make_select( eng, table, CONCEPT.PARTICIPANT.ID, CONCEPT.OUTCOME.EVENT_AGE_DAYS, CONCEPT.OUTCOME.VITAL_STATUS, ): participant_id = get(row, CONCEPT.PARTICIPANT.ID) event_age_days = get(row, CONCEPT.OUTCOME.EVENT_AGE_DAYS) vital_status = get(row, CONCEPT.OUTCOME.VITAL_STATUS) status = clinical_status.get(vital_status) if not participant_id or not status: continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, participant_id, vital_status, event_age_days), "meta": { "profile": [ "http://fhir.kids-first.io/StructureDefinition/kfdrc-vital-status" ] }, "status": "preliminary", "code": { "coding": [{ "code": "263493007", "system": "http://snomed.info/sct", "display": "Clinical status", }], "text": "Clinical status", }, "subject": { "reference": f'Patient/{kfdrc_patients[participant_id]["id"]}' }, "valueCodeableConcept": { "coding": [status], "text": vital_status }, } if event_age_days: retval.setdefault("extension", []).append({ "url": "http://fhir.kids-first.io/StructureDefinition/age-at-event", "valueAge": { "value": int(event_age_days), "unit": "d", "system": "http://unitsofmeasure.org", "code": "days", }, }) yield retval
def yield_groups(eng, table, study_id, kfdrc_patients): df = pd.DataFrame([ dict(row) for row in make_select( eng, table, CONCEPT.FAMILY.ID, CONCEPT.PARTICIPANT.SPECIES, CONCEPT.PARTICIPANT.ID, ) ]) for family_id, group in df.groupby(CONCEPT.FAMILY.ID): if not family_id: continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, study_id, family_id), "meta": { "profile": ["http://hl7.org/fhir/StructureDefinition/Group"] }, "identifier": [{ "system": f"https://kf-api-dataservice.kidsfirstdrc.org/families?study_id={study_id}&external_id=", "value": family_id, }], "actual": True, } for _, row in group.iterrows(): species = get(row, CONCEPT.PARTICIPANT.SPECIES) participant_id = get(row, CONCEPT.PARTICIPANT.ID) if not participant_id: continue retval["type"] = group_type.get(species) or "person" retval.setdefault("member", []).append({ "entity": { "reference": f'Patient/{kfdrc_patients[participant_id]["id"]}' } }) if not isinstance(retval.get("member"), list): continue yield retval, family_id
def yield_practitioner_roles(eng, table, practitioners, organizations): for row in make_select( eng, table, CONCEPT.INVESTIGATOR.ID, CONCEPT.INVESTIGATOR.INSTITUTION, CONCEPT.INVESTIGATOR.NAME, ): investigator_id = get(row, CONCEPT.INVESTIGATOR.ID) institution = get(row, CONCEPT.INVESTIGATOR.INSTITUTION) name = get(row, CONCEPT.INVESTIGATOR.NAME) if not all((institution, name)): continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, institution, name), "meta": { "profile": ["http://hl7.org/fhir/StructureDefinition/PractitionerRole"] }, "practitioner": { "reference": f'Practitioner/{practitioners[name]["id"]}' }, "organization": { "reference": f'Organization/{organizations[institution]["id"]}' }, "code": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/practitioner-role", "code": "researcher", "display": "Researcher", }] }], } if investigator_id: retval.setdefault("identifier", []).append({ "system": "https://kf-api-dataservice.kidsfirstdrc.org/investigators?external_id=", "value": investigator_id, }) yield retval, (institution, name)
def yield_practitioners(eng, table): for row in make_select(eng, table, CONCEPT.INVESTIGATOR.NAME): name = get(row, CONCEPT.INVESTIGATOR.NAME) if not name: continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, name), "meta": { "profile": ["http://hl7.org/fhir/StructureDefinition/Practitioner"] }, "identifier": [{ "system": "https://kf-api-dataservice.kidsfirstdrc.org/investigators?name=", "value": name, }], "name": [{ "text": name }], } yield retval, name
def yield_kfdrc_patient_relations(eng, table, kfdrc_patients): df = pd.DataFrame( [ dict(row) for row in make_select( eng, table, CONCEPT.FAMILY_RELATIONSHIP.PERSON1.ID, CONCEPT.FAMILY_RELATIONSHIP.PERSON2.ID, CONCEPT.FAMILY_RELATIONSHIP.RELATION_FROM_1_TO_2, ) ] ) for person2_id, group in df.groupby(CONCEPT.FAMILY_RELATIONSHIP.PERSON2.ID): retval = kfdrc_patients.get(person2_id) if not retval: continue for _, row in group.iterrows(): person1_id = get(row, CONCEPT.FAMILY_RELATIONSHIP.PERSON1.ID) relation = get( row, CONCEPT.FAMILY_RELATIONSHIP.RELATION_FROM_1_TO_2 ) retval.setdefault("extension", []).append( { "url": "http://fhir.kids-first.io/StructureDefinition/relation", "extension": [ { "url": "subject", "valueReference": { "reference": f'{RESOURCE_TYPE}/{kfdrc_patients[person1_id]["id"]}' }, }, relation_dict[relation], ], } ) yield retval, person2_id
def yield_organizations(eng, table): for row in make_select(eng, table, CONCEPT.INVESTIGATOR.INSTITUTION): institution = get(row, CONCEPT.INVESTIGATOR.INSTITUTION) if not institution: continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, institution), "meta": { "profile": ["http://hl7.org/fhir/StructureDefinition/Organization"] }, "name": institution, } yield retval, institution
def yield_kfdrc_patients(eng, table, study_id): for row in make_select( eng, table, CONCEPT.PARTICIPANT.ID, CONCEPT.PARTICIPANT.ETHNICITY, CONCEPT.PARTICIPANT.RACE, CONCEPT.PARTICIPANT.SPECIES, CONCEPT.PARTICIPANT.GENDER, ): participant_id = get(row, CONCEPT.PARTICIPANT.ID) ethnicity = get(row, CONCEPT.PARTICIPANT.ETHNICITY) race = get(row, CONCEPT.PARTICIPANT.RACE) species = get(row, CONCEPT.PARTICIPANT.SPECIES) gender = get(row, CONCEPT.PARTICIPANT.GENDER) if not participant_id: continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, study_id, participant_id), "meta": { "profile": [ "http://fhir.kids-first.io/StructureDefinition/kfdrc-patient" ] }, "identifier": [{ "system": f"https://kf-api-dataservice.kidsfirstdrc.org/participants?study_id={study_id}&external_id=", "value": participant_id, }], } if ethnicity: if omb_ethnicity_category.get(ethnicity): retval.setdefault("extension", []).append({ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity", "extension": [ omb_ethnicity_category[ethnicity], { "url": "text", "valueString": ethnicity }, ], }) if race: if omb_race_category.get(race): retval.setdefault("extension", []).append({ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race", "extension": [ omb_race_category[race], { "url": "text", "valueString": race }, ], }) if species: if species_dict.get(species): retval.setdefault("extension", []).append(species_dict[species]) if gender: if administrative_gender.get(gender): retval["gender"] = administrative_gender[gender] yield retval, participant_id
def yield_kfdrc_specimens(eng, table, study_id, kfdrc_patients): for row in make_select( eng, table, CONCEPT.PARTICIPANT.ID, CONCEPT.BIOSPECIMEN.ID, CONCEPT.BIOSPECIMEN.EVENT_AGE_DAYS, CONCEPT.BIOSPECIMEN.CONCENTRATION_MG_PER_ML, CONCEPT.BIOSPECIMEN.COMPOSITION, CONCEPT.BIOSPECIMEN.VOLUME_UL, ): participant_id = get(row, CONCEPT.PARTICIPANT.ID) biospecimen_id = get(row, CONCEPT.BIOSPECIMEN.ID) event_age_days = get(row, CONCEPT.BIOSPECIMEN.EVENT_AGE_DAYS) concentration_mg_per_ml = get( row, CONCEPT.BIOSPECIMEN.CONCENTRATION_MG_PER_ML) composition = get(row, CONCEPT.BIOSPECIMEN.COMPOSITION) volume_ul = get(row, CONCEPT.BIOSPECIMEN.VOLUME_UL) if not all((participant_id, biospecimen_id)): continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, study_id, biospecimen_id), "meta": { "profile": [ "http://fhir.kids-first.io/StructureDefinition/kfdrc-specimen" ] }, "identifier": [{ "system": f"http://kf-api-dataservice.kidsfirstdrc.org/biospecimens?study_id={study_id}&external_aliquot_id=", "value": biospecimen_id, }], "subject": { "reference": f'Patient/{kfdrc_patients[participant_id]["id"]}' }, } if event_age_days: retval.setdefault("extension", []).append({ "url": "http://fhir.kids-first.io/StructureDefinition/age-at-event", "valueAge": { "value": int(event_age_days), "unit": "d", "system": "http://unitsofmeasure.org", "code": "days", }, }) if concentration_mg_per_ml: retval.setdefault("extension", []).append({ "url": "http://fhir.kids-first.io/StructureDefinition/concentration", "valueQuantity": { "value": float(concentration_mg_per_ml), "unit": "mg/mL", }, }) if composition: retval["type"] = { "coding": [specimen_type[composition]], "text": composition, } if volume_ul: retval.setdefault("collection", {})["quantity"] = { "unit": "uL", "value": float(volume_ul), } yield retval, biospecimen_id
def yield_kfdrc_research_studies(eng, table, target_service_id, organizations, practitioner_roles, groups): for row in make_select( eng, table, CONCEPT.STUDY.ID, CONCEPT.INVESTIGATOR.INSTITUTION, CONCEPT.INVESTIGATOR.NAME, CONCEPT.STUDY.ATTRIBUTION, CONCEPT.STUDY.SHORT_NAME, CONCEPT.STUDY.AUTHORITY, CONCEPT.STUDY.NAME, ): study_id = get(row, CONCEPT.STUDY.ID) institution = get(row, CONCEPT.INVESTIGATOR.INSTITUTION) investigator_name = get(row, CONCEPT.INVESTIGATOR.NAME) study_name = get(row, CONCEPT.STUDY.NAME) attribution = get(row, CONCEPT.STUDY.ATTRIBUTION) short_name = get(row, CONCEPT.STUDY.SHORT_NAME) if not all((study_id, institution, investigator_name, study_name)): continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, study_id), "meta": { "profile": [ "http://fhir.kids-first.io/StructureDefinition/kfdrc-research-study" ] }, "identifier": [ { "system": "https://kf-api-dataservice.kidsfirstdrc.org/studies", "value": target_service_id, }, { "system": "https://kf-api-dataservice.kidsfirstdrc.org/studies?external_id=", "value": study_id, }, ], "extension": [{ "url": "http://fhir.kids-first.io/StructureDefinition/related-organization", "extension": [{ "url": "organization", "valueReference": { "reference": f'Organization/{organizations[institution]["id"]}' }, }], }], "title": study_name, "status": "completed", "principalInvestigator": { "reference": f'PractitionerRole/{practitioner_roles[(institution, investigator_name)]["id"]}' }, } if attribution: retval["identifier"].append({"value": attribution}) if short_name: retval["extension"].append({ "url": "http://fhir.kids-first.io/StructureDefinition/display-name", "valueString": short_name, }) if groups: retval["enrollment"] = [{ "reference": f'Group/{group["id"]}' } for group in groups.values()] yield retval
def yield_kfdrc_conditions(eng, table, study_id, kfdrc_patients): for row in make_select( eng, table, CONCEPT.PARTICIPANT.ID, CONCEPT.DIAGNOSIS.NAME, CONCEPT.DIAGNOSIS.EVENT_AGE_DAYS, CONCEPT.DIAGNOSIS.MONDO_ID, CONCEPT.DIAGNOSIS.NCIT_ID, CONCEPT.DIAGNOSIS.ICD_ID, ): participant_id = get(row, CONCEPT.PARTICIPANT.ID) name = get(row, CONCEPT.DIAGNOSIS.NAME) event_age_days = get(row, CONCEPT.DIAGNOSIS.EVENT_AGE_DAYS) mondo = get(row, CONCEPT.DIAGNOSIS.MONDO_ID) ncit = get(row, CONCEPT.DIAGNOSIS.NCIT_ID) icd = get(row, CONCEPT.DIAGNOSIS.ICD_ID) if not all((participant_id, name)): continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier(RESOURCE_TYPE, study_id, participant_id, name, event_age_days), "meta": { "profile": [ "http://fhir.kids-first.io/StructureDefinition/kfdrc-condition" ] }, "category": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/condition-category", "code": "encounter-diagnosis", "display": "Encounter Diagnosis", }] }], "code": { "text": name }, "subject": { "reference": f'Patient/{kfdrc_patients[participant_id]["id"]}' }, } if event_age_days: retval.setdefault("extension", []).append({ "url": "http://fhir.kids-first.io/StructureDefinition/age-at-event", "valueAge": { "value": int(event_age_days), "unit": "d", "system": "http://unitsofmeasure.org", "code": "days", }, }) if mondo: retval["code"].setdefault("coding", []).append({ "system": "http://purl.obolibrary.org/obo/mondo.owl", "code": mondo, }) if ncit: retval["code"].setdefault("coding", []).append({ "system": "http://purl.obolibrary.org/obo/ncit.owl", "code": ncit }) if icd: retval["code"].setdefault("coding", []).append({ "system": "http://hl7.org/fhir/sid/icd-10", "code": icd }) yield retval
def yield_kfdrc_phenotypes(eng, table, study_id, kfdrc_patients): for row in make_select( eng, table, CONCEPT.PARTICIPANT.ID, CONCEPT.PHENOTYPE.NAME, CONCEPT.PHENOTYPE.HPO_ID, CONCEPT.PHENOTYPE.EVENT_AGE_DAYS, CONCEPT.PHENOTYPE.OBSERVED, ): participant_id = get(row, CONCEPT.PARTICIPANT.ID) name = get(row, CONCEPT.PHENOTYPE.NAME) hpo = get(row, CONCEPT.PHENOTYPE.HPO_ID) event_age_days = get(row, CONCEPT.PHENOTYPE.EVENT_AGE_DAYS) observed = get(row, CONCEPT.PHENOTYPE.OBSERVED) if not all( (participant_id, name, hpo)) or not interpretation.get(observed): continue retval = { "resourceType": RESOURCE_TYPE, "id": make_identifier( RESOURCE_TYPE, study_id, participant_id, name, observed, event_age_days, ), "meta": { "profile": [ "http://fhir.kids-first.io/StructureDefinition/kfdrc-phenotype" ] }, "status": "preliminary", "code": { "coding": [{ "code": hpo }], "text": name }, "subject": { "reference": f'Patient/{kfdrc_patients[participant_id]["id"]}' }, "interpretation": [{ "coding": [interpretation[observed]], "text": observed }], } if event_age_days: retval.setdefault("extension", []).append({ "url": "http://fhir.kids-first.io/StructureDefinition/age-at-event", "valueAge": { "value": int(event_age_days), "unit": "d", "system": "http://unitsofmeasure.org", "code": "days", }, }) yield retval