Saicharan21 commited on
Commit
23438cf
·
verified ·
1 Parent(s): f767c1c

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +41 -58
app.py CHANGED
@@ -13,8 +13,13 @@ KNOWHOW = ('SJSU CardioLab: '
13
  'Equipment: Heska HT5 hematology analyzer time-resolved PIV Tygon tubing Arduino Uno.')
14
 
15
  CSS = (
 
16
  'body { background: #0a0f1e !important; }'
17
- '.gradio-container { background: #0a0f1e !important; color: white !important; }'
 
 
 
 
18
  )
19
 
20
  def get_pubmed(query, n=5):
@@ -24,8 +29,7 @@ def get_pubmed(query, n=5):
24
  'retmax':n,'retmode':'json','sort':'date'},timeout=10)
25
  ids = r.json()['esearchresult']['idlist']
26
  if not ids: return ''
27
- links = ['https://pubmed.ncbi.nlm.nih.gov/'+i for i in ids]
28
- return 'PubMed: ' + ' | '.join(links)
29
  except: return ''
30
 
31
  def get_scholar(query, n=5):
@@ -40,17 +44,17 @@ def get_scholar(query, n=5):
40
  url = p.get('url','')
41
  citations = str(p.get('citationCount',0))
42
  if url:
43
- out.append(title[:80]+' ('+year+') '+citations+' citations - '+url)
44
- return chr(10).join(out)
45
  except: return ''
46
 
47
  def quick_search(query):
48
  if not query.strip(): return 'Please enter a research topic.'
49
  pubmed = get_pubmed(query, n=8)
50
  scholar = get_scholar(query, n=5)
51
- result = 'RESEARCH PAPERS FOR: ' + query + chr(10) + chr(10)
52
- result += 'PUBMED (verified links):' + chr(10) + pubmed + chr(10) + chr(10)
53
- result += 'SEMANTIC SCHOLAR:' + chr(10) + scholar
54
  return result
55
 
56
  def research_chat(message, history):
@@ -61,8 +65,7 @@ def research_chat(message, history):
61
  try:
62
  client = Groq(api_key=GROQ_KEY)
63
  pubmed = get_pubmed(message, n=3)
64
- scholar = get_scholar(message, n=3)
65
- system_msg = 'You are CardioLab AI from SJSU Biomedical Engineering built on Biomni Stanford SNAP Lab. Expert in MHV MCL PIV TGT uPAD CKD FSI. Remember full conversation. Never invent URLs. ' + KNOWHOW
66
  msgs = [{'role':'system','content':system_msg}]
67
  for item in history:
68
  if isinstance(item, dict):
@@ -70,8 +73,7 @@ def research_chat(message, history):
70
  msgs.append({'role':'user','content':message})
71
  resp = client.chat.completions.create(model='llama-3.3-70b-versatile',messages=msgs,max_tokens=700)
72
  answer = resp.choices[0].message.content
73
- if pubmed: answer += chr(10)+chr(10)+'VERIFIED PUBMED: '+pubmed
74
- if scholar: answer += chr(10)+chr(10)+'SEMANTIC SCHOLAR: '+chr(10)+scholar
75
  history.append({'role':'user','content':message})
76
  history.append({'role':'assistant','content':answer})
77
  return '', history
@@ -82,37 +84,30 @@ def research_chat(message, history):
82
 
83
  def piv_tool(velocity, shear, hr):
84
  v = 'HIGH - stenosis risk' if float(velocity)>2.0 else 'NORMAL'
85
- s = 'HIGH - thrombosis risk' if float(shear)>10 else 'ELEVATED - monitor' if float(shear)>5 else 'NORMAL'
86
  hr_s = 'ABNORMAL' if float(hr)<60 or float(hr)>100 else 'NORMAL'
87
- return 'PIV ANALYSIS RESULTS'+chr(10)+'Velocity: '+str(velocity)+' m/s - '+v+chr(10)+'Shear: '+str(shear)+' Pa - '+s+chr(10)+'Heart Rate: '+str(hr)+' bpm - '+hr_s
88
 
89
  def tgt_tool(tat,pf12,hemo,platelets,time):
90
  risk=sum([float(tat)>15,float(pf12)>2.0,float(hemo)>50,float(platelets)<150])
91
  r='HIGH THROMBOGENIC RISK' if risk>=3 else 'MODERATE RISK' if risk>=2 else 'LOW RISK'
