Spaces:
Build error
Build error
| import streamlit as st | |
| import streamlit.components as components | |
| from annotated_text import annotated_text, annotation | |
| from htbuilder import h3 | |
| import pandas as pd | |
| import numpy as np | |
| from math import ceil | |
| from collections import Counter | |
| from string import punctuation | |
| import spacy | |
| from negspacy.negation import Negex | |
| from spacy import displacy | |
| from spacy.lang.en import English | |
| from spacy.matcher import PhraseMatcher | |
| from spacy.tokens import Span | |
| #import en_ner_bc5cdr_md | |
| import re | |
| from streamlit.components.v1 import html | |
| import pickle | |
| from functools import reduce | |
| import operator | |
| import itertools | |
| from itertools import chain | |
| from collections import Counter | |
| from collections import OrderedDict | |
| ### ========== Loading Dataset ========== | |
| ## ======== Loading dataset ======== | |
| ## Loading in Admission Dataset | |
| ## df = Admission | |
| ## df2 = Admission Chief Complaint and Diagnosis | |
| ## df3 = Discharge History | |
| ## df4 = Daily Narrative | |
| # #================================= | |
| nlp = spacy.load("en_ner_bc5cdr_md") | |
| df = pd.read_csv('shpi25nov.csv') | |
| df.sort_values(by='SUBJECT_ID',ascending = True, inplace=True) | |
| df2 = pd.read_csv('cohort_cc_adm_diag.csv') | |
| df3 = pd.read_csv('cohort_past_history_12072022.csv') | |
| df3.sort_values(by='CHARTDATE',ascending = False, inplace=True) | |
| df4 = pd.read_csv('24houreventsFulltextwdifference.csv') | |
| #df4.sort_values(by=['hadmid','DATETIME'],ascending = True, inplace=True) | |
| # Loading in Daily Narrative - refreshed full 24 hr text | |
| df5 = pd.read_csv('24hourevents10Jan.csv') | |
| df5.sort_values(by=['hadmid','DATETIME'],ascending = True, inplace=True) | |
| #Append the updated 24 hr text and changes column | |
| df5.rename(columns={'hadmid':'HADM_ID', | |
| 'DATETIME':'STORETIME'}, inplace = True) | |
| df4 = pd.merge(df4[['HADM_ID','DESCRIPTION','SUBJECT_ID','CHARTTIME','STORETIME','CGID','TEXT','checks','_24_Hour_Events','Full_24_Hour_Events']],df5[['HADM_ID','STORETIME','full_24 Hour Events:','24 Hour Events:']], on = ['HADM_ID','STORETIME'], how = 'left') | |
| hr24event_pattern = re.compile('((24 Hour Events):\\n(?s).*?Allergies:)') | |
| #there are some records with full_24 Hour Events: null, hence replaced these text with the extracted text from the progress note | |
| df4['hr24event_extracted'] = '' | |
| for (idx, row) in df4.iterrows(): | |
| try: | |
| text = df4['TEXT'][idx] | |
| df4['hr24event_extracted'][idx] = re.findall(hr24event_pattern,text) | |
| df4['hr24event_extracted'][idx] = [x for x in chain.from_iterable(df4['hr24event_extracted'][idx])] | |
| except: | |
| df4['hr24event_extracted'][idx] = '' | |
| df4 = df4.reset_index(drop=True) | |
| df4['hr24event_extracted'] = df4['hr24event_extracted'].apply(' '.join) | |
| df4['hr24event_extracted'] = df4['hr24event_extracted'].str.replace('\s+[a-z]+:\\n', ' ') | |
| df4['hr24event_extracted'] = df4['hr24event_extracted'].str.replace('24 Hour Events:|24 Hour Events|Allergies:', '') | |
| df4['hr24event_extracted'] = df4['hr24event_extracted'].str.replace('\s+', ' ') | |
| df4['hr24event_extracted'] = df4['hr24event_extracted'].str.replace('\.\s+\.', '.') | |
| df4['hr24event_extracted'] = df4['hr24event_extracted'].replace(r"^ +| +$", r"", regex=True) | |
| df4.loc[df4['full_24 Hour Events:'].isnull(),'full_24 Hour Events:'] = df4['hr24event_extracted'] | |
| df4.loc[df4['24 Hour Events:'].isnull(),'24 Hour Events:'] = df4['_24_Hour_Events'] | |
| # combining both data into one | |
| df = pd.merge(df, df2, on=['HADM_ID','SUBJECT_ID']) | |
| # Deleting admission chief complaint and diagnosis after combining | |
| del df2 | |
| # Remove decimal point from Admission ID and format words | |
| df['HADM_ID'] = df['HADM_ID'].astype(str).apply(lambda x: x.replace('.0','')) | |
| df3['HADM_ID'] = df3['HADM_ID'].astype(str).apply(lambda x: x.replace('.0','')) | |
| df4['HADM_ID'] = df4['HADM_ID'].astype(str).apply(lambda x: x.replace('.0','')) | |
| df3['INDEX_HADM_ID'] = df3['INDEX_HADM_ID'].astype(str).apply(lambda x: x.replace('.0','')) | |
| df3["CHARTDATE_HADM_ID"] = df3["CHARTDATE"].astype(str) +' ('+ df3["HADM_ID"] +')' | |
| df3["DIAGNOSIS"] = df3["DIAGNOSIS"].str.capitalize() | |
| df3["DISCHARGE_LOCATION"] = df3["DISCHARGE_LOCATION"].str.capitalize() | |
| df3["Diagnosis_Description"] =df3["Diagnosis_Description"].replace(r'\n',' \n ', regex=True) | |
| df3["TEXT"] =df3["TEXT"].replace(r'\n',' \n ', regex=True) | |
| df3["TEXT"] =df3["TEXT"].replace(r'#',' ', regex=True) | |
| df3["BertSummarizer"] =df3["BertSummarizer"].replace(r'#',' ', regex=True) | |
| #Renaming column | |
| df.rename(columns={'SUBJECT_ID':'Patient_ID', | |
| 'HADM_ID':'Admission_ID', | |
| 'hpi_input_text':'Original_Text', | |
| 'hpi_reference_summary':'Reference_text'}, inplace = True) | |
| df3.rename(columns={'SUBJECT_ID':'Patient_ID', | |
| 'HADM_ID':'PAST_Admission_ID', | |
| 'INDEX_HADM_ID':'Admission_ID'}, inplace = True) | |
| df4.rename(columns={'HADM_ID':'Admission_ID', | |
| 'full_24 Hour Events:':'Full Text', | |
| '24 Hour Events:':'Change_Note', | |
| 'past_24 Hour Events:':'Past_Change_Note'}, inplace = True) | |
| df4["Full Text"] =df4["Full Text"].replace('["[','').replace(']"]','') | |
| ## ========== Setting up Streamlit Sidebar ========== | |
| st.set_page_config(page_title ='Patient Inpatient Progression Dashboard', | |
| #page_icon= "Notes", | |
| layout='wide') | |
| st.title('Patient Inpatient Progression Dashboard') | |
| st.markdown( | |
| """ | |
| <style> | |
| [data-testid="stSidebar"][aria-expanded="true"] > div:first-child { | |
| width: 400px; | |
| } | |
| [data-testid="stSidebar"][aria-expanded="false"] > div:first-child { | |
| width: 400px; | |
| margin-left: -230px; | |
| } | |
| </style> | |
| """, | |
| unsafe_allow_html=True, | |
| ) | |
| st.sidebar.markdown('Using transformer model') | |
| #Filter selection | |
| st.sidebar.header("Search for Patient:") | |
| # ===== Initial filter for patient and admission id ===== | |
| patientid = df['Patient_ID'].unique() | |
| patient = st.sidebar.selectbox('Select Patient ID:', patientid) #Filter Patient | |
| admissionid = df['Admission_ID'].loc[df['Patient_ID'] == patient] #Filter available Admission id for patient | |
| HospitalAdmission = st.sidebar.selectbox(' ', admissionid) | |
| pastHistoryEpDate = df3['CHARTDATE_HADM_ID'].loc[(df3['Patient_ID'] == patient) & (df3['Admission_ID']== HospitalAdmission)] | |
| countOfAdmission = len(pastHistoryEpDate) | |
| # List of Model available | |
| #model = st.sidebar.selectbox('Select Model', ('BertSummarizer','BertGPT2','t5seq2eq','t5','gensim','pysummarizer')) | |
| model = 'BertSummarizer' | |
| st.sidebar.markdown('Model: ' + model) | |
| original_text = df.query( | |
| "Patient_ID == @patient & Admission_ID == @HospitalAdmission" | |
| ) | |
| original_text2 = original_text['Original_Text'].values | |
| AdmissionChiefCom = original_text['Admission_Chief_Complaint'].values | |
| diagnosis =original_text['DIAGNOSIS'].values | |
| reference_text = original_text['Reference_text'].values | |
| dailyNoteChange =df4[['STORETIME','Change_Note','Full Text']].loc[(df4['Admission_ID']==HospitalAdmission) & df4['_24_Hour_Events'].notnull()] | |
| dailyNoteFull =df4[['STORETIME','Change_Note','Full Text']].loc[(df4['Admission_ID']==HospitalAdmission) & df4['_24_Hour_Events'].notnull()] | |
| dailyNoteChange.rename(columns={'STORETIME':'Time of Record', | |
| 'Change_Note':'Note Changes'}, inplace = True) | |
| #dailyNoteChange['Time of Record'] = pd.to_datetime(dailyNoteChange['Time of Record']) | |
| dailyNoteChange['TimeDiff'] = pd.to_datetime(dailyNoteChange["Time of Record"], format='%Y/%m/%d %H:%M') | |
| #dailyNoteChange['TimeDiff'] = pd.to_datetime(dailyNoteChange["Time of Record"], format='%d/%m/%Y %H:%M') | |
| dailyNoteChange['TimeDiff'] = dailyNoteChange['TimeDiff'] -dailyNoteChange['TimeDiff'].shift() | |
| dailyNoteChange['TimeDiff'] = dailyNoteChange['TimeDiff'].fillna(pd.Timedelta(seconds=0)) | |
| dailyNoteChange['TimeDiff']= dailyNoteChange['TimeDiff'].dt.total_seconds().div(60).astype(int) | |
| dailyNoteChange['Hour'] = dailyNoteChange['TimeDiff'] // 60 | |
| dailyNoteChange['Mins'] = dailyNoteChange['TimeDiff']- dailyNoteChange['Hour'] * 60 | |
| dailyNoteChange["TimeDiff"] = dailyNoteChange['Hour'].astype(str) + " hours " + dailyNoteChange['Mins'].astype(str) + " Mins" | |
| del dailyNoteChange['Hour'] | |
| del dailyNoteChange['Mins'] | |
| dailyNoteChange["PreviousRecord"] = dailyNoteChange["Time of Record"].shift() | |
| dailyNoteChange.sort_values(by=['Time of Record'],ascending = False, inplace=True) | |
| dailyNoteFull.rename(columns={'STORETIME':'Time of Record', | |
| 'Change_Note':'Note Changes'}, inplace = True) | |
| dailyNote = df4['Full Text'].loc[(df4['Admission_ID']==HospitalAdmission)] | |
| dailyNote = dailyNote.unique() | |
| try: | |
| mindate = min(dailyNoteFull['Time of Record']) | |
| except: | |
| mindate = '' | |
| # ===== to display selected patient and admission id on main page | |
| col3,col4 = st.columns(2) | |
| patientid = col3.write(f"Patient ID: {patient} ") | |
| admissionid =col4.write(f"Admission ID: {HospitalAdmission} ") | |
| ##========= Buttons to the 3 tabs ======== Temp disabled Discharge Plan and Social Notes | |
| col1, col2, col3 = st.columns([1,1,1]) | |
| #col6, col7 =st.columns([2,2]) | |
| with st.container(): | |
| with col1: | |
| btnAdmission = st.button("🏥 Admission") | |
| with col2: | |
| btnDailyNarrative = st.button('📆Daily Narrative') | |
| with col3: | |
| btnPastHistory = st.button('📇Past History (6 Mths)') | |
| ##======================== Start of NER Tagging ======================== | |
| #lemmatizing the notes to capture all forms of negation(e.g., deny: denies, denying) | |
| def lemmatize(note, nlp): | |
| doc = nlp(note) | |
| lemNote = [wd.lemma_ for wd in doc] | |
| return " ".join(lemNote) | |
| #function to modify options for displacy NER visualization | |
| def get_entity_options(): | |
| entities = ["DISEASE", "CHEMICAL", "NEG_ENTITY"] | |
| colors = {'DISEASE': 'pink', 'CHEMICAL': 'orange', "NEG_ENTITY":'white'} | |
| options = {"ents": entities, "colors": colors} | |
| return options | |
| #adding a new pipeline component to identify negation | |
| def neg_model(): | |
| nlp.add_pipe('sentencizer') | |
| nlp.add_pipe( | |
| "negex", | |
| config={ | |
| "chunk_prefix": ["no"], | |
| }, | |
| last=True) | |
| return nlp | |
| def negation_handling(note, neg_model): | |
| results = [] | |
| nlp = neg_model() | |
| note = note.split(".") #sentence tokenizing based on delimeter | |
| note = [n.strip() for n in note] #removing extra spaces at the begining and end of sentence | |
| for t in note: | |
| doc = nlp(t) | |
| for e in doc.ents: | |
| rs = str(e._.negex) | |
| if rs == "True": | |
| results.append(e.text) | |
| return results | |
| #function to identify span objects of matched negative phrases from text | |
| def match(nlp,terms,label): | |
| patterns = [nlp.make_doc(text) for text in terms] | |
| matcher = PhraseMatcher(nlp.vocab) | |
| matcher.add(label, None, *patterns) | |
| return matcher | |
| #replacing the labels for identified negative entities | |
| def overwrite_ent_lbl(matcher, doc): | |
| matches = matcher(doc) | |
| seen_tokens = set() | |
| new_entities = [] | |
| entities = doc.ents | |
| for match_id, start, end in matches: | |
| if start not in seen_tokens and end - 1 not in seen_tokens: | |
| new_entities.append(Span(doc, start, end, label=match_id)) | |
| entities = [e for e in entities if not (e.start < end and e.end > start)] | |
| seen_tokens.update(range(start, end)) | |
| doc.ents = tuple(entities) + tuple(new_entities) | |
| return doc | |
| #deduplicate repeated entities | |
| def dedupe(items): | |
| seen = set() | |
| for item in items: | |
| item = str(item).strip() | |
| if item not in seen: | |
| yield item | |
| seen.add(item) | |
| ##======================== End of NER Tagging ======================== | |
| def run_model(input_text): | |
| if model == "BertSummarizer": | |
| output = original_text['BertSummarizer2s'].values | |
| st.write('Summary') | |
| elif model == "BertGPT2": | |
| output = original_text['BertGPT2'].values | |
| st.write('Summary') | |
| elif model == "t5seq2eq": | |
| output = original_text['t5seq2eq'].values | |
| st.write('Summary') | |
| elif model == "t5": | |
| output = original_text['t5'].values | |
| st.write('Summary') | |
| elif model == "gensim": | |
| output = original_text['gensim'].values | |
| st.write('Summary') | |
| elif model == "pysummarizer": | |
| output = original_text['pysummarizer'].values | |
| st.write('Summary') | |
| st.success(output) | |
| def Admission(): | |
| with st.container(): | |
| runtext =st.text_area('History of presenting illnesses at admission', str(original_text2)[1:-1], height=300) | |
| lem_clinical_note= lemmatize(runtext, nlp) | |
| #creating a doc object using BC5CDR model | |
| doc = nlp(lem_clinical_note) | |
| options = get_entity_options() | |
| #list of negative concepts from clinical note identified by negspacy | |
| results0 = negation_handling(lem_clinical_note, neg_model) | |
| matcher = match(nlp, results0,"NEG_ENTITY") | |
| #doc0: new doc object with added "NEG_ENTITY label" | |
| doc0 = overwrite_ent_lbl(matcher,doc) | |
| #visualizing identified Named Entities in clinical input text | |
| ent_html = displacy.render(doc0, style='ent', options=options) | |
| col1, col2 = st.columns([1,1]) | |
| with st.container(): | |
| with col1: | |
| st.button('Summarize') | |
| run_model(runtext) | |
| with col2: | |
| st.button('NER') | |
| # ===== Adding the Disease/Chemical into a list ===== | |
| problem_entities = list(dedupe([t for t in doc0.ents if t.label_ == 'DISEASE'])) | |
| medication_entities = list(dedupe([t for t in doc0.ents if t.label_ == 'CHEMICAL'])) | |
| st.markdown('**CHIEF COMPLAINT:**') | |
| st.write(str(AdmissionChiefCom)[1:-1]) | |
| st.markdown('**ADMISSION DIAGNOSIS:**') | |
| st.markdown(str(diagnosis)[1:-1].capitalize()) | |
| st.markdown('**PROBLEM/ISSUE**') | |
| #st.markdown(problem_entities) | |
| st.markdown(f'<p style="background-color:PINK;color:#080808;font-size:16px;">{str(problem_entities)[1:-1]}</p>', unsafe_allow_html=True) | |
| #genEntities(trans_df, 'DISEASE') | |
| st.markdown('**MEDICATION**') | |
| st.markdown(f'<p style="background-color:orange;color:#080808;font-size:16px;">{str(medication_entities)[1:-1]}</p>', unsafe_allow_html=True) | |
| #genEntities(trans_df, 'CHEMICAL') | |
| #st.table(trans_df) | |
| st.markdown('**NER**') | |
| with st.expander("See NER Details"): | |
| st.markdown(ent_html, unsafe_allow_html=True) | |
| alphabets= "([A-Za-z])" | |
| prefixes = "(mr|st|mrs|ms|dr)[.]" | |
| suffixes = "(inc|ltd|jr|sr|co)" | |
| starters = "(mr|mrs|ms|dr|he\s|she\s|it\s|they\s|their\s|our\s|we\s|but\s|however\s|that\s|this\s|wherever)" | |
| acronyms = "([A-Z][.][A-Z][.](?:[A-Z][.])?)" | |
| websites = "[.](com|net|org|io|gov)" | |
| digits = "([0-9])" | |
| def split_into_sentences(text): | |
| # text = str(text) | |
| text = " " + text + " " | |
| text = text.replace("\n"," ") | |
| # text = text.replace("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{2}:[0-9]{2}:[0-9]{2}"," ") | |
| text = re.sub(prefixes,"\\1<prd>",text) | |
| text = re.sub(websites,"<prd>\\1",text) | |
| text = re.sub(digits + "[.]" + digits,"\\1<prd>\\2",text) | |
| if "..." in text: text = text.replace("...","<prd><prd><prd>") | |
| if "Ph.D" in text: text = text.replace("Ph.D.","Ph<prd>D<prd>") | |
| text = re.sub("\s" + alphabets + "[.] "," \\1<prd> ",text) | |
| text = re.sub(acronyms+" "+starters,"\\1<stop> \\2",text) | |
| text = re.sub(alphabets + "[.]" + alphabets + "[.]" + alphabets + "[.]","\\1<prd>\\2<prd>\\3<prd>",text) | |
| text = re.sub(alphabets + "[.]" + alphabets + "[.]","\\1<prd>\\2<prd>",text) | |
| text = re.sub(" "+suffixes+"[.] "+starters," \\1<stop> \\2",text) | |
| text = re.sub(" "+suffixes+"[.]"," \\1<prd>",text) | |
| text = re.sub(" " + alphabets + "[.]"," \\1<prd>",text) | |
| if "”" in text: text = text.replace(".”","”.") | |
| if "\"" in text: text = text.replace(".\"","\".") | |
| if "!" in text: text = text.replace("!\"","\"!") | |
| if "?" in text: text = text.replace("?\"","\"?") | |
| text = text.replace(".",".<stop>") | |
| text = text.replace("?","?<stop>") | |
| text = text.replace("!","!<stop>") | |
| text = text.replace("[0-9]{2}:[0-9]{2}:[0-9]{2}:","[0-9]{2}:[0-9]{2}:[0-9]{2}:<stop>") | |
| text = text.replace("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}","[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}<stop>") | |
| # text = text.replace("-","-<stop>") | |
| # text = text.replace("- -","- -<stop>") | |
| text = text.replace("<br><br>","<stop><br><br>") | |
| text = text.replace("<prd>",".") | |
| sentences = text.split("<stop>") | |
| # sentences = text.split('-') | |
| # sentences = sentences[:-1] | |
| sentences = [s.strip() for s in sentences] | |
| return sentences | |
| def DailyNarrative(): | |
| with st.container(): | |
| dailyNarrativeTime= st.selectbox('',dailyNoteChange['Time of Record']) | |
| if df4[['Change_Note']].loc[(df4['Admission_ID']==HospitalAdmission) & (df4['STORETIME'] == dailyNarrativeTime)].size != 0: | |
| changeNote = df4[['Change_Note']].loc[(df4['Admission_ID']==HospitalAdmission) & (df4['STORETIME'] == dailyNarrativeTime)].values[0] | |
| else: | |
| changeNote = 'No records' | |
| if dailyNoteChange['TimeDiff'].loc[(dailyNoteChange['Time of Record']==dailyNarrativeTime)].empty: | |
| changeNoteTime = 'No records' | |
| previousRecord = ' ' | |
| else: | |
| changeNoteTime =dailyNoteChange['TimeDiff'].loc[(dailyNoteChange['Time of Record']==dailyNarrativeTime)].values[0] | |
| previousRecord =dailyNoteChange['PreviousRecord'].loc[(dailyNoteChange['Time of Record']==dailyNarrativeTime)].values[0] | |
| if dailyNarrativeTime == mindate: | |
| changeNote = 'Nil' | |
| else: | |
| changeNote = str(changeNote).replace('["[','').replace(']"]','').replace("'","").replace('"','').replace(',','').replace('\\','').replace('[','').replace(']','').replace('\\','') | |
| changeNote = changeNote.strip("[-,]").strip("") | |
| changeNote = ' '.join(changeNote.split()) | |
| # changeNote_split = re.split(r'(?<=[^A-Z].[.?]) +(?=[A-Z])|-', changeNote) | |
| # changeNote_split = [x.strip(' ') for x in changeNote_split] | |
| changeNote_split = split_into_sentences(changeNote) | |
| changeNote_split = [x for x in changeNote_split if x] | |
| latestRecord = dailyNoteChange['Time of Record'].max() | |
| st.markdown('Changes: ' + changeNote) | |
| st.markdown('Changes recorded from previous record at ' + str(previousRecord) + ' , ' + str(changeNoteTime) + ' ago') | |
| if df4[['Full Text']].loc[(df4['Admission_ID']==HospitalAdmission) & (df4['STORETIME'] == dailyNarrativeTime)].empty: | |
| dailyNarrativeText = 'No Records' | |
| else: | |
| dailyNoteChange.sort_values(by='Time of Record',ascending = True, inplace=True) | |
| dailyNoteChange["Combined"] = '' | |
| count = 0 | |
| text ='' | |
| for index, row in dailyNoteChange.iterrows(): | |
| text = '[**' + str(row['Time of Record']) + '**]' + ':<stop> ' + row['Full Text'] + '<br>' + '<br>' + text | |
| dailyNoteChange['Combined'].iloc[count] = text | |
| count = count + 1 | |
| dailyNarrativeText =dailyNoteChange[['Combined']].loc[(dailyNoteChange['Time of Record'] == dailyNarrativeTime)].values[0] | |
| #dailyNarrativeText =df4[['Full Text']].loc[(df4['Admission_ID']==HospitalAdmission) & (df4['DATETIME'] == dailyNarrativeTime)].values[0] | |
| dailyNarrativeText = str(dailyNarrativeText).replace('["[','').replace(']"]','').replace("'","").replace(',','').replace('"','').replace('[','').replace(']','').replace('\\','') | |
| dailyNarrativeText = dailyNarrativeText.strip("[-,]").strip(" ") | |
| dailyNarrativeText = ' '.join(dailyNarrativeText.split()) | |
| # dailyNarrativeText_split = re.split(r'(?<=[^A-Z].[.?]) +(?=[A-Z])|-|<br><br>', dailyNarrativeText) | |
| # dailyNarrativeText_split = [x.strip(' ') for x in dailyNarrativeText_split] | |
| dailyNarrativeText_split = split_into_sentences(dailyNarrativeText) | |
| #st.table(dailyNoteChange) # testing to see if data calculate correctly | |
| annt_ls = [] | |
| for sent in dailyNarrativeText_split: | |
| if '<br><br>' in sent: | |
| break # one item didn't complete the condition, get out of this loop | |
| else: | |
| end_index = dailyNarrativeText_split.index(sent) + 1 | |
| annt_ls.append(sent) | |
| non_annt_ls = dailyNarrativeText_split[end_index:] | |
| with st.expander("See in detail"): | |
| ls = [] | |
| for sent in annt_ls: | |
| if sent in changeNote_split: | |
| sent = sent.replace(str(sent),str(annotation(sent))) | |
| ls.append(sent) | |
| else: | |
| ls.append(sent) | |
| ls2 = ls + non_annt_ls | |
| highlight = ' '.join(ls2) | |
| st.markdown(highlight, unsafe_allow_html=True) | |
| def PastHistory(): | |
| col6, col7 =st.columns([2,2]) | |
| with st.container(): | |
| with col6: | |
| st.markdown('**No. of admission past 6 months:**') | |
| st.markdown(countOfAdmission) | |
| with col7: | |
| #st.date_input('Select Admission Date') # To replace with a dropdown filter instead | |
| #st.selectbox('Past Episodes',pastHistoryEp) | |
| pastHistory = st.selectbox('Select Past History Admission', pastHistoryEpDate, format_func=lambda x: 'Select an option' if x == '' else x) | |
| historyAdmission = df3.query( | |
| "Patient_ID == @patient & CHARTDATE_HADM_ID == @pastHistory" | |
| ) | |
| if historyAdmission.shape[0] == 0: | |
| runtext = "No past episodes" | |
| else: | |
| #runtext = historyAdmission['hospital_course_processed'].values[0] | |
| runtext = historyAdmission['hospital_course_processed'].values[0] | |
| lem_clinical_note= lemmatize(runtext, nlp) | |
| #creating a doc object using BC5CDR model | |
| doc = nlp(lem_clinical_note) | |
| options = get_entity_options() | |
| #list of negative concepts from clinical note identified by negspacy | |
| results0 = negation_handling(lem_clinical_note, neg_model) | |
| matcher = match(nlp, results0,"NEG_ENTITY") | |
| #doc0: new doc object with added "NEG_ENTITY label" | |
| doc0 = overwrite_ent_lbl(matcher,doc) | |
| #visualizing identified Named Entities in clinical input text | |
| ent_html = displacy.render(doc0, style='ent', options=options) | |
| # ===== Adding the Disease/Chemical into a list ===== | |
| problem_entities = list(dedupe([t for t in doc0.ents if t.label_ == 'DISEASE'])) | |
| medication_entities = list(dedupe([t for t in doc0.ents if t.label_ == 'CHEMICAL'])) | |
| if historyAdmission.shape[0] == 0: | |
| st.markdown('Admission Date: NA') | |
| st.markdown('Date of Discharge: NA') | |
| st.markdown('Days from current admission: NA') | |
| else: | |
| st.markdown('Admission Date: ' + historyAdmission['ADMITTIME'].values[0]) | |
| st.markdown('Date of Discharge: ' + historyAdmission['DISCHTIME'].values[0]) | |
| st.markdown('Days from current admission: ' + str(historyAdmission['days_from_index'].values[0]) +' days') | |
| #st.markdown('Summary: ') | |
| st.markdown(f'<p style="color:#080808;font-size:16px;"><b>Summary: </b></p>', unsafe_allow_html=True) | |
| if model == "BertSummarizer": | |
| if historyAdmission.shape[0] == 0: | |
| st.markdown('NA') | |
| else: | |
| st.markdown(str(historyAdmission['BertSummarizer'].values[0])) | |
| elif model == "t5seq2eq": | |
| if historyAdmission.shape[0] == 0: | |
| st.markdown('NA') | |
| else: | |
| st.markdown(str(historyAdmission['t5seq2eq'].values[0])) | |
| st.markdown(f'<p style="color:#080808;font-size:16px;"><b>Diagnosis: </b></p>', unsafe_allow_html=True) | |
| if historyAdmission.shape[0] == 0: | |
| st.markdown('NA') | |
| else: | |
| st.markdown(str(historyAdmission['Diagnosis_Description'].values[0])) | |
| st.markdown('**PROBLEM/ISSUE**') | |
| st.markdown(f'<p style="background-color:PINK;color:#080808;font-size:16px;">{str(problem_entities)[1:-1]}</p>', unsafe_allow_html=True) | |
| st.markdown('**MEDICATION**') | |
| st.markdown(f'<p style="background-color:orange;color:#080808;font-size:16px;">{str(medication_entities)[1:-1]}</p>', unsafe_allow_html=True) | |
| st.markdown('Discharge Disposition: ' + str(historyAdmission['DISCHARGE_LOCATION'].values[0])) | |
| with st.expander('Full Discharge Summary'): | |
| #st.write("line 1 \n line 2 \n line 3") | |
| fulldischargesummary = historyAdmission['TEXT'].values[0] | |
| st.write(fulldischargesummary) | |
| if "load_state" not in st.session_state: | |
| st.session_state.load_state = False | |
| if "button_clicked" not in st.session_state: | |
| st.session_state.button_clicked = False | |
| if "admission_button_clicked" not in st.session_state: | |
| st.session_state.admission_button_clicked = False | |
| if "daily_button_clicked" not in st.session_state: | |
| st.session_state.daily_button_clicked = False | |
| if "past_button_clicked" not in st.session_state: | |
| st.session_state.past_button_clicked = False | |
| if btnAdmission or st.session_state["admission_button_clicked"] and not btnDailyNarrative and not btnPastHistory: | |
| st.session_state["admission_button_clicked"] = True | |
| st.session_state["daily_button_clicked"] = False | |
| st.session_state["past_button_clicked"] = False | |
| Admission() | |
| if btnDailyNarrative or st.session_state["daily_button_clicked"] and not btnAdmission and not btnPastHistory: | |
| st.session_state["daily_button_clicked"] = True | |
| st.session_state["admission_button_clicked"] = False | |
| st.session_state["past_button_clicked"] = False | |
| DailyNarrative() | |
| if btnPastHistory or st.session_state["past_button_clicked"] and not btnDailyNarrative and not btnAdmission: | |
| st.session_state["past_button_clicked"] = True | |
| st.session_state["admission_button_clicked"] = False | |
| st.session_state["daily_button_clicked"] = False | |
| PastHistory() |