Saicharan21 commited on
Commit
0741658
·
verified ·
1 Parent(s): e0d2512

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +76 -33
app.py CHANGED
@@ -1,58 +1,101 @@
1
  import gradio as gr
2
- import os
3
  from groq import Groq
4
 
5
- GROQ_KEY = os.environ.get("GROQ_API_KEY", "")
6
  client = Groq(api_key=GROQ_KEY)
7
 
8
  KNOWHOW = """
9
- CardioLab SJSU Know-How:
10
- MCL: Sylgard 184 at 10:1 ratio, 48hr cure, green laser PIV, 70bpm 5L/min flow
11
- TGT: Arduino Uno + Stepper Motor, 150mL blood, sample at 0/20/40/60min, measure TAT PF1.2 hemolysis platelets
12
- uPAD: Jaffe reaction creatinine + picric acid = orange-red, normal <1.2 mg/dL, CKD >1.5 mg/dL
13
- FSI: COMSOL ALE mesh, blood density 1060 kg/m3, viscosity 0.0035 Pa.s, St Jude geometry
14
- MHV: 27mm SJM Regent, bileaflet, trileaflet, monoleaflet, pediatric designs
15
- CKD: Stages 1-5 by creatinine, uPAD image RGB analysis 64x64 pixel
 
 
 
16
  """
17
 
18
- def ask_biomni(question):
19
  try:
20
- response = client.chat.completions.create(
21
- model="llama-3.3-70b-versatile",
22
- messages=[
23
- {"role": "system", "content": "You are CardioLab AI built on Biomni from Stanford SNAP Lab. Expert in SJSU Biomedical Engineering research. Always give detailed accurate answers.\n" + KNOWHOW},
24
- {"role": "user", "content": question}
25
- ],
26
- max_tokens=500
27
- )
28
- return response.choices[0].message.content
29
- except Exception as e:
30
- return "Error: " + str(e)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  def piv_tool(velocity, shear, hr):
33
- v = "HIGH - stenosis risk" if float(velocity) > 2.0 else "NORMAL"
34
- s = "HIGH - thrombosis risk" if float(shear) > 10 else "ELEVATED - monitor" if float(shear) > 5 else "NORMAL"
35
- return "Velocity: " + str(velocity) + " m/s - " + v + "\nShear Stress: " + str(shear) + " Pa - " + s + "\nHeart Rate: " + str(hr) + " bpm"
36
 
37
  def tgt_tool(tat, pf12, hemo, platelets, time):
38
  risk = sum([float(tat)>15, float(pf12)>2.0, float(hemo)>50, float(platelets)<150])
39
  overall = "HIGH THROMBOGENIC RISK" if risk>=3 else "MODERATE RISK" if risk>=2 else "LOW RISK"
40
- return "TAT: " + str(tat) + "\nPF1.2: " + str(pf12) + "\nFree Hemoglobin: " + str(hemo) + "\nPlatelets: " + str(platelets) + "\nTime: " + str(time) + " min\nOverall: " + overall
41
 
42
  def upad_tool(r, g, b):
43
  creatinine = max(0, round(0.02*(float(r)-float(b))-0.5, 2))
44
  stage = "Normal" if creatinine<1.2 else "Borderline" if creatinine<1.5 else "Stage 2 CKD" if creatinine<3.0 else "Stage 3-4 CKD" if creatinine<6.0 else "Stage 5 CKD"
45
- return "Creatinine: " + str(creatinine) + " mg/dL\nCKD Stage: " + stage + "\nConfirm with: Heska Element HT5"
46
 
47
  with gr.Blocks(title="CardioLab AI - SJSU") as demo:
48
  gr.Markdown("# CardioLab AI Agent")
49
- gr.Markdown("### SJSU Biomedical Engineering | Built on Biomni (Stanford) | Powered by Llama 70B")
50
- gr.Markdown("GitHub: github.com/pranatechsol/Cardio-Lab-Ai")
51
- with gr.Tab("Ask Agent"):
52
- gr.Markdown("Ask anything about MCL, PIV, TGT, uPAD, CKD, FSI, MHV")
53
- q = gr.Textbox(label="Your question", placeholder="e.g. What is Sylgard 184 used for?")
54
- a = gr.Textbox(label="Answer", lines=6)
55
- gr.Button("Ask CardioLab AI").click(ask_biomni, inputs=q, outputs=a)
56
  with gr.Tab("PIV Analysis"):