92
- t_s='HIGH' if float(tat)>15 else 'NORMAL'
93
- p_s='HIGH' if float(pf12)>2.0 else 'NORMAL'
94
- h_s='HIGH' if float(hemo)>50 else 'NORMAL'
95
- pl_s='LOW' if float(platelets)<150 else 'NORMAL'
96
- return 'TGT BLOOD ANALYSIS'+chr(10)+'Time: '+str(time)+' min'+chr(10)+'TAT: '+str(tat)+' - '+t_s+chr(10)+'PF1.2: '+str(pf12)+' - '+p_s+chr(10)+'Hemoglobin: '+str(hemo)+' - '+h_s+chr(10)+'Platelets: '+str(platelets)+' - '+pl_s+chr(10)+'Overall: '+r
97
 
98
  def upad_tool(r,g,b):
99
  c=max(0,round(0.02*(float(r)-float(b))-0.5,2))
100
- if c<1.2: s='Normal'
101
- elif c<1.5: s='Borderline'
102
  elif c<3.0: s='Stage 2 CKD'
103
  elif c<6.0: s='Stage 3-4 CKD'
104
- else: s='Stage 5 CKD'
105
- return 'uPAD CKD ANALYSIS'+chr(10)+'RGB: R='+str(r)+' G='+str(g)+' B='+str(b)+chr(10)+'Creatinine: '+str(c)+' mg/dL'+chr(10)+'CKD Stage: '+s+chr(10)+'Confirm with: Heska Element HT5'
106
 
107
- with gr.Blocks(title='CardioLab AI SJSU', css=CSS) as demo:
108
- gr.Markdown('# CardioLab AI Agent')
109
- gr.Markdown('### SJSU Biomedical Engineering | Biomni Stanford + Llama 70B + PubMed Live Search')
110
- gr.Markdown('github.com/pranatechsol/Cardio-Lab-Ai | huggingface.co/Saicharan21')
111
 
112
  with gr.Tabs():
113
- with gr.Tab('Research Chat'):
114
- gr.Markdown('### Chat with memory like ChatGPT - searches PubMed for every question')
115
- chatbot = gr.Chatbot(label='CardioLab AI', height=500)
116
  with gr.Row():
117
  msg_box = gr.Textbox(placeholder='Ask anything about CardioLab research...', label='', lines=2, scale=4)
118
  with gr.Column(scale=1):
@@ -123,47 +118,35 @@ with gr.Blocks(title='CardioLab AI SJSU', css=CSS) as demo:
123
  clear_btn.click(lambda: ([], ''), outputs=[chatbot, msg_box])
124
 
125
  with gr.Tab('Paper Search'):
126
- gr.Markdown('### Search latest research papers with verified working links')
127
- gr.Markdown('Searches PubMed + Semantic Scholar - only real verified URLs sorted by most recent')
128
- search_input = gr.Textbox(placeholder='e.g. mechanical heart valve thrombogenicity 2024', label='Research topic')
129
  search_btn = gr.Button('Search Papers', variant='primary')
130
- search_output = gr.Textbox(label='Research Papers Found', lines=20)
131
  search_btn.click(quick_search, inputs=search_input, outputs=search_output)
132
  search_input.submit(quick_search, inputs=search_input, outputs=search_output)
133
- gr.Markdown('Suggested: mechanical heart valve PIV | creatinine uPAD microfluidic | bileaflet MHV thrombogenicity | CKD point-of-care')
134
 
135
  with gr.Tab('PIV Analysis'):
136
- gr.Markdown('### Analyze PIV flow data from Mock Circulatory Loop')
137
  with gr.Row():
138
  with gr.Column():
139
- v=gr.Number(label='Max Velocity m/s', value=1.8, info='Normal: 0.5-2.0 m/s')
140
- s=gr.Number(label='Wall Shear Stress Pa', value=6.5, info='Normal: <5 Pa')
141
- h=gr.Number(label='Heart Rate bpm', value=72, info='Normal: 60-100 bpm')
142
- gr.Button('Analyze PIV', variant='primary').click(piv_tool,inputs=[v,s,h],outputs=gr.Textbox(label='Result',lines=6))
 
143
 
144
  with gr.Tab('TGT Results'):
145
- gr.Markdown('### Interpret Thrombogenicity Tester blood results')
146
- t1=gr.Number(label='TAT ng/mL', value=18, info='Normal: <8')
147
- t2=gr.Number(label='PF1.2 nmol/L', value=2.5, info='Normal: <2.0')
148
- t3=gr.Number(label='Free Hemoglobin mg/L', value=60, info='Normal: <20')
149
- t4=gr.Number(label='Platelet Count', value=140, info='Normal: >150')
150
  t5=gr.Number(label='Time minutes', value=40)
151
- out2=gr.Textbox(label='Result',lines=8)
152
  gr.Button('Analyze TGT', variant='primary').click(tgt_tool,inputs=[t1,t2,t3,t4,t5],outputs=out2)
153
 
154
  with gr.Tab('uPAD CKD'):
