Feri007 commited on
Commit
6bb8e8d
·
verified ·
1 Parent(s): 69927d9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -270
app.py CHANGED
@@ -1,271 +1,14 @@
1
- import gradio as gr
2
- import json
3
- from collections import defaultdict
4
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
5
- from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
6
- from reportlab.lib import colors
7
- from reportlab.lib.enums import TA_RIGHT
8
- from reportlab.pdfbase import pdfmetrics
9
- from reportlab.pdfbase.ttfonts import TTFont
10
- import difflib
11
-
12
- # -------------------------------------------------------
13
- # بارگذاری داده‌ها
14
- # -------------------------------------------------------
15
- def load_guidelines(json_file_path):
16
- try:
17
- with open(json_file_path, 'r', encoding='utf-8') as file:
18
- data = json.load(file)
19
- return data['guidelines']
20
- except Exception as e:
21
- print(f"Error loading JSON file: {e}")
22
- return []
23
-
24
- guidelines = load_guidelines("enriched_guidelines_with_lab_findings_completed.json")
25
-
26
- # -------------------------------------------------------
27
- # تحلیل علائم
28
- # -------------------------------------------------------
29
- def analyze_symptoms(symptoms_input, guidelines):
30
- symptoms_input = [s.lower().strip() for s in symptoms_input.split(',') if s.strip()]
31
- matched_diseases = defaultdict(lambda: {'score': 0, 'matched_symptoms': [], 'alarm_matched': False, 'full_guideline_data': None})
32
-
33
- key_symptoms_weights = {
34
- 'signs of liver decompensation': 2.0,
35
- 'bloody diarrhea': 1.5,
36
- 'fever (≥38°c)': 1.3,
37
- 'abdominal pain (sudden or progressive)': 1.2,
38
- 'abdominal distension (ascites)': 1.2,
39
- 'back pain': 1.1,
40
- 'dyspepsia': 1.0,
41
- 'asymptomatic (incidental finding)': 0.8
42
- }
43
-
44
- for guideline in guidelines:
45
- disease_name = guideline.get('condition_name', 'Unknown')
46
- icd_code = guideline.get('icd_code', 'N/A')
47
- guideline_symptoms = [s.lower().strip() for s in guideline.get('symptoms', [])]
48
- alarm_features = guideline.get('alarm_features', {})
49
-
50
- matched_symptoms = [s for s in symptoms_input if s in guideline_symptoms]
51
- if matched_symptoms:
52
- score = sum([key_symptoms_weights.get(symptom, 1.0) for symptom in matched_symptoms])
53
- is_alarm_matched = any(
54
- symptom.lower() in str(alarm_features.values()).lower()
55
- for symptom in matched_symptoms
56
- )
57
- matched_diseases[disease_name] = {
58
- 'score': score,
59
- 'icd_code': icd_code,
60
- 'matched_symptoms': matched_symptoms,
61
- 'alarm_matched': is_alarm_matched,
62
- 'full_guideline_data': guideline
63
- }
64
-
65
- results = []
66
- total_score = sum(d['score'] for d in matched_diseases.values())
67
-
68
- if total_score == 0:
69
- return []
70
-
71
- for disease_name, data in matched_diseases.items():
72
- probability = (data['score'] / total_score) * 100
73
- if data['alarm_matched']:
74
- probability *= 1.5
75
- probability = max(min(probability, 100), 5)
76
-
77
- results.append({
78
- 'disease_name': disease_name,
79
- 'icd_code': data['icd_code'],
80
- 'probability': round(probability, 2),
81
- 'matched_symptoms': ', '.join(data['matched_symptoms']),
82
- 'full_data': data['full_guideline_data']
83
- })
84
-
85
- results.sort(key=lambda x: x['probability'], reverse=True)
86
- return results
87
-
88
- # -------------------------------------------------------
89
- # تحلیل آزمایش‌ها
90
- # -------------------------------------------------------
91
- synonyms = {
92
- "ast": ["ast", "sgot", "aspartate aminotransferase"],
93
- "alt": ["alt", "sgpt", "alanine aminotransferase"],
94
- "serum glucose": ["serum glucose", "glucose", "blood sugar"],
95
- "bilirubin": ["bilirubin", "total bilirubin"],
96
- "alkaline phosphatase": ["alkaline phosphatase", "alp"],
97
- "albumin": ["albumin", "serum albumin"],
98
- "prothrombin time": ["prothrombin time", "pt", "protime"],
99
- "creatinine": ["creatinine", "serum creatinine"],
100
- "platelets": ["platelets", "plts"],
101
- "hemoglobin": ["hemoglobin", "hgb"],
102
- "wbc": ["wbc", "white blood cell count"]
103
- }
104
-
105
- def normalize_test_name(name):
106
- name = name.lower().strip()
107
- for key, syns in synonyms.items():
108
- if name in syns:
109
- return key
110
- for key in synonyms.keys():
111
- if difflib.get_close_matches(name, synonyms[key], cutoff=0.7):
112
- return key
113
- return name
114
-
115
- def check_condition(user_value, expected):
116
- try:
117
- user_val = float(user_value)
118
- if expected.startswith("<="):
119
- return user_val <= float(expected[2:])
120
- elif expected.startswith(">="):
121
- return user_val >= float(expected[2:])
122
- elif expected.startswith("<"):
123
- return user_val < float(expected[1:])
124
- elif expected.startswith(">"):
125
- return user_val > float(expected[1:])
126
- else:
127
- return str(user_val) == expected
128
- except:
129
- return expected.lower() in user_value.lower() or user_value.lower() in expected.lower()
130
-
131
- def analyze_lab_results(lab_results_text, guidelines):
132
- lab_results_input = {}
133
- for line in lab_results_text.split('\n'):
134
- if ':' in line:
135
- key, value = line.split(':', 1)
136
- norm_key = normalize_test_name(key)
137
- lab_results_input[norm_key] = value.strip()
138
-
139
- matched_diseases = []
140
- for guideline in guidelines:
141
- disease_name = guideline.get('condition_name', 'Unknown')
142
- icd_code = guideline.get('icd_code', 'N/A')
143
- lab_findings = guideline.get('lab_findings', {})
144
-
145
- matches = []
146
- for lab_test, criteria in lab_findings.items():
147
- norm_test = normalize_test_name(lab_test)
148
- if norm_test in lab_results_input:
149
- user_value = lab_results_input[norm_test]
150
- expected = str(criteria.get('expected', '')).strip()
151
- meaning = criteria.get('meaning', '')
152
- if check_condition(user_value, expected):
153
- matches.append({
154
- 'test': lab_test,
155
- 'user_value': user_value,
156
- 'expected': expected,
157
- 'meaning': meaning
158
- })
159
-
160
- if matches:
161
- matched_diseases.append({
162
- 'disease_name': disease_name,
163
- 'icd_code': icd_code,
164
- 'lab_matches': matches,
165
- 'full_data': guideline
166
- })
167
-
168
- return matched_diseases
169
-
170
- # -------------------------------------------------------
171
- # ترکیب نتایج برای UI
172
- # -------------------------------------------------------
173
- def combined_analysis_for_ui(symptoms, lab_results_text):
174
- symptom_results = analyze_symptoms(symptoms, guidelines)
175
- lab_results = analyze_lab_results(lab_results_text, guidelines)
176
-
177
- if not symptom_results and not lab_results:
178
- return [], "❌ هیچ بیماری مرتبطی یافت نشد.", [], []
179
-
180
- symptom_table_data = []
181
- for r in symptom_results:
182
- symptom_table_data.append([r['disease_name'], r['icd_code'], f"{r['probability']}%", r['matched_symptoms']])
183
-
184
- lab_results_html = ""
185
- if lab_results:
186
- lab_results_html += "<h4>🧪 تحلیل بر اساس آزمایش‌ها:</h4>"
187
- for lab in lab_results:
188
- lab_results_html += f"<b>{lab['disease_name']}</b> (ICD: {lab['icd_code']})<br>"
189
- for match in lab['lab_matches']:
190
- lab_results_html += f" - <b>{match['test']}</b>: {match['user_value']} (انتظار: {match['expected']}) → {match['meaning']}<br>"
191
- lab_results_html += "<br>"
192
-
193
- return symptom_table_data, lab_results_html, symptom_results, lab_results
194
-
195
- # -------------------------------------------------------
196
- # نمایش جزئیات هنگام کلیک روی بیماری
197
- # -------------------------------------------------------
198
- def show_details(evt: gr.SelectData, symptom_results):
199
- if evt is None or evt.index is None:
200
- return "هیچ بیماری انتخاب نشده است."
201
-
202
- selected_row = evt.index[0] if isinstance(evt.index, (list, tuple)) else evt.index
203
- if selected_row < 0 or selected_row >= len(symptom_results):
204
- return "بیماری انتخاب شده معتبر نیست."
205
-
206
- disease = symptom_results[selected_row]["full_data"]
207
- html = f"<h4 style='color:#2E86C1;'>{disease.get('condition_name','Unknown')}</h4>"
208
-
209
- if disease.get('diagnosis_criteria'):
210
- html += "<b>معیارهای تشخیصی:</b><ul>"
211
- for item in disease['diagnosis_criteria']:
212
- html += f"<li>{item}</li>"
213
- html += "</ul>"
214
-
215
- if disease.get('alarm_features'):
216
- html += "<b>علائم هشدار:</b><ul>"
217
- for k, v in disease['alarm_features'].items():
218
- html += f"<li><b>{k}</b>: {v}</li>"
219
- html += "</ul>"
220
-
221
- if disease.get('first_line_treatment'):
222
- html += "<b>درمان خط اول:</b><ul>"
223
- for t in disease['first_line_treatment']:
224
- html += f"<li>{t}</li>"
225
- html += "</ul>"
226
-
227
- if disease.get('second_line_treatment'):
228
- html += "<b>درمان خط دوم:</b><ul>"
229
- for t in disease['second_line_treatment']:
230
- html += f"<li>{t}</li>"
231
- html += "</ul>"
232
-
233
- return html
234
-
235
- # -------------------------------------------------------
236
- # رابط Gradio
237
- # -------------------------------------------------------
238
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
239
- gr.Markdown("<h2 style='text-align:center;color:#2E86C1;'>💡 سیستم هوشمند تحلیل علائم و آزمایش‌ها</h2>")
240
-
241
- with gr.Row():
242
- symptoms_input = gr.Textbox(label="✅ علائم (با کاما جدا کنید)")
243
- lab_results_input = gr.Textbox(label="🧪 نتایج آزمایش (هر خط: نام: مقدار)")
244
-
245
- analyze_button = gr.Button("🔍 تحلیل کن")
246
-
247
- with gr.Row():
248
- with gr.Column(scale=2):
249
- symptom_table_output = gr.Dataframe(headers=["بیماری", "ICD", "احتمال", "علائم منطبق"], interactive=False)
250
- lab_results_output = gr.HTML()
251
-
252
- with gr.Column(scale=3):
253
- detailed_output = gr.HTML()
254
-
255
- symptom_results_state = gr.State()
256
- lab_results_state = gr.State()
257
-
258
- analyze_button.click(
259
- fn=combined_analysis_for_ui,
260
- inputs=[symptoms_input, lab_results_input],
261
- outputs=[symptom_table_output, lab_results_output, symptom_results_state, lab_results_state]
262
- )
263
-
264
- symptom_table_output.select(
265
- fn=show_details,
266
- inputs=[symptom_results_state],
267
- outputs=detailed_output
268
- )
269
-
270
- if __name__ == "__main__":
271
  demo.launch()
 
1
+ import gradio as gr
2
+ import os
3
+
4
+ # این کد اپلیکیشن را از Space خصوصی شما بارگذاری می‌کند
5
+ # مطمئن شوید که نام Space خصوصی را درست وارد کرده‌اید
6
+ # برای دسترسی به Space خصوصی، به یک توکن نیاز است که در گام بعدی تنظیم می‌کنیم
7
+ demo = gr.load(
8
+ "spaces/Feri007/GIapp-private",
9
+ hf_token=os.environ.get("HF_TOKEN")
10
+ )
11
+
12
+ # نیازی به تغییر این بخش نیست
13
+ if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  demo.launch()