57
  gr.Markdown("### Analyze PIV flow data from Mock Circulatory Loop")
58
  v = gr.Number(label="Max Velocity m/s", value=1.8)
 
1
  import gradio as gr
2
+ import os, requests, glob
3
  from groq import Groq
4
 
5
+ GROQ_KEY = os.environ.get("GROQ_API_KEY","")
6
  client = Groq(api_key=GROQ_KEY)
7
 
8
  KNOWHOW = """
9
+ SJSU CardioLab Know-How:
10
+ MCL: Mock Circulatory Loop using Sylgard 184 PDMS at 10:1 ratio cured 48hrs, green laser PIV, 70bpm 5L/min physiological flow
11
+ TGT: Thrombogenicity Tester with Arduino Uno + Stepper Motor, 150mL blood, sample at 0/20/40/60min, measure TAT PF1.2 hemolysis platelets
12
+ uPAD: Microfluidic Paper Device, Jaffe reaction creatinine + picric acid = orange-red color, normal creatinine 0.6-1.2 mg/dL, CKD above 1.5 mg/dL
13
+ FSI: COMSOL Multiphysics ALE mesh, blood density 1060 kg/m3, viscosity 0.0035 Pa.s, St Jude Medical geometry reference
14
+ MHV: 27mm SJM Regent bileaflet mechanical heart valve, also trileaflet, monoleaflet, pediatric designs studied
15
+ CKD Stages: Stage 1 below 1.5, Stage 2 1.5-3.0, Stage 3-4 3.0-6.0, Stage 5 above 6.0 mg/dL creatinine
16
+ Equipment: Heska Element HT5 hematology analyzer, time-resolved PIV, Tygon tubing
17
+ Acoustic detection: microphone on valve housing detects clot formation via frequency shift
18
+ Projects: 13 total, 3 pillars - MHV hemodynamics, CKD diagnostics, FSI simulations
19
  """
20
 
21
+ def search_pubmed(query, n=3):
22
  try:
23
+ r = requests.get("https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi",
24
+ params={"db":"pubmed","term":query,"retmax":n,"retmode":"json"}, timeout=10)
25
+ ids = r.json()["esearchresult"]["idlist"]
26
+ if not ids: return ""
27
+ r2 = requests.get("https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi",
28
+ params={"db":"pubmed","id":",".join(ids),"retmode":"xml","rettype":"abstract"}, timeout=10)
29
+ import xmltodict
30
+ data = xmltodict.parse(r2.content)
31
+ articles = data.get("PubmedArticleSet",{}).get("PubmedArticle",[])
32
+ if isinstance(articles, dict): articles = [articles]
33
+ out = []
34
+ for a in articles[:n]:
35
+ try:
36
+ c = a["MedlineCitation"]
37
+ title = str(c["Article"]["ArticleTitle"])
38
+ abstract = c["Article"].get("Abstract",{}).get("AbstractText","")
39
+ if isinstance(abstract, list): abstract = " ".join([str(x) for x in abstract])
40
+ if isinstance(abstract, dict): abstract = str(abstract.get("#text",""))
41
+ pmid = str(c["PMID"]["#text"] if isinstance(c["PMID"],dict) else c["PMID"])
42
+ out.append("[PubMed: " + title[:80] + "]\n" + str(abstract)[:300] + "\nURL: https://pubmed.ncbi.nlm.nih.gov/" + pmid)
43
+ except: continue
44
+ return "\n\n".join(out)
45
+ except: return ""
46
+
47
+ def search_scholar(query, n=3):
48
+ try:
49
+ r = requests.get("https://api.semanticscholar.org/graph/v1/paper/search",
50
+ params={"query":query,"limit":n,"fields":"title,abstract,year,url"}, timeout=10)
51
+ papers = r.json().get("data",[])
52
+ out = []
53
+ for p in papers:
54
+ out.append("[Scholar " + str(p.get("year","")) + ": " + p.get("title","")[:80] + "]\n" + (p.get("abstract") or "")[:300] + "\nURL: " + p.get("url",""))
55
+ return "\n\n".join(out)
56
+ except: return ""
57
+
58
+ def ask_agent(question):
59
+ if not GROQ_KEY:
60
+ return "Error: GROQ_API_KEY not set in Space secrets."
61
+ cardio_query = question + " AND (mechanical heart valve OR microfluidic OR CKD creatinine OR PIV hemodynamics OR thrombogenicity)"
62
+ pubmed = search_pubmed(cardio_query, n=3)
63
+ scholar = search_scholar(question + " biomedical", n=3)
64
+ sources = pubmed + "\n\n" + scholar
65
+ response = client.chat.completions.create(
66
+ model="llama-3.3-70b-versatile",
67
+ messages=[
68
+ {"role":"system","content":"You are CardioLab AI built on Biomni from Stanford SNAP Lab. Expert in SJSU Biomedical Engineering. Always cite sources.\n\nCARDIOLAB KNOW-HOW:\n" + KNOWHOW},
69
+ {"role":"user","content":"Research question: " + question + "\n\nOnline sources found:\n" + sources[:3000]}
70
+ ],
71
+ max_tokens=800
72
+ )
73
+ return response.choices[0].message.content
74
 
