Saicharan21 commited on
Commit
2c0524b
·
verified ·
1 Parent(s): 803b2e8

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +56 -101
app.py CHANGED
@@ -1,20 +1,17 @@
1
  import gradio as gr
2
  import os, requests, io
3
- import matplotlib
4
- matplotlib.use('Agg')
5
- import matplotlib.pyplot as plt
6
- import matplotlib.patches as mpatches
7
- import numpy as np
8
  from groq import Groq
9
  from PIL import Image
10
 
11
  GROQ_KEY = os.environ.get('GROQ_API_KEY', '')
 
 
12
  KNOWHOW = 'MCL: Sylgard 184 PDMS 10:1 ratio 48hr cure green laser PIV 70bpm 5L/min. TGT: Arduino Uno Stepper Motor 150mL blood sampled at 0 20 40 60min measures TAT PF1.2 hemolysis platelets. uPAD: Jaffe reaction creatinine plus picric acid gives orange-red color normal 0.6-1.2 mg/dL CKD above 1.5. MHV: 27mm SJM Regent bileaflet also trileaflet monoleaflet pediatric.'
13
 
14
  CSS = '''
15
- body, .gradio-container { background: #f0f4f8 !important; color: #1a202c !important; }
16
  .tab-nav { background: #ffffff !important; border-bottom: 2px solid #e2e8f0 !important; padding: 0 10px !important; }
17
- .tab-nav button { background: #f7fafc !important; color: #2d3748 !important; border: 1px solid #e2e8f0 !important; border-radius: 8px 8px 0 0 !important; padding: 12px 18px !important; font-size: 0.9em !important; font-weight: 600 !important; margin-top: 6px !important; }
18
  .tab-nav button:hover { background: #ebf4ff !important; color: #1a237e !important; }
19
  .tab-nav button.selected { background: linear-gradient(135deg, #e63946, #c1121f) !important; color: #ffffff !important; font-weight: 700 !important; }
20
  button.primary { background: linear-gradient(135deg, #e63946 0%, #c1121f 100%) !important; color: white !important; border: none !important; border-radius: 8px !important; font-weight: 700 !important; }
@@ -96,86 +93,36 @@ def voice_chat(audio, history):
96
  history.append({'role':'assistant','content':'Voice error: '+str(e)})
97
  return history
98
 
99
- def generate_diagram(topic):
100
- t = topic.lower()
101
- fig, ax = plt.subplots(figsize=(12, 8))
102
- ax.set_xlim(0,12); ax.set_ylim(0,8); ax.axis('off')
103
- fig.patch.set_facecolor('#0d1b3e'); ax.set_facecolor('#0d1b3e')
104
- if 'tgt' in t or 'thrombogen' in t:
105
- ax.set_title('Thrombogenicity Tester (TGT) - SJSU CardioLab', color='white', fontsize=14, fontweight='bold', pad=15)
106
- boxes = [
107
- (0.5, 6.0, 2.0, 0.9, '#e63946', 'Arduino Uno'),
108
- (3.5, 6.0, 2.0, 0.9, '#4361ee', 'Motor Driver'),
109
- (6.5, 6.0, 2.0, 0.9, '#2ecc71', 'Stepper Motor'),
110
- (3.5, 3.5, 4.0, 2.0, '#1a2744', 'Test Chamber - 27mm SJM MHV - 150mL Blood'),
111
- (0.5, 1.0, 2.0, 0.9, '#e67e22', 'Heska HT5 Analyzer'),
112
- (9.0, 1.0, 2.0, 0.9, '#9b59b6', 'Data Logger'),
113
- ]
114
- for x,y,w,h,c,lbl in boxes:
115
- ax.add_patch(mpatches.FancyBboxPatch((x,y),w,h,boxstyle='round,pad=0.1',facecolor=c,edgecolor='white',linewidth=2))
116
- ax.text(x+w/2, y+h/2, lbl, ha='center', va='center', color='white', fontsize=8, fontweight='bold')
117
- for x1,y1,x2,y2 in [(2.5,6.45,3.5,6.45),(5.5,6.45,6.5,6.45),(7.5,6.0,7.5,5.5),(5.5,3.5,5.5,2.3),(4.0,3.5,2.0,1.9),(8.0,3.5,10.0,1.9)]:
118
- ax.annotate('',xy=(x2,y2),xytext=(x1,y1),arrowprops=dict(arrowstyle='->',color='#7eb8f7',lw=2))
119
- for x,y,txt in [(2.9,6.7,'Signal'),(6.0,6.7,'Drive'),(7.8,5.7,'Rotate'),(6.0,2.9,'Sample'),(2.8,2.7,'Analyze'),(9.2,2.7,'Record')]:
120
- ax.text(x,y,txt,color='#a8b2d8',fontsize=7,ha='center')
121
- ax.text(6, 0.4, 'Sample at: 0 min | 20 min | 40 min | 60 min', color='#e63946', fontsize=9, ha='center', fontweight='bold')
122
- elif 'mcl' in t or 'piv' in t or 'circulatory' in t:
123
- ax.set_title('Mock Circulatory Loop + PIV System - SJSU CardioLab', color='white', fontsize=13, fontweight='bold', pad=15)
124
- lx = [2,4,6,8,10,10,8,6,4,2,2]; ly = [4,6,6.5,6,4,3,2,1.5,2,3,4]
125
- ax.plot(lx,ly,color='#4361ee',linewidth=4)
126
- for x,y,w,h,c,lbl in [(4.8,5.8,2.0,0.8,'#e63946','MHV Test Section'),(0.8,3.5,1.5,0.8,'#2ecc71','Pump'),(9.5,3.5,1.5,0.8,'#e67e22','Compliance'),(4.2,1.2,2.0,0.8,'#9b59b6','Reservoir')]:
127
- ax.add_patch(mpatches.FancyBboxPatch((x,y),w,h,boxstyle='round,pad=0.1',facecolor=c,edgecolor='white',linewidth=2))
128
- ax.text(x+w/2,y+h/2,lbl,ha='center',va='center',color='white',fontsize=7,fontweight='bold')
129
- ax.add_patch(mpatches.FancyBboxPatch((4.8,7.4),2.0,0.5,boxstyle='round,pad=0.05',facecolor='#00cc44',edgecolor='white',linewidth=1))
130
- ax.text(5.8,7.65,'GREEN LASER',ha='center',va='center',color='black',fontsize=8,fontweight='bold')
131
- ax.annotate('',xy=(5.8,6.6),xytext=(5.8,7.4),arrowprops=dict(arrowstyle='->',color='#00ff44',lw=3))
132
- ax.add_patch(mpatches.FancyBboxPatch((9.5,5.3),1.8,0.9,boxstyle='round,pad=0.05',facecolor='#1a2744',edgecolor='#7eb8f7',linewidth=2))
133
- ax.text(10.4,5.75,'PIV Camera',ha='center',va='center',color='white',fontsize=7,fontweight='bold')
134
- ax.text(6,0.4,'70 bpm | 5 L/min | 80-120 mmHg',color='#7eb8f7',fontsize=9,ha='center',fontweight='bold')
135
- elif 'upad' in t or 'ckd' in t or 'creatinine' in t:
136
- ax.set_title('uPAD Fabrication and CKD Detection - SJSU CardioLab', color='white', fontsize=13, fontweight='bold', pad=15)
137
- steps = [('1.Whatman Paper','#4361ee'),('2.Wax Print','#e67e22'),('3.Heat 120C','#f1c40f'),('4.Add Reagent','#2ecc71'),('5.Apply Sample','#e63946'),('6.RGB Capture','#9b59b6')]
138
- for i,(lbl,c) in enumerate(steps):
139
- cx = 1.0+i*1.8
140
- ax.add_patch(plt.Circle((cx,6.2),0.75,color=c,zorder=5))
141
- ax.text(cx,6.2,lbl,ha='center',va='center',color='white',fontsize=6.5,fontweight='bold',zorder=6)
142
- if i<len(steps)-1: ax.annotate('',xy=(cx+1.05,6.2),xytext=(cx+0.75,6.2),arrowprops=dict(arrowstyle='->',color='white',lw=2))
143
- stages = [('Normal','<1.2','#27ae60'),('Borderline','1.2-1.5','#f1c40f'),('Stage 2','1.5-3.0','#e67e22'),('Stage 3-4','3.0-6.0','#e74c3c'),('Stage 5','>6.0','#922b21')]
144
- for i,(s,r,c) in enumerate(stages):
145
- ax.add_patch(mpatches.FancyBboxPatch((0.3+i*2.3,1.5),2.0,2.8,boxstyle='round,pad=0.1',facecolor=c,edgecolor='white',linewidth=2,alpha=0.85))
146
- ax.text(1.3+i*2.3,3.1,s,ha='center',color='white',fontsize=9,fontweight='bold')
147
- ax.text(1.3+i*2.3,2.6,r+' mg/dL',ha='center',color='white',fontsize=8)
148
- ax.text(6,1.0,'Creatinine Level (mg/dL)',color='#7eb8f7',fontsize=9,ha='center',fontweight='bold')
149
- elif 'mhv' in t or 'valve' in t:
150
- ax.set_title('Mechanical Heart Valve (MHV) - 27mm SJM Regent Bileaflet', color='white', fontsize=13, fontweight='bold', pad=15)
151
- ax.add_patch(plt.Circle((6,4),3.0,color='#2d3a5a',zorder=1))
152
- ax.add_patch(plt.Circle((6,4),2.8,color='#1a2744',zorder=2))
153
- ax.add_patch(plt.Circle((6,4),3.0,color='#7eb8f7',fill=False,linewidth=4,zorder=3))
154
- ax.add_patch(mpatches.FancyBboxPatch((4.3,2.8),1.4,2.4,boxstyle='round,pad=0.1',facecolor='#e63946',edgecolor='white',linewidth=2,zorder=4))
155
- ax.add_patch(mpatches.FancyBboxPatch((6.3,2.8),1.4,2.4,boxstyle='round,pad=0.1',facecolor='#e63946',edgecolor='white',linewidth=2,zorder=4))
156
- ax.text(5.0,4.0,'Leaflet 1',ha='center',va='center',color='white',fontsize=8,fontweight='bold',zorder=5)
157
- ax.text(7.0,4.0,'Leaflet 2',ha='center',va='center',color='white',fontsize=8,fontweight='bold',zorder=5)
158
- ax.annotate('',xy=(6,7.5),xytext=(6,7.0),arrowprops=dict(arrowstyle='->',color='#4361ee',lw=4))
159
- ax.text(6,7.7,'Blood Flow',color='#4361ee',ha='center',fontsize=10,fontweight='bold')
160
- for i,(spec) in enumerate(['Diameter: 27mm','Material: Pyrolytic Carbon','Type: Bileaflet','Opening Angle: 85 deg']):
161
- ax.text(0.3,2.0+i*0.7,'* '+spec,color='#a8b2d8',fontsize=8)
162
- else:
163
- ax.set_title('CardioLab AI - Research Overview - SJSU Biomedical Engineering', color='white', fontsize=12, fontweight='bold', pad=15)
164
- for i,(x,c,title,items) in enumerate([(2.0,'#e63946','MHV + PIV',['MCL Loop','PIV Laser','FSI COMSOL']),(5.5,'#4361ee','Thrombosis',['TGT Circuit','TAT PF1.2','Hemolysis']),(9.0,'#2ecc71','CKD Diag.',['uPAD Paper','Jaffe Rxn','Creatinine'])]):
165
- ax.add_patch(mpatches.FancyBboxPatch((x-1.2,4.5),2.8,3.0,boxstyle='round,pad=0.2',facecolor=c,edgecolor='white',linewidth=2,alpha=0.9))
166
- ax.text(x+0.2,7.0,title,ha='center',color='white',fontsize=10,fontweight='bold')
167
- for j,it in enumerate(items): ax.text(x+0.2,6.3-j*0.6,'* '+it,ha='center',color='white',fontsize=8)
168
- ax.add_patch(mpatches.FancyBboxPatch((0.5,1.0),11.0,3.0,boxstyle='round,pad=0.2',facecolor='#1a2744',edgecolor='#7eb8f7',linewidth=2))
169
- ax.text(6,3.7,'KEY EQUIPMENT',ha='center',color='#7eb8f7',fontsize=10,fontweight='bold')
170
- equip = ['27mm SJM Regent MHV','Arduino Uno + Stepper Motor','Time-resolved PIV Green Laser','Sylgard 184 Transparent MCL','Heska Element HT5 Analyzer']
171
- for i,eq in enumerate(equip): ax.text(1.0+(i%2)*6,3.0-(i//2)*0.7,'* '+eq,color='#e2e8f0',fontsize=8)
172
- buf = io.BytesIO()
173
- plt.tight_layout()
174
- plt.savefig(buf,format='png',facecolor=fig.get_facecolor(),bbox_inches='tight',dpi=120)
175
- buf.seek(0)
176
- img = Image.open(buf)
177
- plt.close()
178
- return img
179
 
180
  def piv_tool(velocity, shear, hr):
181
  v = 'HIGH - stenosis risk' if float(velocity)>2.0 else 'NORMAL'
@@ -194,9 +141,9 @@ def upad_tool(r,g,b):
194
  return 'uPAD RESULT'+chr(10)+'Creatinine: '+str(c)+' mg/dL'+chr(10)+'CKD Stage: '+s
195
 
196
  with gr.Blocks(title='CardioLab AI', css=CSS) as demo:
197
- gr.HTML('<div style="background:linear-gradient(135deg,#1a237e,#b71c1c);padding:25px;text-align:center;border-radius:12px 12px 0 0;"><div style="font-size:2.8em;font-weight:900;color:#fff;letter-spacing:3px;">❤️ CardioLab AI</div></div>')
198
  with gr.Tabs():
199
- with gr.Tab('💬 Chat'):
200
  chatbot = gr.Chatbot(label='', height=450)
201
  with gr.Row():
202
  msg_box = gr.Textbox(placeholder='Ask anything about CardioLab research...', label='', lines=2, scale=4)
@@ -206,7 +153,7 @@ with gr.Blocks(title='CardioLab AI', css=CSS) as demo:
206
  send_btn.click(research_chat, inputs=[msg_box, chatbot], outputs=[msg_box, chatbot])
207
  msg_box.submit(research_chat, inputs=[msg_box, chatbot], outputs=[msg_box, chatbot])
208
  clear_btn.click(lambda: ([], ''), outputs=[chatbot, msg_box])
209
- with gr.Tab('🎙️ Voice'):
210
  gr.Markdown('### Speak your question - Groq Whisper AI')
211
  voice_chatbot = gr.Chatbot(label='', height=350)
212
  audio_input = gr.Audio(sources=['microphone'], type='filepath', label='Record Question')
@@ -215,22 +162,30 @@ with gr.Blocks(title='CardioLab AI', css=CSS) as demo:
215
  voice_clear = gr.Button('Clear', variant='secondary')
216
  voice_btn.click(voice_chat, inputs=[audio_input, voice_chatbot], outputs=voice_chatbot)
217
  voice_clear.click(lambda: [], outputs=voice_chatbot)
218
- with gr.Tab('🔍 Papers'):
219
- gr.Markdown('### Search research papers - verified links only')
220
  with gr.Row():
221
  search_input = gr.Textbox(placeholder='e.g. mechanical heart valve thrombogenicity', label='Research Topic', scale=4)
222
  search_btn = gr.Button('Search', variant='primary', scale=1)
223
  search_output = gr.Textbox(label='Verified Results', lines=18)
224
  search_btn.click(quick_search, inputs=search_input, outputs=search_output)
225
  search_input.submit(quick_search, inputs=search_input, outputs=search_output)
226
- with gr.Tab('🎨 Diagrams'):
227
- gr.Markdown('### Real visual diagrams - try: TGT setup | MCL PIV | uPAD CKD | MHV valve | CardioLab overview')
 
228
  with gr.Row():
229
- diagram_input = gr.Textbox(placeholder='e.g. TGT setup', label='What to diagram', scale=4)
230
- diagram_btn = gr.Button('Generate', variant='primary', scale=1)
231
- diagram_output = gr.Image(label='Visual Diagram', type='pil')
232
- diagram_btn.click(generate_diagram, inputs=diagram_input, outputs=diagram_output)
233
- with gr.Tab('📊 PIV'):
 
 
 
 
 
 
 
 
234
  with gr.Row():
235
  with gr.Column():
236
  v=gr.Number(label='Max Velocity m/s', value=1.8)
@@ -238,7 +193,7 @@ with gr.Blocks(title='CardioLab AI', css=CSS) as demo:
238
  h=gr.Number(label='Heart Rate bpm', value=72)
239
  piv_out=gr.Textbox(label='Result', lines=5)
240
  gr.Button('Analyze PIV', variant='primary').click(piv_tool,inputs=[v,s,h],outputs=piv_out)
241
- with gr.Tab('🩸 TGT'):
242
  with gr.Row():
243
  with gr.Column():
244
  t1=gr.Number(label='TAT ng/mL', value=18)
@@ -248,7 +203,7 @@ with gr.Blocks(title='CardioLab AI', css=CSS) as demo:
248
  t5=gr.Number(label='Time minutes', value=40)
249
  out2=gr.Textbox(label='Result', lines=8)
250
  gr.Button('Analyze TGT', variant='primary').click(tgt_tool,inputs=[t1,t2,t3,t4,t5],outputs=out2)
251
- with gr.Tab('🧪 uPAD'):
252
  with gr.Row():
253
  with gr.Column():
254
  r=gr.Number(label='R value', value=210)
 
1
  import gradio as gr
2
  import os, requests, io
 
 
 
 
 
3
  from groq import Groq
4
  from PIL import Image
5
 
6
  GROQ_KEY = os.environ.get('GROQ_API_KEY', '')
7
+ HF_TOKEN = os.environ.get('HF_TOKEN', '')
8
+
9
  KNOWHOW = 'MCL: Sylgard 184 PDMS 10:1 ratio 48hr cure green laser PIV 70bpm 5L/min. TGT: Arduino Uno Stepper Motor 150mL blood sampled at 0 20 40 60min measures TAT PF1.2 hemolysis platelets. uPAD: Jaffe reaction creatinine plus picric acid gives orange-red color normal 0.6-1.2 mg/dL CKD above 1.5. MHV: 27mm SJM Regent bileaflet also trileaflet monoleaflet pediatric.'
10
 
11
  CSS = '''
