IFMedTechdemo commited on
Commit
63499c7
·
verified ·
1 Parent(s): f577c36

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +322 -0
app.py ADDED
@@ -0,0 +1,322 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ from clinical_ner import ClinicalNERProcessor
4
+
5
+ # Initialize the NER processor
6
+ ner_processor = ClinicalNERProcessor(use_pos=True, use_anatomy=True)
7
+
8
+ # Example text
9
+ EXAMPLE_TEXT = "Patient presents with pain in the left ventricle and elevated cardiac enzymes. The heart shows signs of inflammation."
10
+
11
+ def format_entities(entities):
12
+ """Format entities for display"""
13
+ if not entities:
14
+ return "No entities found."
15
+
16
+ result = []
17
+ for i, entity in enumerate(entities, 1):
18
+ result.append(f"{i}. **{entity['word']}** - Type: {entity['entity_group']} (Score: {entity['score']:.4f})")
19
+ return "\n".join(result)
20
+
21
+ def format_pos_tags(pos_tags):
22
+ """Format POS tags for display"""
23
+ if not pos_tags:
24
+ return "No POS tags found."
25
+
26
+ result = []
27
+ for i, tag in enumerate(pos_tags, 1):
28
+ result.append(f"{i}. **{tag['token']}** - POS: {tag['pos']}, Tag: {tag['tag']}, Lemma: {tag['lemma']}")
29
+ return "\n".join(result)
30
+
31
+ def clinical_ner_basic(text):
32
+ """Clinical NER only"""
33
+ if not text.strip():
34
+ return "Please enter some text."
35
+ try:
36
+ entities = ner_processor.basic_ner(text)
37
+ return format_entities(entities)
38
+ except Exception as e:
39
+ return f"Error: {str(e)}"
40
+
41
+ def clinical_ner_prolog(text):
42
+ """Clinical NER as Prolog facts"""
43
+ if not text.strip():
44
+ return "Please enter some text."
45
+ try:
46
+ prolog_facts = ner_processor.prolog_ner(text)
47
+ return prolog_facts if prolog_facts else "No entities found."
48
+ except Exception as e:
49
+ return f"Error: {str(e)}"
50
+
51
+ def anatomy_ner_basic(text):
52
+ """Anatomy NER only"""
53
+ if not text.strip():
54
+ return "Please enter some text."
55
+ try:
56
+ entities = ner_processor.anatomy_ner(text)
57
+ return format_entities(entities)
58
+ except Exception as e:
59
+ return f"Error: {str(e)}"
60
+
61
+ def anatomy_ner_prolog(text):
62
+ """Anatomy NER as Prolog facts"""
63
+ if not text.strip():
64
+ return "Please enter some text."
65
+ try:
66
+ prolog_facts = ner_processor.prolog_anatomy(text)
67
+ return prolog_facts if prolog_facts else "No entities found."
68
+ except Exception as e:
69
+ return f"Error: {str(e)}"
70
+
71
+ def pos_tagging_basic(text):
72
+ """POS tagging only"""
73
+ if not text.strip():
74
+ return "Please enter some text."
75
+ try:
76
+ pos_tags = ner_processor.pos_tagging(text)
77
+ return format_pos_tags(pos_tags)
78
+ except Exception as e:
79
+ return f"Error: {str(e)}"
80
+
81
+ def pos_tagging_prolog(text):
82
+ """POS tagging as Prolog facts"""
83
+ if not text.strip():
84
+ return "Please enter some text."
85
+ try:
86
+ prolog_facts = ner_processor.prolog_pos(text)
87
+ return prolog_facts if prolog_facts else "No POS tags found."
88
+ except Exception as e:
89
+ return f"Error: {str(e)}"
90
+
91
+ def combined_analysis(text):
92
+ """Combined analysis"""
93
+ if not text.strip():
94
+ return "Please enter some text.", "Please enter some text.", "Please enter some text."
95
+ try:
96
+ result = ner_processor.combined_analysis(text)
97
+ clinical = format_entities(result['clinical_entities'])
98
+ anatomy = format_entities(result['anatomy_entities'])
99
+ pos = format_pos_tags(result['pos_tags'])
100
+ return clinical, anatomy, pos
101
+ except Exception as e:
102
+ error_msg = f"Error: {str(e)}"
103
+ return error_msg, error_msg, error_msg
104
+
105
+ def combined_prolog(text):
106
+ """Combined analysis as Prolog facts"""
107
+ if not text.strip():
108
+ return "Please enter some text."
109
+ try:
110
+ prolog_facts = ner_processor.prolog_combined(text)
111
+ return prolog_facts if prolog_facts else "No results found."
112
+ except Exception as e:
113
+ return f"Error: {str(e)}"
114
+
115
+ # Create Gradio interface with tabs
116
+ with gr.Blocks(title="Clinical NER & Anatomy Detection", theme=gr.themes.Soft()) as demo:
117
+ gr.Markdown(
118
+ """
119
+ # Clinical NER, Anatomy Detection, and POS Tagging
120
+
121
+ This application provides Named Entity Recognition (NER) for clinical text,
122
+ anatomy detection, and Part-of-Speech (POS) tagging using state-of-the-art models:
123
+ - **Clinical NER**: Bio_ClinicalBERT
124
+ - **Anatomy NER**: OpenMed AnatomyDetect
125
+ - **POS Tagging**: spaCy en_core_web_sm
126
+ """
127
+ )
128
+
129
+ with gr.Tabs():
130
+ # Tab 1: Clinical NER
131
+ with gr.Tab("Clinical NER"):
132
+ with gr.Row():
133
+ with gr.Column():
134
+ clinical_input = gr.Textbox(
135
+ label="Enter Clinical Text",
136
+ placeholder="Enter medical text here...",
137
+ lines=5,
138
+ value=EXAMPLE_TEXT
139
+ )
140
+ clinical_format = gr.Radio(
141
+ choices=["Basic", "Prolog"],
142
+ value="Basic",
143
+ label="Output Format"
144
+ )
145
+ clinical_btn = gr.Button("Extract Clinical Entities", variant="primary")
146
+
147
+ with gr.Column():
148
+ clinical_output = gr.Textbox(
149
+ label="Clinical Entities",
150
+ lines=15,
151
+ show_copy_button=True
152
+ )
153
+
154
+ def clinical_ner_process(text, format_type):
155
+ if format_type == "Basic":
156
+ return clinical_ner_basic(text)
157
+ else:
158
+ return clinical_ner_prolog(text)
159
+
160
+ clinical_btn.click(
161
+ fn=clinical_ner_process,
162
+ inputs=[clinical_input, clinical_format],
163
+ outputs=clinical_output
164
+ )
165
+
166
+ # Tab 2: Anatomy NER
167
+ with gr.Tab("Anatomy Detection"):
168
+ with gr.Row():
169
+ with gr.Column():
170
+ anatomy_input = gr.Textbox(
171
+ label="Enter Clinical Text",
172
+ placeholder="Enter medical text here...",
173
+ lines=5,
174
+ value=EXAMPLE_TEXT
175
+ )
176
+ anatomy_format = gr.Radio(
177
+ choices=["Basic", "Prolog"],
178
+ value="Basic",
179
+ label="Output Format"
180
+ )
181
+ anatomy_btn = gr.Button("Detect Anatomy", variant="primary")
182
+
183
+ with gr.Column():
184
+ anatomy_output = gr.Textbox(
185
+ label="Anatomy Entities",
186
+ lines=15,
187
+ show_copy_button=True
188
+ )
189
+
190
+ def anatomy_ner_process(text, format_type):
191
+ if format_type == "Basic":
192
+ return anatomy_ner_basic(text)
193
+ else:
194
+ return anatomy_ner_prolog(text)
195
+
196
+ anatomy_btn.click(
197
+ fn=anatomy_ner_process,
198
+ inputs=[anatomy_input, anatomy_format],
199
+ outputs=anatomy_output
200
+ )
201
+
202
+ # Tab 3: POS Tagging
203
+ with gr.Tab("POS Tagging"):
204
+ with gr.Row():
205
+ with gr.Column():
206
+ pos_input = gr.Textbox(
207
+ label="Enter Text",
208
+ placeholder="Enter text here...",
209
+ lines=5,
210
+ value=EXAMPLE_TEXT
211
+ )
212
+ pos_format = gr.Radio(
213
+ choices=["Basic", "Prolog"],
214
+ value="Basic",
215
+ label="Output Format"
216
+ )
217
+ pos_btn = gr.Button("Tag POS", variant="primary")
218
+
219
+ with gr.Column():
220
+ pos_output = gr.Textbox(
221
+ label="POS Tags",
222
+ lines=15,
223
+ show_copy_button=True
224
+ )
225
+
226
+ def pos_process(text, format_type):
227
+ if format_type == "Basic":
228
+ return pos_tagging_basic(text)
229
+ else:
230
+ return pos_tagging_prolog(text)
231
+
232
+ pos_btn.click(
233
+ fn=pos_process,
234
+ inputs=[pos_input, pos_format],
235
+ outputs=pos_output
236
+ )
237
+
238
+ # Tab 4: Combined Analysis
239
+ with gr.Tab("Combined Analysis"):
240
+ with gr.Row():
241
+ with gr.Column():
242
+ combined_input = gr.Textbox(
243
+ label="Enter Clinical Text",
244
+ placeholder="Enter medical text here...",
245
+ lines=5,
246
+ value=EXAMPLE_TEXT
247
+ )
248
+ combined_format = gr.Radio(
249
+ choices=["Basic (Separated)", "Prolog (Combined)"],
250
+ value="Basic (Separated)",
251
+ label="Output Format"
252
+ )
253
+ combined_btn = gr.Button("Analyze All", variant="primary")
254
+
255
+ with gr.Row():
256
+ with gr.Column():
257
+ combined_clinical = gr.Textbox(
258
+ label="Clinical Entities",
259
+ lines=10,
260
+ show_copy_button=True,
261
+ visible=True
262
+ )
263
+
264
+ with gr.Column():
265
+ combined_anatomy = gr.Textbox(
266
+ label="Anatomy Entities",
267
+ lines=10,
268
+ show_copy_button=True,
269
+ visible=True
270
+ )
271
+
272
+ with gr.Column():
273
+ combined_pos = gr.Textbox(
274
+ label="POS Tags",
275
+ lines=10,
276
+ show_copy_button=True,
277
+ visible=True
278
+ )
279
+
280
+ combined_prolog_output = gr.Textbox(
281
+ label="Combined Prolog Output",
282
+ lines=20,
283
+ show_copy_button=True,
284
+ visible=False
285
+ )
286
+
287
+ def combined_process(text, format_type):
288
+ if format_type == "Basic (Separated)":
289
+ clinical, anatomy, pos = combined_analysis(text)
290
+ return {
291
+ combined_clinical: gr.update(value=clinical, visible=True),
292
+ combined_anatomy: gr.update(value=anatomy, visible=True),
293
+ combined_pos: gr.update(value=pos, visible=True),
294
+ combined_prolog_output: gr.update(visible=False)
295
+ }
296
+ else:
297
+ prolog = combined_prolog(text)
298
+ return {
299
+ combined_clinical: gr.update(visible=False),
300
+ combined_anatomy: gr.update(visible=False),
301
+ combined_pos: gr.update(visible=False),
302
+ combined_prolog_output: gr.update(value=prolog, visible=True)
303
+ }
304
+
305
+ combined_btn.click(
306
+ fn=combined_process,
307
+ inputs=[combined_input, combined_format],
308
+ outputs=[combined_clinical, combined_anatomy, combined_pos, combined_prolog_output]
309
+ )
310
+
311
+ gr.Markdown(
312
+ """
313
+ ---
314
+ ### Models Used:
315
+ - Clinical NER: `samrawal/bert-base-uncased_clinical-ner`
316
+ - Anatomy Detection: `OpenMed/OpenMed-NER-AnatomyDetect-BioPatient-108M`
317
+ - POS Tagging: spaCy `en_core_web_sm`
318
+ """
319
+ )
320
+
321
+ if __name__ == "__main__":
322
+ demo.launch()