75
  def piv_tool(velocity, shear, hr):
76
+ v = "HIGH - stenosis risk" if float(velocity)>2.0 else "NORMAL"
77
+ s = "HIGH - thrombosis risk" if float(shear)>10 else "ELEVATED - monitor" if float(shear)>5 else "NORMAL"
78
+ return "Velocity: "+str(velocity)+" m/s - "+v+"\nShear: "+str(shear)+" Pa - "+s+"\nHeart Rate: "+str(hr)+" bpm"
79
 
80
  def tgt_tool(tat, pf12, hemo, platelets, time):
81
  risk = sum([float(tat)>15, float(pf12)>2.0, float(hemo)>50, float(platelets)<150])
82
  overall = "HIGH THROMBOGENIC RISK" if risk>=3 else "MODERATE RISK" if risk>=2 else "LOW RISK"
83
+ return "TAT: "+str(tat)+"\nPF1.2: "+str(pf12)+"\nHemoglobin: "+str(hemo)+"\nPlatelets: "+str(platelets)+"\nTime: "+str(time)+" min\nResult: "+overall
84
 
85
  def upad_tool(r, g, b):
86
  creatinine = max(0, round(0.02*(float(r)-float(b))-0.5, 2))
87
  stage = "Normal" if creatinine<1.2 else "Borderline" if creatinine<1.5 else "Stage 2 CKD" if creatinine<3.0 else "Stage 3-4 CKD" if creatinine<6.0 else "Stage 5 CKD"
88
+ return "Creatinine: "+str(creatinine)+" mg/dL\nCKD Stage: "+stage+"\nConfirm with: Heska Element HT5"
89
 
90
  with gr.Blocks(title="CardioLab AI - SJSU") as demo:
91
  gr.Markdown("# CardioLab AI Agent")
92
+ gr.Markdown("### SJSU Biomedical Engineering | Built on Biomni (Stanford) | Llama 70B + PubMed + Semantic Scholar")
93
+ gr.Markdown("**Open Source** | GitHub: github.com/pranatechsol/Cardio-Lab-Ai")
94
+ with gr.Tab("Research Assistant"):
95
+ gr.Markdown("### Ask anything searches CardioLab papers + PubMed + Semantic Scholar")
96
+ q = gr.Textbox(label="Research question", placeholder="e.g. What are latest methods for MHV thrombogenicity detection?")
97
+ a = gr.Textbox(label="Answer with citations", lines=10)
98
+ gr.Button("Search & Answer").click(ask_agent, inputs=q, outputs=a)
99
  with gr.Tab("PIV Analysis"):
100
  gr.Markdown("### Analyze PIV flow data from Mock Circulatory Loop")
101
  v = gr.Number(label="Max Velocity m/s", value=1.8)