155
- gr.Markdown('### Analyze uPAD colorimetric result - Jaffe Reaction')
156
- r=gr.Number(label='R value', value=210, info='Range 0-255')
157
- g=gr.Number(label='G value', value=140, info='Range 0-255')
158
- b=gr.Number(label='B value', value=80, info='Range 0-255')
159
- out3=gr.Textbox(label='CKD Result',lines=6)
160
  gr.Button('Analyze uPAD', variant='primary').click(upad_tool,inputs=[r,g,b],outputs=out3)
161
 
162
- with gr.Tab('About'):
163
- gr.Markdown('## CardioLab AI Agent - SJSU Biomedical Engineering')
164
- gr.Markdown('Built on Biomni Stanford SNAP Lab | Apache 2.0')
165
- gr.Markdown('Live: https://huggingface.co/spaces/Saicharan21/CardioLab-AI')
166
- gr.Markdown('Code: https://github.com/pranatechsol/Cardio-Lab-Ai')
167
- gr.Markdown('Brain: Llama 3.3 70B via Groq free | Search: PubMed + Semantic Scholar free')
168
-
169
  demo.launch()
 
13
  'Equipment: Heska HT5 hematology analyzer time-resolved PIV Tygon tubing Arduino Uno.')
14
 
15
  CSS = (
16
+ '.gradio-container { background: #0a0f1e !important; color: white !important; max-width: 100% !important; }'
17
  'body { background: #0a0f1e !important; }'
18
+ '.gr-button-primary { background: linear-gradient(135deg, #e63946, #c1121f) !important; border: none !important; color: white !important; border-radius: 8px !important; }'
19
+ '.gr-button-secondary { background: #1d3461 !important; border: 1px solid #4361ee !important; color: white !important; border-radius: 8px !important; }'
20
+ 'textarea, input { background: #1a2744 !important; color: white !important; border: 1px solid #2d4a8a !important; border-radius: 8px !important; }'
21
+ '.gr-box { background: #0d1b3e !important; border: 1px solid #2d4a8a !important; border-radius: 12px !important; }'
22
+ 'h1 { color: #e63946 !important; font-size: 2.5em !important; font-weight: 900 !important; text-align: center !important; padding: 20px !important; }'
23
  )
24
 
25
  def get_pubmed(query, n=5):
 
29
  'retmax':n,'retmode':'json','sort':'date'},timeout=10)
30
  ids = r.json()['esearchresult']['idlist']
31
  if not ids: return ''
32
+ return chr(10).join(['https://pubmed.ncbi.nlm.nih.gov/'+i for i in ids])
 
33
  except: return ''
34
 
35
  def get_scholar(query, n=5):
 
44
  url = p.get('url','')
45
  citations = str(p.get('citationCount',0))
46
  if url:
47
+ out.append(title[:80]+' ('+year+') - '+citations+' citations'+chr(10)+' '+url)
48
+ return chr(10)+chr(10).join(out)
49
  except: return ''
50
 
51
  def quick_search(query):
52
  if not query.strip(): return 'Please enter a research topic.'
53
  pubmed = get_pubmed(query, n=8)
54
  scholar = get_scholar(query, n=5)
55
+ result = 'PAPERS FOR: ' + query + chr(10)+chr(10)
56
+ result += 'PUBMED (click links to open):'+chr(10)+pubmed+chr(10)+chr(10)
57
+ result += 'SEMANTIC SCHOLAR:'+chr(10)+scholar
58
  return result
59
 
60
  def research_chat(message, history):
 
65
  try:
66
  client = Groq(api_key=GROQ_KEY)
67
  pubmed = get_pubmed(message, n=3)
68
+ system_msg = 'You are CardioLab AI assistant. Expert in MHV MCL PIV TGT uPAD CKD FSI. Remember full conversation. Never invent URLs. ' + KNOWHOW
 
69
  msgs = [{'role':'system','content':system_msg}]
70
  for item in history:
71
  if isinstance(item, dict):
 
73
  msgs.append({'role':'user','content':message})
74
  resp = client.chat.completions.create(model='llama-3.3-70b-versatile',messages=msgs,max_tokens=700)
75
  answer = resp.choices[0].message.content
76
+ if pubmed: answer += chr(10)+chr(10)+'PUBMED LINKS:'+chr(10)+pubmed
 
77
  history.append({'role':'user','content':message})
78
  history.append({'role':'assistant','content':answer})
79
  return '', history
 
84
 
85
  def piv_tool(velocity, shear, hr):
86
  v = 'HIGH - stenosis risk' if float(velocity)>2.0 else 'NORMAL'
87
+ s = 'HIGH - thrombosis risk' if float(shear)>10 else 'ELEVATED' if float(shear)>5 else 'NORMAL'
88
  hr_s = 'ABNORMAL' if float(hr)<60 or float(hr)>100 else 'NORMAL'