12
+ body, .gradio-container { background: #f0f4f8 !important; }
13
  .tab-nav { background: #ffffff !important; border-bottom: 2px solid #e2e8f0 !important; padding: 0 10px !important; }
14
+ .tab-nav button { background: #f7fafc !important; color: #2d3748 !important; border: 1px solid #e2e8f0 !important; border-radius: 8px 8px 0 0 !important; padding: 12px 18px !important; font-weight: 600 !important; margin-top: 6px !important; }
15
  .tab-nav button:hover { background: #ebf4ff !important; color: #1a237e !important; }
16
  .tab-nav button.selected { background: linear-gradient(135deg, #e63946, #c1121f) !important; color: #ffffff !important; font-weight: 700 !important; }
17
  button.primary { background: linear-gradient(135deg, #e63946 0%, #c1121f 100%) !important; color: white !important; border: none !important; border-radius: 8px !important; font-weight: 700 !important; }
 
93
  history.append({'role':'assistant','content':'Voice error: '+str(e)})
94
  return history
95
 
96
+ def generate_image(prompt):
97
+ if not prompt.strip(): return None, 'Please enter a description.'
98
+ if not HF_TOKEN: return None, 'Error: Add HF_TOKEN to Space Settings Secrets.'
99
+ try:
100
+ # Add biomedical context to prompt
101
+ full_prompt = 'Highly detailed scientific biomedical illustration of: ' + prompt + ', professional medical diagram, high quality, detailed, photorealistic'
102
+ headers = {'Authorization': 'Bearer ' + HF_TOKEN}
103
+ payload = {'inputs': full_prompt}
104
+ # Use FLUX.1-schnell - best free model on HuggingFace
105
+ r = requests.post(
106
+ 'https://api-inference.huggingface.co/models/black-forest-labs/FLUX.1-schnell',
107
+ headers=headers, json=payload, timeout=60
108
+ )
109
+ if r.status_code == 200:
110
+ img = Image.open(io.BytesIO(r.content))
111
+ return img, 'Image generated successfully!'
112
+ elif r.status_code == 503:
113
+ # Model loading - try stable diffusion
114
+ r2 = requests.post(
115
+ 'https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0',
116
+ headers=headers, json=payload, timeout=60
117
+ )
118
+ if r2.status_code == 200:
119
+ img = Image.open(io.BytesIO(r2.content))
120
+ return img, 'Image generated!'
121
+ return None, 'Model loading, please wait 30 seconds and try again.'
122
+ else:
123
+ return None, 'Error: '+str(r.status_code)+' '+r.text[:200]
124
+ except Exception as e:
125
+ return None, 'Error: '+str(e)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
  def piv_tool(velocity, shear, hr):
128
  v = 'HIGH - stenosis risk' if float(velocity)>2.0 else 'NORMAL'
 
141
  return 'uPAD RESULT'+chr(10)+'Creatinine: '+str(c)+' mg/dL'+chr(10)+'CKD Stage: '+s
142
 
143
  with gr.Blocks(title='CardioLab AI', css=CSS) as demo:
144
+ gr.HTML('<div style="background:linear-gradient(135deg,#1a237e,#b71c1c);padding:25px;text-align:center;border-radius:12px 12px 0 0 "><div style="font-size:2.8em;font-weight:900;color:#fff;letter-spacing:3px">CardioLab AI</div></div>')
145
  with gr.Tabs():
146
+ with gr.Tab('Chat'):
147
  chatbot = gr.Chatbot(label='', height=450)
148
  with gr.Row():
149
  msg_box = gr.Textbox(placeholder='Ask anything about CardioLab research...', label='', lines=2, scale=4)
 
153
  send_btn.click(research_chat, inputs=[msg_box, chatbot], outputs=[msg_box, chatbot])
154
  msg_box.submit(research_chat, inputs=[msg_box, chatbot], outputs=[msg_box, chatbot])
155
  clear_btn.click(lambda: ([], ''), outputs=[chatbot, msg_box])
156
+ with gr.Tab('Voice'):
157
  gr.Markdown('### Speak your question - Groq Whisper AI')
158
  voice_chatbot = gr.Chatbot(label='', height=350)
159
  audio_input = gr.Audio(sources=['microphone'], type='filepath', label='Record Question')
 
162
  voice_clear = gr.Button('Clear', variant='secondary')
163
  voice_btn.click(voice_chat, inputs=[audio_input, voice_chatbot], outputs=voice_chatbot)
164
  voice_clear.click(lambda: [], outputs=voice_chatbot)
165
+ with gr.Tab('Papers'):
 
166
  with gr.Row():
167
  search_input = gr.Textbox(placeholder='e.g. mechanical heart valve thrombogenicity', label='Research Topic', scale=4)
168
  search_btn = gr.Button('Search', variant='primary', scale=1)
169
  search_output = gr.Textbox(label='Verified Results', lines=18)
170
  search_btn.click(quick_search, inputs=search_input, outputs=search_output)
171
  search_input.submit(quick_search, inputs=search_input, outputs=search_output)
172
+ with gr.Tab('AI Image Generator'):
173
+ gr.Markdown('### Real AI Image Generation using FLUX.1 - Free HuggingFace Model')
174
+ gr.Markdown('**Describe any biomedical image and AI will generate it**')
175
  with gr.Row():
176
+ img_prompt = gr.Textbox(
177
+ placeholder='e.g. mechanical heart valve bileaflet design | uPAD microfluidic device | blood flow through valve | Arduino circuit for TGT',
178
+ label='Describe the image you want',
179
+ lines=3,
180
+ scale=4
181
+ )
182
+ with gr.Column(scale=1):
183
+ img_btn = gr.Button('Generate Image', variant='primary')
184
+ img_status = gr.Textbox(label='Status', lines=2)
185
+ img_output = gr.Image(label='Generated Image', type='pil', height=500)
186
+ img_btn.click(generate_image, inputs=img_prompt, outputs=[img_output, img_status])
187
+ gr.Markdown('**Try:** `27mm bileaflet mechanical heart valve` | `microfluidic paper device for CKD testing` | `blood flow visualization PIV` | `Arduino circuit with stepper motor`')
188
+ with gr.Tab('PIV'):
189
  with gr.Row():
190
  with gr.Column():
191
  v=gr.Number(label='Max Velocity m/s', value=1.8)
 
193
  h=gr.Number(label='Heart Rate bpm', value=72)
194
  piv_out=gr.Textbox(label='Result', lines=5)
195
  gr.Button('Analyze PIV', variant='primary').click(piv_tool,inputs=[v,s,h],outputs=piv_out)
196
+ with gr.Tab('TGT'):
197
  with gr.Row():
198
  with gr.Column():
199
  t1=gr.Number(label='TAT ng/mL', value=18)
 
203
  t5=gr.Number(label='Time minutes', value=40)
204
  out2=gr.Textbox(label='Result', lines=8)
205
  gr.Button('Analyze TGT', variant='primary').click(tgt_tool,inputs=[t1,t2,t3,t4,t5],outputs=out2)
206
+ with gr.Tab('uPAD'):
207
  with gr.Row():
208
  with gr.Column():
209
  r=gr.Number(label='R value', value=210)