def build_identifiers(nct_id, study_id, secondary_ids): """ Construct the identifiers :param id_info: :return: """ ident = [ identifier.Identifier(dict(use="usual", value=study_id)), identifier.Identifier( dict(use="official", value=nct_id, system="https://clinicaltrials.gov/ct2/show/")) ] for _id in secondary_ids: ident.append(dict(use='secondary', value=_id)) return ident
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 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')
limit = 100 for index, row in itertools.islice(df_a.iterrows(), limit): # for index, row in df_a.iterrows(): patient = p.Patient() # not using rec_id as pandas id, leaving empty patient.gender = row['sex'] name = hn.HumanName() name.given = [row['given_name']] name.family = row['surname'] name.use = 'official' patient.name = [name] phone = cp.ContactPoint() phone.system = 'phone' phone.value = row['phone_number'] patient.telecom = [phone] patient.birthDate = fd.FHIRDate(row['date_of_birth']) emr = ident.Identifier() emr.system = 'http://clientregistry.org/openmrs' emr.value = row['rec_id'] art = ident.Identifier() art.system = 'http://system1/artnumber' art.value = row['art_number'] nin = ident.Identifier() nin.system = 'http://system1/nationalid' nin.value = row['uganda_nin'] patient.identifier = [emr, art, nin] # print(json.dumps(patient.as_json())) headers = {'Content-Type': 'application/json'} start = time.time() response = post(server, headers=headers,
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 identifier(self): return idn.Identifier({ "use": "official", "system": "http://hl7.org/fhir/sid/us-ssn", "value": "xxxxx" })
return 'draft' if __name__ == "__main__": ct = ClinicalStudy.from_file("examples/NCT02348489.xml", local_schema=True) locations = [build_location(x) for x in ct.locations] foci = build_focus(ct.mesh_terms) print([x.as_json() for x in foci]) keywords = build_keyword(ct.keywords) print([x.as_json() for x in keywords]) identifiers = build_identifiers(ct.nct_id, ct.study_id, ct.secondary_id) print([x.as_json() for x in identifiers]) package = bundle.Bundle() package.type = "document" package.identifier = identifier.Identifier( dict(use='official', system="https://clinicaltrials.gov/ct2/show/", value=ct.nct_id)) entries = [] for location in locations: be = bundle.BundleEntry() be.resource_type = "Location" be.resource = location entries.append(be) study = researchstudy.ResearchStudy() study.identifier = identifiers print("Study Identifier: ", type(study.identifier[0])) study.period = period.Period( dict(start=ct.trail.study_first_posted.date.strftime("%Y-%m-%d"))) study.status = build_status(ct.status) entries.append(study) package.entry = entries
def create_fhir_object(self): """ Generate a fhirclient.Patient class object and store in the protected attribute _fhir :return: None """ # Patient object must be persistent to generate FHIR attributes ins = inspect(self) if ins.persistent: # Initialize Patient resource fhir_pt = fhir_patient.Patient() # Set resource logical identifier fhir_pt.id = self.get_url() # Build and assign Meta resource for Patient object fhir_meta = meta.Meta() fhir_meta.lastUpdated = fhir_gen_datetime(value=self.updated_at, error_out=False, to_date=False) fhir_meta.versionId = str(self.version_number) fhir_meta.profile = ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient'] fhir_pt.meta = fhir_meta # Patient name represented as HumanName resource fhir_pt.name = [] fhir_pt.name.append(fhir_gen_humanname(use='usual', first_name=self.first_name, last_name=self.last_name, middle_name=self.middle_name, suffix=self.suffix, prefix=self.prefix)) # Display MRN as identifier codeable concept = Patient.identifier.codeableconcept.coding # Initialize Identifier resource id_mrn = identifier.Identifier() id_mrn.use = 'usual' id_mrn.system = 'http://unkani.com' id_mrn.value = str(self.uuid) # Initialize CodeableConcept resource mrn_cc = codeableconcept.CodeableConcept() mrn_cc.text = 'Medical Record Number' # Initialize Coding resource mrn_coding = coding.Coding() mrn_coding.system = 'http://hl7.org/fhir/v2/0203' mrn_coding.code = 'MR' mrn_coding.display = 'Medical Record Number' # Assign Coding resource to CodeableConcept mrn_cc.coding = [mrn_coding] # Assign CodeableConcept to Identifier id_mrn.type = mrn_cc # Assign CodeableConcept to Patient fhir_pt.identifier = [id_mrn] # Display SSN as identifier codeable concept = Patient.identifier.codeableconcept.coding if self.ssn: # Initialize Identifier resource id_ssn = identifier.Identifier() id_ssn.use = 'usual' id_ssn.system = 'http://hl7.org/fhir/sid/us-ssn' id_ssn.value = self.ssn # Initialize CodeableConcept resource ssn_cc = codeableconcept.CodeableConcept() ssn_cc.text = 'Social Security Number' # Initialize Coding resource ssn_coding = coding.Coding() ssn_coding.system = 'http://hl7.org/fhir/v2/0203' ssn_coding.code = 'SS' ssn_coding.display = 'Social Security Number' # Assign Coding resource to CodeableConcept ssn_cc.coding = [ssn_coding] # Assign CodeableConcept to Identifier id_ssn.type = ssn_cc # Assign CodeableConcept to Patient fhir_pt.identifier.append(id_ssn) if self.marital_status: marital_status_cc = codeableconcept.CodeableConcept() marital_status_url = 'http://hl7.org/fhir/ValueSet/marital-status' marital_status_concept = ValueSet.get_valueset_concept(marital_status_url, self.marital_status) if marital_status_concept: marital_status_cc.text = getattr(marital_status_concept, 'display') marital_status_coding = coding.Coding() marital_status_coding.code = self.marital_status marital_status_coding.system = marital_status_url marital_status_coding.display = marital_status_cc.text marital_status_cc.coding = [marital_status_coding] fhir_pt.maritalStatus = marital_status_cc if self.race: ext_race = extension.Extension() ext_race.url = 'http://hl7.org/fhir/StructureDefinition/us-core-race' race_url = 'http://hl7.org/fhir/us/core/ValueSet/omb-race-category' cc_race = codeableconcept.CodeableConcept() race_concept = ValueSet.get_valueset_concept(race_url, self.race) if race_concept: cc_race.text = getattr(race_concept, 'display') coding_race = coding.Coding() coding_race.system = race_url coding_race.code = self.race coding_race.display = cc_race.text cc_race.coding = [coding_race] ext_race.valueCodeableConcept = cc_race try: fhir_pt.extension.append(ext_race) except AttributeError: fhir_pt.extension = [ext_race] if self.ethnicity: ext_ethnicity = extension.Extension() ext_ethnicity.url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity' cc_ethnicity = codeableconcept.CodeableConcept() cc_ethnicity.text = ethnicity_dict.get(self.ethnicity)[0].capitalize() coding_ethnicity = coding.Coding() coding_ethnicity.system = 'http://hl7.org/fhir/us/core/ValueSet/omb-ethnicity-category' coding_ethnicity.code = self.race coding_ethnicity.display = cc_ethnicity.text cc_ethnicity.coding = [coding_ethnicity] ext_ethnicity.valueCodeableConcept = cc_ethnicity try: fhir_pt.extension.append(ext_ethnicity) except AttributeError: fhir_pt.extension = [ext_ethnicity] if self.sex: sex_dict = {"administrativeGender": {"M": "male", "F": "female", "u": "unknown", "o": "other"}, "usCoreBirthSex": {"M": "M", "F": "F", "U": "UNK", "O": "UNK"}} fhir_pt.gender = sex_dict['administrativeGender'][str(self.sex).upper()] ext_birth_sex = extension.Extension() ext_birth_sex.url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex' ext_birth_sex.valueCode = sex_dict['usCoreBirthSex'][str(self.sex).upper()] try: fhir_pt.extension.append(ext_birth_sex) except AttributeError: fhir_pt.extension = [ext_birth_sex] if self.dob: fhir_pt.birthDate = fhir_gen_datetime(value=self.dob, to_date=True) fhir_pt.active = self.active fhir_pt.deceasedBoolean = self.deceased if self.deceased_date: fhir_pt.deceasedDateTime = fhir_gen_datetime(value=self.deceased_date, to_date=False) if self.preferred_language: fhir_comm = fhir_patient.PatientCommunication() fhir_comm.preferred = True fhir_lang_cc = codeableconcept.CodeableConcept() fhir_lang_coding = coding.Coding() fhir_lang_coding.code = self.preferred_language fhir_lang_url = 'http://hl7.org/fhir/ValueSet/languages' fhir_lang_coding.system = fhir_lang_url fhir_lang_concept = ValueSet.get_valueset_concept(fhir_lang_url, self.preferred_language) if fhir_lang_concept: fhir_lang_coding.display = fhir_lang_concept.display fhir_lang_cc.text = fhir_lang_coding.display fhir_lang_cc.coding = [fhir_lang_coding] fhir_comm.language = fhir_lang_cc fhir_pt.communication = [fhir_comm] contact_point_list = [] phone_list = self.phone_numbers.all() if phone_list: for ph in phone_list: contact_point_list.append(ph.fhir) email_list = self.email_addresses.all() if email_list: for em in email_list: contact_point_list.append(em.fhir) if contact_point_list: fhir_pt.telecom = contact_point_list address_list = self.addresses.all() if address_list: fhir_pt.address = [] for addr in address_list: fhir_pt.address.append(addr.fhir) xhtml = render_template('fhir/patient.html', fhir_patient=fhir_pt, patient=self) fhir_pt.text = narrative.Narrative() fhir_pt.text.status = 'generated' fhir_pt.text.div = xhtml self._fhir = fhir_pt
def createPatient(dohmpifield, record): #extract fields from dohmpi from database field = [] for i in range(len(dohmpifield)): f1, = dohmpifield[i] # dohmpi loads from db as a list of onetuples. field.append(f1) # we make a traditional list to refer to. fnamei = field.index('provider_first') lnamei = field.index('provider_last') genderi = field.index('provider_gender_cd') deathyi = field.index('deathccyy') deathmi = field.index('deathmm') deathdi = field.index('deathdd') birthi = field.index('provider_dob_dob') provi = field.index('provider_license_no') # record is one record from the postgres db import fhirclient.models.patient as p # set patient id as provider licence numberS pid = record[provi] p = p.Patient({}) import fhirclient.models.identifier as idf identifier = idf.Identifier() identifier.value = pid p.identifier = [identifier] # resolve name import fhirclient.models.humanname as hn name = hn.HumanName() name.given = [record[fnamei]] name.family = [record[lnamei]] p.name = [name] #[name.family, name.given] # resolve gender if (record[genderi] == "1"): p.gender = 'male' elif (record[genderi] == "2"): p.gender = 'female' else: p.gender = 'unknown' # build and resolve birthdate birthdate = record[birthi] bsep1 = birthdate.index("/") bsep2 = birthdate.index("/", bsep1 + 1) year = birthdate[-4:] month = birthdate[0:bsep1] if (len(month) < 2): month = "0%s" % month date = birthdate[bsep1 + 1:bsep2] if (len(date) < 2): date = "0%s" % date birthdate = year + "-" + month + "-" + date p.birthDate = fhirclient.models.fhirdate.FHIRDate(birthdate) # build and resolve death date tt = "12:00:00" #Setting time to noon yyyy = record[deathyi] mm = record[deathmi] if (len(mm) < 2): mm = "0%s" % mm dd = record[deathdi] if (len(dd) < 2): dd = "0%s" % dd deathdate = "%s-%s-%sT%s" % (yyyy, mm, dd, tt) deathdate = fhirclient.models.fhirdate.FHIRDate(deathdate) # Create period import fhirclient.models.period as per per = per.Period() per.start = deathdate p.deceasedBoolean = True p.deceasedDateTime = deathdate return p
def biosample_to_fhir(obj): """Converts Biosample to FHIR Specimen. :param obj: Biosample json :return: FHIR Specimen json """ schema_path = os.path.join(SCHEMA_PATH, 'biosample_schema.json') try: validate_schema(schema_path, obj) except jsonschema.exceptions.ValidationError: raise Exception("The biosample object is not valid.") 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['sampledTissue']['id'] coding.display = obj['sampledTissue']['label'] specimen.type.coding.append(coding) # description if 'description' in obj: 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 'bodySite' in obj['procedure']: specimen.collection.bodySite = fhir_codeable_concept( obj['procedure']['bodySite']) # 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 'individualAgeAtCollection' in obj: ind_age_at_collection_extension = age_to_fhir( obj, PHENOPACKETS_ON_FHIR_MAPPING['biosample'] ['individualAgeAtCollection'], 'individualAgeAtCollection') specimen.extension.append(ind_age_at_collection_extension) concept_extensions = codeable_concepts_fields([ 'histologicalDiagnosis', 'tumorProgression', 'tumorGrade', 'diagnosticMarkers' ], 'biosample', obj) for concept in concept_extensions: specimen.extension.append(concept) if 'isControlSample' in obj: control_extension = extension.Extension() control_extension.url = PHENOPACKETS_ON_FHIR_MAPPING['biosample'][ 'isControlSample'] control_extension.valueBoolean = obj['isControlSample'] specimen.extension.append(control_extension) # TODO 2m extensions - references return specimen.as_json()