89
+ return 'VELOCITY: '+str(velocity)+' m/s - '+v+chr(10)+'SHEAR: '+str(shear)+' Pa - '+s+chr(10)+'HEART RATE: '+str(hr)+' bpm - '+hr_s
90
 
91
  def tgt_tool(tat,pf12,hemo,platelets,time):
92
  risk=sum([float(tat)>15,float(pf12)>2.0,float(hemo)>50,float(platelets)<150])
93
  r='HIGH THROMBOGENIC RISK' if risk>=3 else 'MODERATE RISK' if risk>=2 else 'LOW RISK'
94
+ return 'TIME: '+str(time)+' min'+chr(10)+'TAT: '+str(tat)+(' - HIGH' if float(tat)>15 else ' - NORMAL')+chr(10)+'PF1.2: '+str(pf12)+(' - HIGH' if float(pf12)>2.0 else ' - NORMAL')+chr(10)+'HEMOGLOBIN: '+str(hemo)+(' - HIGH' if float(hemo)>50 else ' - NORMAL')+chr(10)+'PLATELETS: '+str(platelets)+(' - LOW' if float(platelets)<150 else ' - NORMAL')+chr(10)+chr(10)+'OVERALL: '+r
 
 
 
 
95
 
96
  def upad_tool(r,g,b):
97
  c=max(0,round(0.02*(float(r)-float(b))-0.5,2))
98
+ if c<1.2: s='Normal - No CKD'
99
+ elif c<1.5: s='Borderline - Monitor'
100
  elif c<3.0: s='Stage 2 CKD'
101
  elif c<6.0: s='Stage 3-4 CKD'
102
+ else: s='Stage 5 CKD - Kidney Failure'
103
+ return 'RGB: R='+str(r)+' G='+str(g)+' B='+str(b)+chr(10)+'CREATININE: '+str(c)+' mg/dL'+chr(10)+'CKD STAGE: '+s+chr(10)+'Confirm with: Heska Element HT5'
104
 
105
+ with gr.Blocks(title='CardioLab AI', css=CSS) as demo:
106
+ gr.Markdown('# CardioLab AI')
 
 
107
 
108
  with gr.Tabs():
109
+ with gr.Tab('Chat'):
110
+ chatbot = gr.Chatbot(label='', height=500)
 
111
  with gr.Row():
112
  msg_box = gr.Textbox(placeholder='Ask anything about CardioLab research...', label='', lines=2, scale=4)
113
  with gr.Column(scale=1):
 
118
  clear_btn.click(lambda: ([], ''), outputs=[chatbot, msg_box])
119
 
120
  with gr.Tab('Paper Search'):
121
+ search_input = gr.Textbox(placeholder='e.g. mechanical heart valve thrombogenicity', label='Research topic')
 
 
122
  search_btn = gr.Button('Search Papers', variant='primary')
123
+ search_output = gr.Textbox(label='Results', lines=20)
124
  search_btn.click(quick_search, inputs=search_input, outputs=search_output)
125
  search_input.submit(quick_search, inputs=search_input, outputs=search_output)
 
126
 
127
  with gr.Tab('PIV Analysis'):
 
128
  with gr.Row():
129
  with gr.Column():
130
+ v=gr.Number(label='Max Velocity m/s', value=1.8)
131
+ s=gr.Number(label='Wall Shear Stress Pa', value=6.5)
132
+ h=gr.Number(label='Heart Rate bpm', value=72)
133
+ piv_out=gr.Textbox(label='Result', lines=5)
134
+ gr.Button('Analyze PIV', variant='primary').click(piv_tool,inputs=[v,s,h],outputs=piv_out)
135
 
136
  with gr.Tab('TGT Results'):
137
+ t1=gr.Number(label='TAT ng/mL', value=18)
138
+ t2=gr.Number(label='PF1.2 nmol/L', value=2.5)
139
+ t3=gr.Number(label='Free Hemoglobin mg/L', value=60)
140
+ t4=gr.Number(label='Platelet Count', value=140)
 
141
  t5=gr.Number(label='Time minutes', value=40)
142
+ out2=gr.Textbox(label='Result', lines=8)
143
  gr.Button('Analyze TGT', variant='primary').click(tgt_tool,inputs=[t1,t2,t3,t4,t5],outputs=out2)
144
 
145
  with gr.Tab('uPAD CKD'):
146
+ r=gr.Number(label='R value', value=210)
147
+ g=gr.Number(label='G value', value=140)
148
+ b=gr.Number(label='B value', value=80)
149
+ out3=gr.Textbox(label='Result', lines=6)
 
150
  gr.Button('Analyze uPAD', variant='primary').click(upad_tool,inputs=[r,g,b],outputs=out3)
151
 
 
 
 
 
 
 
 
152
  demo.launch()