def create_or_update(self, server=FHIRServer, patient=patient.Patient, member=None): obs = self.resource or PROResult.createobservation( self.value, self.code, self.codesystem, self.codedisplay, self.date) # Patient patientreference = fhirreference.FHIRReference() patientreference.reference = f'Patient/{patient.id}' obs.subject = patientreference # request requestresource = self.request.resource if self.request else None if requestresource is not None: serviceRequestReference = fhirreference.FHIRReference() serviceRequestReference.reference = f'ServiceRequest/{requestresource.id}' obs.basedOn = [serviceRequestReference] # member resources if member is not None: ref = fhirreference.FHIRReference() ref.reference = f'QuestionnaireResponse/{member.id}' ref.hasMember = [ref] response = obs.create(server) if response is not None: self.resource = response self.identifier = response['id'] return self.identifier return None
def fhir_composition(obj): """ Converts Phenopacket to FHIR Composition. """ composition = comp.Composition() composition.id = obj['id'] composition.subject = fhirreference.FHIRReference() composition.subject.reference = str(obj['subject']['id']) composition.title = PHENOPACKETS_ON_FHIR_MAPPING['phenopacket']['title'] # elements in Composition required by FHIR spec composition.status = 'preliminary' composition.author = [] author = fhirreference.FHIRReference() author.reference = obj['meta_data']['created_by'] composition.author.append(author) composition.date = fhirdate.FHIRDate(obj['meta_data']['created']) composition.type = fhir_codeable_concept({ "id": PHENOPACKETS_ON_FHIR_MAPPING['phenopacket']['code']['code'], "label": PHENOPACKETS_ON_FHIR_MAPPING['phenopacket']['title'], "system": PHENOPACKETS_ON_FHIR_MAPPING['phenopacket']['code']['system'] }) composition.section = [] sections = ['biosamples', 'variants', 'diseases', 'hts_files'] for section in sections: if obj[section]: section_content = _get_section_object(obj.get(section, None), section) composition.section.append(section_content) return composition.as_json()
def createRequestResource(self, server=FHIRServer, patient=None, practitioner=None, schedule=None): from . import fhirutils if self.instrument is None: print("missin instrument to request") return None # Take instrument or from the argument instr = self.instrument # create new `ServiceRequest` serviceRequest = servicerequest.ServiceRequest() serviceRequest.status = 'active' serviceRequest.intent = 'plan' serviceRequest.category = self.category or [ PRORequest.EvaluationCodeableConcept() ] # Coding Request if instr.code is not None: serviceRequest.code = fhirutils.FHIRUtils.codeableconcept( instr.code, instr.codesystem, instr.title) # Tag Patient if patient is not None: patientreference = fhirreference.FHIRReference() patientreference.reference = f'Patient/{patient.id}' serviceRequest.subject = patientreference # Tag Practitioner if practitioner is not None: practitionerreference = fhirreference.FHIRReference() practitionerreference.reference = f'Practitioner/{practitioner.id}' practitionerreference.display = practitioner.name[0].text serviceRequest.requester = practitionerreference # Schedule if schedule is not None: timing_resource = schedule.createTimingResource() serviceRequest.occurrenceTiming = timing_resource else: now = datetime.datetime.utcnow() fhirDate = fhirdate.FHIRDate() fhirDate.date = now serviceRequest.occurrenceDateTime = fhirDate # Questionnaire Extension if Instrument is a `Questionnaire` if self.is_questionnaire(): extension = PRORequest.QuestionnaireExtension( questionnaire=self.instrument.resource) serviceRequest.extension = [extension] return serviceRequest
def fhir_condition(obj): """ Converts Disease to FHIR Condition. """ condition = cond.Condition() condition.id = str(obj['id']) condition.code = fhir_codeable_concept(obj['term']) # subject is required by Pheno-FHIR mapping Guide and by FHIR, set to 'unknown' condition.subject = fhirreference.FHIRReference() condition.subject.reference = 'unknown' condition.extension = [] # only adds disease-onset if it's ontology term # NOTE it is required element by Pheno-FHIR mapping guide but not Phenopackets if check_disease_onset(obj): onset_extension = extension.Extension() onset_extension.url = PHENOPACKETS_ON_FHIR_MAPPING['disease']['onset'] onset_extension.valueCodeableConcept = fhir_codeable_concept( obj['onset']['age']) condition.extension.append(onset_extension) if 'disease_stage' in obj.keys(): for item in obj['disease_stage']: disease_stage_extension = extension.Extension() disease_stage_extension.url = PHENOPACKETS_ON_FHIR_MAPPING[ 'disease']['disease_stage'] disease_stage_extension.valueCodeableConcept = fhir_codeable_concept( item) condition.extension.append(disease_stage_extension) return condition.as_json()
def create_sleep_observations(patient_ref): form_data = repo.generate_patient_sleep_data() for measurement in form_data.items(): # (date, val) date = measurement[0] value = measurement[1] observation = obs.Observation() observation.status = "registered" # <code> ref_patient = fhirref.FHIRReference() ref_patient.reference = "Patient/" + str(patient_ref) observation.subject = ref_patient observation.code = models.codeableconcept.CodeableConcept() code = models.coding.Coding() code.system = "SNOMED CT" code.code = "248263006" code.display = "Sleep Duration" observation.code.coding = [code] quantity = models.quantity.Quantity() quantity.value = value quantity.unit = "h" quantity.system = "http://unitsofmeasure.org" quantity.code = "h" observation.valueQuantity = quantity observation.effectiveDateTime = fhirdate.FHIRDate(date) result = observation.create(smart.server) print(result)
def _get_section_object(nested_obj, title): """Internal function to convert phenopacket m2m objects to Composition section. :param nested_obj: m2m relationship object :param title: field name that holds m2m relationship :return: section content object """ section_content = comp.CompositionSection() section_values = PHENOPACKETS_ON_FHIR_MAPPING['phenopacket'][title] section_content.title = section_values['title'] section_content.code = codeableconcept.CodeableConcept() section_content.code.coding = [] coding = c.Coding() coding.system = section_values['code']['system'] coding.version = section_values['code']['version'] coding.code = section_values['code']['code'] coding.display = section_values['code']['display'] section_content.code.coding.append(coding) section_content.entry = [] for item in nested_obj: entry = fhirreference.FHIRReference() if item.get('id'): entry.reference = str(item['id']) elif item.get('uri'): entry.reference = item['uri'] else: # generate uuid when no 'id' or 'uri' present entry.reference = str(uuid.uuid1()) section_content.entry.append(entry) return section_content
def create_QR_for_single_patient(patient_ref, form_data, name): for measurement in form_data.items(): date = measurement[0] categories = measurement[1] qr = qresponse.QuestionnaireResponse() qr.status = "completed" qr.authored = fhirdate.FHIRDate(date) qr.questionnaire = models.fhirreference.FHIRReference() qr.questionnaire.reference = getQuestionnaire(name) ref_patient = fhirref.FHIRReference() ref_patient.reference = patient_ref qr.subject = ref_patient answer_set = [] for i, (key, val) in enumerate(categories.items()): qr_item = qresponse.QuestionnaireResponseItem() qr_item.text = key qr_item.answer = [qresponse.QuestionnaireResponseItemAnswer()] qr_item.answer[0].valueInteger = int(val) qr_item.linkId = str( i) # Should correspond to item from Questionnaire answer_set.append(qr_item) qr.item = answer_set result = qr.create(smart.server) print(result)
def QuestionnaireExtension(questionnaire=questionnaire.Questionnaire): from fhirclient.models import extension extension = extension.Extension() extension.url = 'http://hl7.org/fhir/StructureDefinition/servicerequest-questionnaireRequest' reference = fhirreference.FHIRReference() reference.reference = f'Questionnaire/{questionnaire.id}' extension.valueReference = reference return extension
def phenopacket_to_fhir(obj): """Converts Phenopacket to FHIR Composition. :param obj: Phenopacket json :return: FHIR Composition json """ schema_path = os.path.join(SCHEMA_PATH, 'phenopacket_schema.json') try: validate_schema(schema_path, obj) except jsonschema.exceptions.ValidationError: raise Exception("The phenopacket object is not valid.") composition = comp.Composition() if 'id' in obj: composition.id = obj['id'] composition.subject = fhirreference.FHIRReference() if 'subject' in obj: composition.subject.reference = str(obj['subject']['id']) composition.title = PHENOPACKETS_ON_FHIR_MAPPING['phenopacket']['title'] # elements in Composition required by FHIR spec composition.status = 'preliminary' composition.author = [] author = fhirreference.FHIRReference() author.reference = obj['metaData']['createdBy'] composition.author.append(author) composition.date = fhirdate.FHIRDate(obj['metaData']['created']) composition.type = fhir_codeable_concept({ "id": PHENOPACKETS_ON_FHIR_MAPPING['phenopacket']['code']['code'], "label": PHENOPACKETS_ON_FHIR_MAPPING['phenopacket']['title'], "system": PHENOPACKETS_ON_FHIR_MAPPING['phenopacket']['code']['system'] }) composition.section = [] # TODO add htsFiles to the list and fix inconsistency in mappings sections = ['biosamples', 'variants', 'diseases'] for section in sections: if obj[section]: section_content = _get_section_object(obj.get(section, None), section) composition.section.append(section_content) return composition.as_json()
def fhir_specimen(obj): """ Converts biosample to FHIR Specimen. """ specimen = s.Specimen() specimen.identifier = [] # id identifier = fhir_indentifier.Identifier() identifier.value = obj['id'] specimen.identifier.append(identifier) # individual - subject property in FHIR is mandatory for a specimen specimen.subject = fhirreference.FHIRReference() specimen.subject.reference = obj.get('individual', 'unknown') # sampled_tissue specimen.type = codeableconcept.CodeableConcept() specimen.type.coding = [] coding = c.Coding() coding.code = obj['sampled_tissue']['id'] coding.display = obj['sampled_tissue']['label'] specimen.type.coding.append(coding) # description if 'description' in obj.keys(): specimen.note = [] annotation = a.Annotation() annotation.text = obj.get('description', None) specimen.note.append(annotation) # procedure specimen.collection = s.SpecimenCollection() specimen.collection.method = fhir_codeable_concept( obj['procedure']['code']) if 'body_site' in obj['procedure'].keys(): specimen.collection.bodySite = fhir_codeable_concept( obj['procedure']['body_site']) # Note on taxonomy from phenopackets specs: # Individuals already contain a taxonomy attribute so this attribute is not needed. # extensions specimen.extension = [] # individual_age_at_collection if 'individual_age_at_collection' in obj.keys(): ind_age_at_collection_extension = fhir_age( obj, PHENOPACKETS_ON_FHIR_MAPPING['biosample'] ['individual_age_at_collection'], 'individual_age_at_collection') specimen.extension.append(ind_age_at_collection_extension) concept_extensions = codeable_concepts_fields([ 'histological_diagnosis', 'tumor_progression', 'tumor_grade', 'diagnostic_markers' ], 'biosample', obj) for concept in concept_extensions: specimen.extension.append(concept) if 'is_control_sample' in obj.keys(): control_extension = extension.Extension() control_extension.url = PHENOPACKETS_ON_FHIR_MAPPING['biosample'][ 'is_control_sample'] control_extension.valueBoolean = obj['is_control_sample'] specimen.extension.append(control_extension) # TODO 2m extensions - references return specimen.as_json()
def _create_FHIRReference(resource): """ Used to create a FHIR reference object based on a FHIRClient.models object :param resource: FHIRClient.models class object (i.e. Patient()) :returns: FHIRReference object """ FHIRReference = fr.FHIRReference() FHIRReference.reference = f'{resource.resource_name}/{resource.id}' return FHIRReference
def init_aqr(q): aqr = QR.QuestionnaireResponse(f.aqr_templ(q.url), strict=False) # resets aqr and contained q aqr.questionnaire = Ref.FHIRReference( {'reference': '#contained-adaptive-{}'.format(q.id)}) # update the questionnaire aqr.id = q.url.rsplit('/')[-1].replace( 'questionnaire', 'adaptive-questionnaireresponse') # update the QR id dt = '{}Z'.format(datetime.utcnow().isoformat()) # start time... aqr.authored = FD.FHIRDate(dt) # update datetime # application.logger.info(json.dumps(qr.as_json(), indent=4, sort_keys=True)) # ---create narrative only answered and static questions --- logging.info(aqr) # get_next_q(q, aqr) return (aqr)
def add_phased_relationship_obv(self): patient_reference = reference.FHIRReference( {"reference": "Patient/" + self.patientID}) self.sequence_rels \ = get_sequence_relation(self.phased_rec_map) for index in self.sequence_rels.index: siduid = "sid-" + uuid4().hex[:13] self.result_ids.append(siduid) observation_sid = observation.Observation() observation_sid.resource_type = "Observation" observation_sid.id = siduid observation_sid.meta = meta.Meta({ "profile": [("http://hl7.org/fhir/uv/" + "genomics-reporting/" + "StructureDefinition/" + "sequence-phase-relationship")] }) observation_sid.status = "final" observation_sid.category = [ concept.CodeableConcept({ "coding": [{ "system": ("http://terminology.hl7.org/" + "CodeSystem/observation-category"), "code": "laboratory" }] }) ] observation_sid.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "82120-7", "display": "Allelic phase" }] }) observation_sid.subject = patient_reference observation_sid.valueCodeableConcept = concept.CodeableConcept({ "coding": [{ "system": ("http://hl7.org/fhir/uv/" + "genomics-reporting/" + "CodeSystem/seq-phase-relationship"), "code": self.sequence_rels.at[index, 'Relation'], "display": self.sequence_rels.at[index, 'Relation'] }] }) self.report.contained.append(observation_sid)
def initalize_report(self): patient_reference = reference.FHIRReference( {"reference": "Patient/" + self.patientID}) self.report.id = "dr-" + uuid4().hex[:13] self.report.meta = meta.Meta({ "profile": [("http://hl7.org/fhir/uv/genomics-reporting" + "/StructureDefinition/genomics-report")] }) self.report.status = "final" self.report.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "81247-9", "display": "Master HL7 genetic variant reporting panel" }] }) self.report.subject = patient_reference self.report.issued = date.FHIRDate(get_fhir_date()) self.report.contained = []
def status_check( ref ): # fetch resources and check for for slots in bundle check if SLot status == "free" and Appointment is "proposed" if all good then do a PUT transaction with updated status of "pending" TODO update the participant statuses logging.info('starting status_check...') res_json = [] r = requests.get(url='{}/{}'.format(ref_server, ref), headers=f.headers) # fetch appointment appointment = Appt.Appointment(r.json()) logging.info('appt={}\n of type= {} with id ={}'.format( appointment.as_json(), type(appointment), appointment.id)) slots = [] # get the list of slots from the appointment for slot_ref in appointment.slot: logging.info('slot as dict ={}'.format(slot_ref.as_json())) ref = FRef.FHIRReference(slot_ref.as_json()).reference logging.info('ref={}'.format(ref)) r = requests.get(url='{}/{}'.format(ref_server, ref), headers=f.headers) # fetch slot slot = Slot.Slot(r.json()) slots.append(slot) logging.info('slot={}'.format(slots[-1].as_json())) #if hold: ( do this for book too) if appointment.status == 'proposed' and all( slot.status in ['free', 'busy-tentative'] for slot in slots ): # NOTE in brian's server updates automatically upon posting appointments. so assume for now that busy-tentative = free and imagine update statuses busy-tentative logging.info('update statuses...') appointment.status = 'pending' # update statuses appointment.text = None # strip text adn let server update # TODO update actor statuses to 'tentative' for slot in slots: slot.status = "busy-tentative" # **** NOTE *** brian's server updates automatically upon posting appointments. so assume for now that busy-tentative = free update statuses and update to busey - unavailable slot.text = None # strip narrative let server update else: logging.info('hold rejected...') return (False) # hold rejected post_appt([appointment] + slots) return (True) # hold completed
def qr_view(): working_q = '{}_wq'.format(session['form_url']) qr_working_q = cache.get(working_q) reset_q_cache() # results = request.form # this is multiDict structure - can only retreive the first element or use the get list method application.logger.info('results = {}'.format(request.form)) # bp() # ***************** this is a break****************** # split out linkId and text to create answers create a QR resource use a template for the meta for now qr = QR.QuestionnaireResponse(f.qr_templ, strict=False) qr.questionnaire = Ref.FHIRReference({'reference': qr_working_q.url}) # update the questionnaire qr.id = qr_working_q.url.rsplit('/')[-1].replace('questionnaire', 'questionnaireresponse') # update the QR id dt = '{}Z'.format(datetime.utcnow().isoformat()) # == stop time qr.extension = [get_responseperiod_x(session['q_starttime'],dt)] # add extension for FHIRDates start and stoptime qr.authored = FD.FHIRDate(dt) # update datetime # application.logger.info(json.dumps(qr.as_json(), indent=4, sort_keys=True)) qr.item = [] get_qr_items(request.form, qr_working_q.item, qr.item) #application.logger.info(json.dumps(qr.as_json(), indent=4, sort_keys=True)) # ---create narrative--- qr.text.div = '''<div xmlns=\"http://www.w3.org/1999/xhtml\"> <h3>Response Summary</h3> <strong>Questionnaire URL:</strong> {q}<br /> <strong>Date Completed:</strong> {d}<br /> <hr /> {r} <br /><br /> </div>'''.format(q=qr.questionnaire.reference, d=qr.authored.as_json(), r=''.join(session['narr_list'])) #scrub id for user POST and save as session qr qr.identifier.value = qr.id session['qr_id'] = qr.id # this is for saving my examples session['profile'] = qr.meta.profile[0] # this is for uploads if validate by profile # qr.id = None # TODO comment out for user posting to server set_cache(qr.identifier.value, json.dumps(qr.as_json(),indent = 3, sort_keys=True)) # bp() # ***************** this is a break****************** return render_template('qr_view.html', qr=qr, qr_string=cache.get(qr.identifier.value), adaptive=False )
def write(server_url, system, code, patient, value): observation = o.Observation() observation.status = "final" observation.subject = fr.FHIRReference() observation.subject.reference = ("Patient/%s" % patient) observation.code = cc.CodeableConcept() tmp = c.Coding() tmp.system = system tmp.code = code observation.code.coding = [tmp] observation.valueString = str(value) observation.effectiveDateTime = fd.FHIRDate("2017-11-28T00:00:00+00:00") #write json obj json_obj = observation.as_json() json_obj["resourceType"] = "Observation" print(json.dumps(json_obj)) requests.post(server_url + "Observation", json=json_obj)
def disease_to_fhir(obj): """Converts Disease to FHIR Condition. :param obj: Disease json :return: FHIR Condition json """ schema_path = os.path.join(SCHEMA_PATH, 'disease_schema.json') try: validate_schema(schema_path, obj) except jsonschema.exceptions.ValidationError: raise Exception("The disease object is not valid.") condition = cond.Condition() if 'id' in obj: condition.id = str(obj['id']) condition.code = fhir_codeable_concept(obj['term']) # subject is required by Pheno-FHIR mapping Guide and by FHIR, set to 'unknown' condition.subject = fhirreference.FHIRReference() condition.subject.reference = 'unknown' condition.extension = [] # only adds disease-onset if it's ontology term # NOTE it is required element by Phenopackets IG but not Phenopackets # what do to if it's AGE string? if check_disease_onset(obj): onset_extension = extension.Extension() onset_extension.url = PHENOPACKETS_ON_FHIR_MAPPING['disease']['onset'] onset_extension.valueCodeableConcept = fhir_codeable_concept( obj['onset']['age']) condition.extension.append(onset_extension) if 'diseaseStage' in obj: for item in obj['diseaseStage']: disease_stage_extension = extension.Extension() disease_stage_extension.url = PHENOPACKETS_ON_FHIR_MAPPING[ 'disease']['disease_stage'] disease_stage_extension.valueCodeableConcept = fhir_codeable_concept( item) condition.extension.append(disease_stage_extension) return condition.as_json()
def addObservationToServer(self, patient_id, value_code, value_unit, value_quantity, coding_code, coding_display, coding_system, timestamp): observation = o.Observation() # Create Value Quantity quantity = q.Quantity() quantity.code = value_code quantity.unit = value_unit quantity.value = value_quantity observation.valueQuantity = quantity # Create Coding code = cc.CodeableConcept() coding_item = c.Coding() coding_item.code = coding_code coding_item.display = coding_display coding_item.system = coding_system coding_list = [coding_item] code.coding = coding_list observation.code = code # Create Subject reference = r.FHIRReference() reference.reference = self.getPatientById(patient_id).relativePath() observation.subject = reference # Create Status observation.status = 'final' # Create Issued/EffectiveDateTime observation.effectiveDateTime = d.FHIRDate(timestamp) # Write the observation result_json = observation.create(self.smart.server) observation.id = self.getCreatedId(result_json) return observation.id
def _get_section_object(nested_obj, title): """ Internal function to convert phenopacket m2m objects to Composition section. """ section_content = comp.CompositionSection() section_values = PHENOPACKETS_ON_FHIR_MAPPING['phenopacket'][title] section_content.title = section_values['title'] section_content.code = codeableconcept.CodeableConcept() section_content.code.coding = [] coding = c.Coding() coding.system = section_values['code']['system'] coding.version = section_values['code']['version'] coding.code = section_values['code']['code'] coding.display = section_values['code']['display'] section_content.code.coding.append(coding) section_content.entry = [] for item in nested_obj: entry = fhirreference.FHIRReference() if item.get('id'): entry.reference = str(item['id']) else: entry.reference = item['uri'] section_content.entry.append(entry) return section_content
def add_regionstudied_obv(self, ref_seq, reportable_query_regions, nocall_regions): if reportable_query_regions.empty and nocall_regions.empty: return patient_reference = reference.FHIRReference( {"reference": "Patient/" + self.patientID}) contained_uid = "rs-" + uuid4().hex[:13] self.result_ids.append(contained_uid) # Region Studied Obeservation observation_rs = observation.Observation() contained_rs = observation_rs contained_rs.id = contained_uid observation_rs.resource_type = "Observation" contained_rs.meta = meta.Meta({ "profile": [("http://hl7.org/fhir/uv/" + "genomics-reporting/" + "StructureDefinition/region-studied")] }) observation_rs.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "53041-0", "display": "DNA region of interest panel" }] }) observation_rs.status = "final" observation_rs.category = [ concept.CodeableConcept({ "coding": [{ "system": ("http://terminology.hl7.org/" + "CodeSystem/observation-category"), "code": "laboratory" }] }) ] observation_rs.subject = patient_reference observation_rs_component2 = observation.ObservationComponent() observation_rs_component2.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "92822-6", "display": "Genomic coord system" }] }) observation_rs_component2\ .valueCodeableConcept = concept.CodeableConcept( { "coding": [ { "system": "http://loinc.org", "code": "LA30102-0", "display": "1-based character counting" } ] } ) observation_rs_component3 = observation.ObservationComponent() observation_rs_component3.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "48013-7", "display": "Genomic reference sequence ID" }] }) observation_rs_component3\ .valueCodeableConcept = concept.CodeableConcept( { "coding": [ { "system": "http://www.ncbi.nlm.nih.gov/nuccore", "code": ref_seq } ] } ) observation_rs_components = self._get_region_studied_component( reportable_query_regions, nocall_regions) observation_rs.component = [ observation_rs_component2, observation_rs_component3 ] + observation_rs_components # Observation structure : described-variants self.report.contained.append(contained_rs)
def writeLabProfile(labs_counts, labs_frequencyPerYear, labs_fractionOfSubjects,labs_units, labs_names, labs_stats, labs_aboveBelowNorm, labs_correlatedLabsCoefficients, labs_abscorrelation, labs_correlatedMedsCoefficients, labs_correlatedProceduresCoefficients, labs_correlatedDiagnosisCoefficients, labs_correlatedPhenotypesCoefficients, cohort='All', sex='All', race='All', age_low='All', age_high=None, topN=10, correlationCutoff=0.3): """Write out Lab Clinical Profile to JSON File and save locally Keywords: Structures from output of calculateAnyProfile(profileType='labs') cohort -- short name for cohort, special characters besides hyphens are prohibited (default 'All') sex -- specification of whether this is a 'All', 'Male', or 'Female' sex profile (default 'All') race -- specification of whether this is 'All', 'White or Caucasian', 'Black or African American', 'Other' race profile (default 'All') age_low -- low age range for this profile (default 'All') age_high -- high age range for this profile (default None) topN -- integer representing the maximum number of correlations to report in the profile, ranked descending (default 10) correlationCutoff -- minimum correlation coefficient value to report for whole profile (default 0.3) """ import os import sys import sqlalchemy import urllib.parse import pandas as pd import numpy as np import getpass from dataclasses import dataclass from SciServer import Authentication from datetime import datetime import json from fhir_loader import fhir_loader from fhirclient.models import clinicalprofile, fhirreference, identifier, codeableconcept, fhirdate, quantity import pymssql # Initialize profile clinicalProfile = clinicalprofile.ClinicalProfile() clinicalProfile.resourceType = 'ClinicalProfile' if sex == 'M': sex = 'Male' elif sex =='F': sex = 'Female' # Header info if (age_low != 'All'): clinicalProfile.id = 'jh-labs-'+cohort+'-'+sex+'-'+race+'-'+str(int(age_low))+'-'+str(int(age_high)) clinicalProfile.identifier = [identifier.Identifier({'value': 'jh-labs-'+cohort+'-'+sex+'-'+race+'-'+ str(int(age_low))+'-'+str(int(age_high))})] clinicalProfile.cohort = fhirreference.FHIRReference({'reference': 'Group/jh-labs-'+cohort+'-'+sex+'-'+race+'-'+str(int(age_low)) +'-'+str(int(age_high))}) else: clinicalProfile.id = 'jh-labs-'+cohort+'-'+sex+'-'+race+'-'+str(age_low) clinicalProfile.identifier = [identifier.Identifier({'value': 'jh-labs-'+cohort+'-'+sex+'-'+race+'-'+str(age_low)})] clinicalProfile.cohort = fhirreference.FHIRReference({'reference': 'Group/jh-labs-'+cohort+'-'+sex+'-'+race+'-'+str(age_low)}) clinicalProfile.status = 'draft' clinicalProfile.population = fhirreference.FHIRReference({'reference': 'Group/jh-labs-'+cohort}) clinicalProfile.date = fhirdate.FHIRDate(str(datetime.now()).replace(' ', 'T')) clinicalProfile.reporter = fhirreference.FHIRReference({'reference': 'Organization/JHM', 'type': 'Organization', 'display': 'Johns Hopkins School of Medicine'}) ## LABS labs = list() corrmat = (pd.DataFrame(labs_correlatedLabsCoefficients).unstack(level=[0,1]).corr(min_periods=50) .droplevel(level=0).droplevel(level=0,axis=1)) lab_names = pd.DataFrame({'lab_name':labs_names}).reset_index() lab_counts = pd.DataFrame({'lab_counts':labs_counts}).reset_index().rename({'index':'LAB_LOINC'},axis=1) lab_info = lab_names.merge(lab_counts, how='inner', on='LAB_LOINC').set_index('LAB_LOINC') for thisLab in lab_info.index: # Check if STDEV is NaN and skip that lab if so if np.isnan(float(labs_stats.loc[thisLab]['std'].median())): continue # Build the profile thisCPLab = clinicalprofile.ClinicalProfileLab() # try: thisCPLab.code = [codeableconcept.CodeableConcept(dict(coding=[dict(system='http://loinc.org', code=thisLab)], text=lab_info.loc[thisLab]['lab_name'][0]))] thisCPLab.count = int(lab_info.loc[thisLab]['lab_counts']) thisCPLab.frequencyPerYear = round(float(labs_frequencyPerYear.loc[thisLab].mean()),3) thisCPLab.fractionOfSubjects = round(float(labs_fractionOfSubjects.loc[thisLab].mean()),3) thisCPLab.scalarDistribution = clinicalprofile.ClinicalProfileLabScalarDistribution() thisCPLab.scalarDistribution.units = quantity.Quantity(dict(unit=str(labs_units.loc[thisLab][0]))) thisCPLab.scalarDistribution.min = round(float(labs_stats.loc[thisLab]['min'].min()),3) thisCPLab.scalarDistribution.max = round(float(labs_stats.loc[thisLab]['max'].max()),3) thisCPLab.scalarDistribution.mean = round(float(labs_stats.loc[thisLab]['mean'].mean()),3) thisCPLab.scalarDistribution.median = round(float(labs_stats.loc[thisLab]['median'].median()),3) thisCPLab.scalarDistribution.stdDev = round(float(labs_stats.loc[thisLab]['std'].median()),3) deciles = list() for dec in labs_stats.columns[5:]: deciles.append(clinicalprofile.ClinicalProfileLabScalarDistributionDecile( dict(nth=int(dec), value=round(labs_stats.loc[thisLab][dec].mean(),3)))) thisCPLab.scalarDistribution.decile = deciles thisCPLab.scalarDistribution.fractionAboveNormal = round(float(labs_aboveBelowNorm.loc[thisLab].aboveNorm.mean()),3) thisCPLab.scalarDistribution.fractionBelowNormal = round(float(labs_aboveBelowNorm.loc[thisLab].belowNorm.mean()),3) try: yearly_vals = dict() for year in corrmat.loc[thisLab].index: crosstab = corrmat.loc[(thisLab, year)] yearly_vals[year] = (crosstab[crosstab.index.get_level_values(level=1).astype('float') == year] .droplevel(level=1)) topNcorrs = pd.DataFrame(yearly_vals).apply(np.mean, axis=1).drop(thisLab).nlargest(topN).round(3) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherLoinc = [(dict(coding=[dict(system='http://loinc.org', code=code)], text=str(lab_info.loc[code]['lab_name'][0])))] entries.append(dict(labcode=otherLoinc, coefficient=corr)) if not entries: print('No correlated Labs for Lab ', thisLab) else: thisCPLab.scalarDistribution.correlatedLabs = clinicalprofile.ClinicalProfileLabScalarDistributionCorrelatedLabs( dict(topn=topN, entry=entries)) except: print('No correlated Labs for Lab ', thisLab) try: topNcorrs = (pd.DataFrame(labs_correlatedMedsCoefficients.loc[thisLab].groupby(['JH_INGREDIENT_RXNORM_CODE']) .Relative_Counts.mean()) .Relative_Counts.nlargest(topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherRX = [dict(medicationCodeableConcept=dict(coding= [dict(system='http://www.nlm.nih.gov/research/umls/rxnorm/', code=code)]))] entries.append(dict(meds=otherRX, coefficient=corr)) if not entries: print('No correlated Meds for Lab ', thisLab) else: thisCPLab.scalarDistribution.correlatedMedications = clinicalprofile.\ ClinicalProfileLabScalarDistributionCorrelatedMedications( dict(topn=topN, entry=entries)) except: print('No correlated Meds for Lab ', thisLab) try: topNcorrs = (pd.DataFrame(labs_correlatedDiagnosisCoefficients.loc[thisLab].groupby(['DX']) .Relative_Counts.mean()) .Relative_Counts.nlargest(topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherDX = (dict(coding=[dict(system='http://www.icd10data.com/', code=code)])) entries.append(dict(code=otherDX, coefficient=corr)) if not entries: print('No correlated Diagnoses for Lab ', thisLab) else: thisCPLab.scalarDistribution.correlatedDiagnoses = clinicalprofile.\ ClinicalProfileLabScalarDistributionCorrelatedDiagnoses( dict(topn=topN, entry=entries)) except: print('No correlated Diagnoses for Lab ', thisLab) try: topNcorrs = (pd.DataFrame(labs_correlatedProceduresCoefficients.loc[thisLab].groupby(['RAW_PX']) .Relative_Counts.mean()) .Relative_Counts.nlargest(topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherProc = [(dict(coding=[dict(system='http://www.ama-assn.org/practice-management/cpt', code=code)]))] entries.append(dict(code=otherProc, coefficient=corr)) if not entries: print('No correlated Procedures for Lab ', thisLab) else: thisCPLab.scalarDistribution.correlatedProcedures = clinicalprofile.\ ClinicalProfileLabScalarDistributionCorrelatedProcedures( dict(topn=topN, entry=entries)) except: print('No correlated Procedures for Lab ', thisLab) try: topNcorrs = (pd.DataFrame(labs_correlatedPhenotypesCoefficients.loc[thisLab].groupby(['HPO']) .Relative_Counts.mean()) .Relative_Counts.nlargest(topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherHPO = (dict(coding=[dict(system='http://hpo.jax.org/app/', code=code)])) entries.append(dict(code=otherHPO, coefficient=corr)) if not entries: print('No correlated Phenotypes for Lab ', thisLab) else: thisCPLab.scalarDistribution.correlatedPhenotypes = clinicalprofile.\ ClinicalProfileLabScalarDistributionCorrelatedPhenotypes( dict(topn=topN, entry=entries)) except: print('No correlated Phenotypes for Lab ', thisLab) labs.append(thisCPLab) # except: # print('This lab did not work ', thisLab) clinicalProfile.lab = labs if age_high != None: filename = cohort+'_resources/jh-labs-'+cohort+'-'+sex+'-'+race+'-'+str(int(age_low))+'-'+str(int(age_high))+'.json' else: filename = cohort+'_resources/jh-labs-'+cohort+'-'+sex+'-'+race+'-'+str(age_low)+'.json' with open(filename, 'w') as outfile: json.dump(clinicalProfile.as_json(), outfile, indent=4) del(clinicalProfile) return print('Write to '+ filename + ' successful')
def getEmptyFhirJSON(patientID, start, end, refSeq, nocall=False): logging.info("[FHIR: Converting XML to JSON]") noCallRegion, queryRange = getNoCallableData(NO_CALL_FILE, QUERY_RANGE_FILE) nocallRows = len(noCallRegion.index) start = queryRange.at[0, "START"] end = queryRange.at[0, "END"] if not noCallRegion.empty: if noCallRegion['START'].iloc[0] <= queryRange['START'].iloc[0]: noCallRegion['START'].iloc[0] = queryRange['START'].iloc[0] if noCallRegion['END'].iloc[-1] >= queryRange['END'].iloc[0]: noCallRegion['END'].iloc[-1] = queryRange['END'].iloc[0] else: nocall = False contained_uid = uuid4().hex[:13] patient_reference = reference.FHIRReference( {"reference": "Patient/" + patientID}) variant_reference = reference.FHIRReference( {"reference": "#rs-" + contained_uid}) report = dr.DiagnosticReport() report.id = "dr-" + uuid4().hex[:13] report.meta = meta.Meta({ "profile": [ "http://hl7.org/fhir/uv/genomics-reporting/StructureDefinition/diagnosticreport" ] }) report.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "53041-0", "display": "DNA region of interest panel" }] }) report.status = "final" report.subject = patient_reference report.issued = date.FHIRDate(Utilities.getFhirDate()) report.result = [variant_reference] observation_rs = observation.Observation() contained_rs = observation_rs observation_dv = observation.Observation() contained_dv = observation_dv observation_sid = observation.Observation() contained_sid = observation_sid contained_rs.id = "rs-" + contained_uid observation_rs.resource_type = "Observation" contained_rs.meta = meta.Meta({ "profile": [ "http://hl7.org/fhir/uv/genomics-reporting/StructureDefinition/obs-region-studied" ] }) observation_rs.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "53041-0", "display": "DNA region of interest panel" }] }) observation_rs.status = "final" observation_rs.category = [ concept.CodeableConcept({ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "laboratory" }] }) ] observation_rs.subject = patient_reference observation_rs_component1 = observation.ObservationComponent() observation_rs_component1.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "51959-5", "display": "Range(s) of DNA sequence examined" }] }) observation_rs_component1.valueRange = valRange.Range({ "low": { "value": int(start) }, "high": { "value": int(end) } }) observation_rs_component2 = observation.ObservationComponent() observation_rs_component2.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "tbd-coordinate system", "display": "Genomic coordinate system" }] }) observation_rs_component2.valueCodeableConcept = concept.CodeableConcept({ "coding": [{ "system": "http://hl7.org/fhir/uv/genomics-reporting/CodeSystem/genetic-coordinate-system", "code": "1" }] }) observation_rs_component3 = observation.ObservationComponent() observation_rs_component3.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "48013-7", "display": "Genomic reference sequence ID" }] }) observation_rs_component3.valueCodeableConcept = concept.CodeableConcept({ "coding": [{ "system": "http://www.ncbi.nlm.nih.gov/nuccore", "code": refSeq }] }) if nocall: #component Region-studied (No call region) nocallComponents = [] for i in range(nocallRows): nocallComponents.append('observation_rs_component' + str(i + 4)) observation_rs_components = [] for (index, i) in zip(noCallRegion.index, nocallComponents): i = observation.ObservationComponent() i.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "TBD-noCallRegion", "display": "No call region" }] }) observation_rs_components.append(i) if nocall: observation_rs.component = [ observation_rs_component2, observation_rs_component3 ] + observation_rs_components else: observation_rs.component = [ observation_rs_component2, observation_rs_component3 ] response = report.as_json() od = OrderedDict() od["resourceType"] = response['resourceType'] od["id"] = response['id'] od["meta"] = response['meta'] od["contained"] = response['contained'] od["status"] = response['status'] od["code"] = response['code'] od["subject"] = response['subject'] od["issued"] = response['issued'] od["result"] = response['result'] with open(FHIR_JSON_RESULT + 'fhir.json', 'w') as fp: json.dump(od, fp, indent=4) return FHIR_JSON_RESULT
def add_variant_obv(self, record, ref_seq, ratio_ad_dp): # collect all the record with similar position values, # to utilized later in phased sequence relationship self._add_phase_records(record) patient_reference = reference.FHIRReference( {"reference": "Patient/" + self.patientID}) alleles = get_allelic_state(record, ratio_ad_dp) dvuid = "dv-" + uuid4().hex[:13] self.fhir_report.update({str(record.POS): dvuid}) self.result_ids.append(dvuid) observation_dv = observation.Observation() observation_dv.resource_type = "Observation" observation_dv.id = dvuid observation_dv.meta = meta.Meta({ "profile": [("http://hl7.org/fhir/uv/" + "genomics-reporting/StructureDefinition/variant")] }) observation_dv.status = "final" observation_dv.category = [ concept.CodeableConcept({ "coding": [{ "system": ("http://terminology.hl7.org/" + "CodeSystem/observation-category"), "code": "laboratory" }] }) ] observation_dv.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "69548-6", "display": "Genetic variant assessment" }] }) observation_dv.subject = patient_reference observation_dv.valueCodeableConcept = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "LA9633-4", "display": "present" }] }) observation_dv.component = [] observation_dv_component1 = observation.ObservationComponent() observation_dv_component1.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "62374-4", "display": "Human reference sequence assembly version" }] }) observation_dv_component1\ .valueCodeableConcept = concept.CodeableConcept( { "coding": [ { "system": "http://loinc.org", "code": "LA14029-5", "display": "GRCh37" } ] } ) observation_dv.component.append(observation_dv_component1) observation_dv_component2 = observation.ObservationComponent() observation_dv_component2.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "48013-7", "display": "Genomic reference sequence ID" }] }) observation_dv_component2\ .valueCodeableConcept = concept.CodeableConcept( { "coding": [ { "system": "http://www.ncbi.nlm.nih.gov/nuccore", "code": ref_seq } ] } ) observation_dv.component.append(observation_dv_component2) if alleles['CODE'] != "" or alleles['ALLELE'] != "": observation_dv_component3 = observation.ObservationComponent() observation_dv_component3.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "53034-5", "display": "Allelic state" }] }) observation_dv_component3\ .valueCodeableConcept = concept.CodeableConcept( { "coding": [ { "system": "http://loinc.org", "code": alleles['CODE'], "display": alleles['ALLELE'] } ] } ) observation_dv.component.append(observation_dv_component3) observation_dv_component4 = observation.ObservationComponent() observation_dv_component4.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "69547-8", "display": "Genomic Ref allele [ID]" }] }) observation_dv_component4.valueString = record.REF observation_dv.component.append(observation_dv_component4) observation_dv_component5 = observation.ObservationComponent() observation_dv_component5.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "69551-0", "display": "Genomic Alt allele [ID]" }] }) observation_dv_component5.valueString = record.ALT[0].sequence observation_dv.component.append(observation_dv_component5) observation_dv_component6 = observation.ObservationComponent() observation_dv_component6.code = concept.CodeableConcept({ "coding": [{ "system": "http://loinc.org", "code": "92822-6", "display": "Genomic coord system" }] }) observation_dv_component6\ .valueCodeableConcept = concept.CodeableConcept( { "coding": [ { "system": "http://loinc.org", "code": "LA30102-0", "display": "1-based character counting" } ] } ) observation_dv.component.append(observation_dv_component6) observation_dv_component7 = observation.ObservationComponent() observation_dv_component7.code = concept.CodeableConcept({ "coding": [{ "system": ("http://hl7.org/fhir/uv/" + "genomics-reporting/CodeSystem/tbd-codes"), "code": "exact-start-end", "display": "Variant exact start and end" }] }) observation_dv_component7.valueRange = valRange.Range( {"low": { "value": int(record.POS) }}) observation_dv.component.append(observation_dv_component7) self.report.contained.append(observation_dv)
def device(self): return ref.FHIRReference({"reference": "DeviceMetric/manual"})
def performer(self): return [ref.FHIRReference({"reference": "Practitioner/{}".format(self.n_id)})]
def subject(self): return ref.FHIRReference({"reference": "Patient/{}".format(self.p_id)})
def add_report_result(self): report_result = [] for uid in self.result_ids: report_result.append( reference.FHIRReference({"reference": f"#{uid}"})) self.report.result = report_result
def writeMedProfile(meds_medication, meds_frequencyPerYear, meds_fractionOfSubjects, meds_correlatedLabsCoefficients, meds_correlatedMedsCoefficients, meds_correlatedProceduresCoefficients, meds_correlatedDiagnosisCoefficients, meds_correlatedPhenotypesCoefficients, cohort='All', sex='All', race='All', age_low='All', age_high=None, topN=10, correlationCutoff=0.3): """Write out Medication Clinical Profile to JSON File and save locally Keywords: Structures from output of calculateAnyProfile(profileType='medications') cohort -- short name for cohort, special characters besides hyphens are prohibited (default 'All') sex -- specification of whether this is a 'All', 'Male', or 'Female' sex profile (default 'All') race -- specification of whether this is 'All', 'White or Caucasian', 'Black or African American', 'Other' race profile (default 'All') age_low -- low age range for this profile (default 'All') age_high -- high age range for this profile (default None) topN -- integer representing the maximum number of correlations to report in the profile, ranked descending (default 10) correlationCutoff -- minimum correlation coefficient value to report for whole profile (default 0.3) """ import os import sys import sqlalchemy import urllib.parse import pandas as pd import numpy as np import getpass from dataclasses import dataclass from SciServer import Authentication from fhirclient.models import clinicalprofile, fhirreference, identifier, codeableconcept, fhirdate, quantity from datetime import datetime import json from fhir_loader import fhir_loader import pymssql # Initialize profile clinicalProfile = clinicalprofile.ClinicalProfile() if sex == 'M': sex = 'Male' elif sex == 'F': sex = 'Female' # Header info if (age_low != 'All'): clinicalProfile.id = ('jh-medications-' + cohort + '-' + sex + '-' + race + '-' + str(int(age_low)) + '-' + str(int(age_high))) clinicalProfile.identifier = [ identifier.Identifier({ 'value': ('jh-medications-' + cohort + '-' + sex + '-' + race + '-' + str(int(age_low)) + '-' + str(int(age_high))) }) ] clinicalProfile.cohort = fhirreference.FHIRReference({ 'reference': ('Group/jh-medications-' + cohort + '-' + sex + '-' + race + '-' + str(int(age_low)) + '-' + str(int(age_high))) }) else: clinicalProfile.id = 'jh-medications-' + cohort + '-' + sex + '-' + race + '-' + str( age_low) clinicalProfile.identifier = [ identifier.Identifier({ 'value': 'jh-medications-' + cohort + '-' + sex + '-' + race + '-' + str(age_low) }) ] clinicalProfile.cohort = fhirreference.FHIRReference({ 'reference': ('Group/jh-medications-' + cohort + '-' + sex + '-' + race + '-' + str(age_low)) }) clinicalProfile.status = 'draft' clinicalProfile.population = fhirreference.FHIRReference( {'reference': 'Group/jh-medications-' + cohort}) clinicalProfile.date = fhirdate.FHIRDate( str(datetime.now()).replace(' ', 'T')) clinicalProfile.reporter = fhirreference.FHIRReference({ 'reference': 'Organization/JHM', 'type': 'Organization', 'display': 'Johns Hopkins School of Medicine' }) meds = list() meds_medication = [x for x in meds_medication if str(x) != 'nan'] for thisMed in meds_medication: thisCPMed = clinicalprofile.ClinicalProfileMedication() try: thisCPMed.medicationCodeableConcept = codeableconcept.CodeableConcept( dict(coding=[ dict(system='http://www.nlm.nih.gov/research/umls/rxnorm/', code=str(thisMed)) ])) # meds_dosageInfo # thisCPMed.dose = quantity.Quantity(dict(unit=str(meds_dosageInfo.loc[thisMed]))) thisCPMed.frequencyPerYear = round( float(meds_frequencyPerYear.loc[thisMed].mean()), 3) thisCPMed.fractionOfSubjects = round( float(meds_fractionOfSubjects.loc[thisMed].mean()), 3) try: topNcorrs = (pd.DataFrame( meds_correlatedLabsCoefficients.loc[thisMed].groupby([ 'LAB_LOINC' ]).Relative_Counts.mean()).Relative_Counts.nlargest( topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherLab = [(dict( coding=[dict(system='http://loinc.org', code=code)]))] entries.append(dict(labcode=otherLab, coefficient=corr)) if not entries: print('No correlated Labs for Med ', thisMed) else: thisCPMed.correlatedLabs = clinicalprofile.\ ClinicalProfileLabScalarDistributionCorrelatedLabs(dict(topn=topN, entry=entries)) except: print('No correlated Labs for Med ', thisMed) try: topNcorrs = (pd.DataFrame( meds_correlatedDiagnosisCoefficients.loc[thisMed].groupby([ 'DX' ]).Relative_Counts.mean()).Relative_Counts.nlargest( topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherDX = (dict(coding=[ dict(system='http://www.icd10data.com/', code=code) ])) entries.append(dict(code=otherDX, coefficient=corr)) if not entries: print('No correlated Diagnoses for Med ', thisMed) else: thisCPMed.correlatedDiagnoses = clinicalprofile.ClinicalProfileLabScalarDistributionCorrelatedDiagnoses( dict(topn=topN, entry=entries)) except: print('No correlated DX for Med ', thisMed) try: topNcorrs = (pd.DataFrame( meds_correlatedProceduresCoefficients.loc[thisMed].groupby( ['RAW_PX' ]).Relative_Counts.mean()).Relative_Counts.nlargest( topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherProc = [(dict(coding=[ dict(system= 'http://www.ama-assn.org/practice-management/cpt', code=code) ]))] entries.append(dict(code=otherProc, coefficient=corr)) if not entries: print('No correlated Procedures for Med ', thisMed) else: thisCPMed.correlatedProcedures = clinicalprofile.ClinicalProfileLabScalarDistributionCorrelatedProcedures( dict(topn=topN, entry=entries)) except: print('No correlated Procedures for Med ', thisMed) try: topNcorrs = (pd.DataFrame( meds_correlatedMedsCoefficients.loc[thisMed].groupby([ 'JH_INGREDIENT_RXNORM_CODE' ]).Relative_Counts.mean()).Relative_Counts.nlargest( topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherMed = [ dict(medicationCodeableConcept=dict(coding=[ dict( system= 'http://www.nlm.nih.gov/research/umls/rxnorm/', code=code) ])) ] entries.append(dict(meds=otherMed, coefficient=corr)) if not entries: print('No correlated Meds for Med ', thisMed) else: thisCPMed.correlatedMedications = clinicalprofile.ClinicalProfileLabScalarDistributionCorrelatedMedications( dict(topn=topN, entry=entries)) except: print('No correlated Meds for Med ', thisMed) try: topNcorrs = (pd.DataFrame( meds_correlatedPhenotypesCoefficients.loc[thisMed].groupby( ['HPO' ]).Relative_Counts.mean()).Relative_Counts.nlargest( topN).round(3)) entries = list() for code, corr in topNcorrs.iteritems(): if corr <= correlationCutoff: continue otherHPO = (dict(coding=[ dict(system='http://hpo.jax.org/app/', code=code) ])) entries.append(dict(code=otherHPO, coefficient=corr)) if not entries: print('No correlated Phenotypes for Med ', thisMed) else: thisCPMed.correlatedPhenotypes = clinicalprofile.ClinicalProfileLabScalarDistributionCorrelatedPhenotypes( dict(topn=topN, entry=entries)) except: print('No correlated Phenotypes for Med ', thisMed) meds.append(thisCPMed) except Exception as e: print(e) print('This med did not work ', thisMed) clinicalProfile.medication = meds if age_high != None: filename = cohort + '_resources/jh-medications-' + cohort + '-' + sex + '-' + race + '-' + str( int(age_low)) + '-' + str(int(age_high)) + '.json' else: filename = cohort + '_resources/jh-medications-' + cohort + '-' + sex + '-' + race + '-' + str( age_low) + '.json' with open(filename, 'w') as outfile: json.dump(clinicalProfile.as_json(), outfile, indent=4) del (clinicalProfile) return print('Write to ' + filename + ' successful')
def fhir_observation(obj): """ Converts phenotypic feature to FHIR Observation. """ observation = obs.Observation() if 'description' in obj.keys(): observation.note = [] annotation = a.Annotation() annotation.text = obj.get('description', None) observation.note.append(annotation) observation.code = fhir_codeable_concept(obj['type']) # required by FHIR specs but omitted by phenopackets, for now set for unknown observation.status = 'unknown' if 'negated' in obj.keys(): observation.interpretation = fhir_codeable_concept({ "label": "Positive", "id": "POS" }) else: observation.interpretation = fhir_codeable_concept({ "label": "Negative", "id": "NEG" }) observation.extension = [] concept_extensions = codeable_concepts_fields( ['severity', 'modifier', 'onset'], 'phenotypic_feature', obj) for c in concept_extensions: observation.extension.append(c) if 'evidence' in obj.keys(): evidence = extension.Extension() evidence.url = PHENOPACKETS_ON_FHIR_MAPPING['phenotypic_feature'][ 'evidence']['url'] evidence.extension = [] evidence_code = extension.Extension() evidence_code.url = PHENOPACKETS_ON_FHIR_MAPPING['phenotypic_feature'][ 'evidence']['evidence_code'] evidence_code.valueCodeableConcept = fhir_codeable_concept( obj['evidence']['evidence_code']) evidence.extension.append(evidence_code) if 'reference' in obj['evidence'].keys(): evidence_reference = extension.Extension() evidence_reference.url = PHENOPACKETS_ON_FHIR_MAPPING[ 'external_reference']['url'] evidence_reference.extension = [] evidence_reference_id = extension.Extension() evidence_reference_id.url = PHENOPACKETS_ON_FHIR_MAPPING[ 'external_reference']['id_url'] # GA$GH guide requires valueURL but there is no such property evidence_reference_id.valueUri = obj['evidence']['reference']['id'] evidence_reference.extension.append(evidence_reference_id) if 'description' in obj['evidence']['reference'].keys(): evidence_reference_desc = extension.Extension() evidence_reference_desc.url = PHENOPACKETS_ON_FHIR_MAPPING[ 'external_reference']['description_url'] evidence_reference_desc.valueString = obj['evidence'][ 'reference'].get('description', None) evidence_reference.extension.append(evidence_reference_desc) evidence.extension.append(evidence_reference) observation.extension.append(evidence) if 'biosample' in obj.keys(): observation.specimen = fhirreference.FHIRReference() observation.specimen.reference = obj.get('biosample', None) return observation.as_json()