sujataprakashdatycs commited on
Commit
8f07844
Β·
verified Β·
1 Parent(s): cd663d5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +354 -18
app.py CHANGED
@@ -123,7 +123,8 @@ def json_to_markdown(data) -> str:
123
 
124
 
125
  # ---------- Processing Pipeline with Gradio Progress ----------
126
- def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, output_folder="outputs", progress=gr.Progress()):
 
127
  try:
128
  start = time.time()
129
  step = 0
@@ -138,7 +139,7 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
138
  else: color = "#e5e7eb"
139
  bar_html += f'<div style="flex-grow: 1; background-color: {color}; border-radius: 3px;"></div>'
140
  bar_html += '</div>'
141
- return f"{msg}{bar_html}<small>⏳ Elapsed: {elapsed:.1f} sec</small>"
142
 
143
  if pdf_file is None:
144
  yield log("⚠️ Please upload a patient chart PDF.", 0)
@@ -153,16 +154,15 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
153
  file_name = os.path.splitext(os.path.basename(pdf_path))[0]
154
  print(f"[PROCESSING] {file_name}")
155
 
156
- # --- MODIFICATION: Extract and show demographics first ---
157
  # Step 1: Extract Demographics
158
  step += 1
159
- progress((step, total_steps), desc="Extracting demographics")
160
- yield log(f"🧍 Step {step}/{total_steps}: Extracting patient demographics...", step)
 
161
  demographics_engine = PatientInfoExtractionEngine(pdf_path)
162
  demographics_info = demographics_engine.run()
163
  print(f"[DEMOGRAPHICS] Extracted: {demographics_info}")
164
 
165
- # Create and yield the initial report with only demographics
166
  initial_report_data = {
167
  "file_name": file_name,
168
  "hcc_code": hcc_code_str,
@@ -172,14 +172,10 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
172
  }
173
  demographics_md = json_to_markdown(initial_report_data)
174
  yield demographics_md
175
- time.sleep(1) # Pause for a moment to show the demographics
176
- # --- END OF MODIFICATION ---
177
-
178
- # Subsequent steps will append progress below the initial demographic display
179
-
180
  # Step 2: Diagnoses
181
  step += 1
182
- progress((step, total_steps), desc="Extracting diagnoses")
183
  yield demographics_md + log(f"πŸ” Step {step}/{total_steps}: Extracting possible HCC Diagnoses...", step)
184
  diagnoses = HCCDiagnosisListEngine(hcc_code_str, model_version, csv_path).run()
185
  if not diagnoses:
@@ -188,7 +184,6 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
188
 
189
  # Step 3: Chart checking
190
  step += 1
191
- progress((step, total_steps), desc="Checking chart")
192
  yield demographics_md + log(f"πŸ“„ Step {step}/{total_steps}: Checking diagnoses in patient chart...", step)
193
  all_checked_results = ChartDiagnosisChecker(pdf_path).run(diagnoses)
194
  confirmed_diagnoses = [d for d in all_checked_results if d.get("answer_explicit", "").lower() == "yes" or d.get("answer_implicit", "").lower() == "yes"]
@@ -198,20 +193,17 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
198
 
199
  # Step 4: Tests
200
  step += 1
201
- progress((step, total_steps), desc="Finding tests")
202
  yield demographics_md + log(f"πŸ§ͺ Step {step}/{total_steps}: Finding relevant tests...", step)
203
  diagnoses_with_tests = TestFindingAgent(hcc_code=hcc_code_str, model_version=model_version).run(confirmed_diagnoses)
204
 
205
  # Step 5: Clinical Status
206
  step += 1
207
- progress((step, total_steps), desc="Determining clinical status")
208
  yield demographics_md + log(f"βš•οΈ Step {step}/{total_steps}: Determining clinical status...", step)
209
  diagnoses_with_status = ClinicalStatusAgent().run(diagnoses_with_tests)
210
  active_diagnoses = [d for d in diagnoses_with_status if d.get("clinical_status") == "ACTIVE"]
211
 
212
  # Step 6: MEAT
213
  step += 1
214
- progress((step, total_steps), desc="Validating MEAT")
215
  if active_diagnoses:
216
  yield demographics_md + log(f"πŸ– Step {step}/{total_steps}: Validating MEAT...", step)
217
  validated_meat_diagnoses = MEATValidatorAgent().run(active_diagnoses)
@@ -221,7 +213,6 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
221
 
222
  # Step 7: Comorbidities
223
  step += 1
224
- progress((step, total_steps), desc="Checking comorbidities")
225
  diagnoses_passed_meat = [d for d in validated_meat_diagnoses if any(d.get("meat", {}).values())]
226
  if diagnoses_passed_meat:
227
  yield demographics_md + log(f"🀝 Step {step}/{total_steps}: Checking comorbidities...", step)
@@ -231,7 +222,6 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
231
 
232
  # Step 8: Final Report
233
  step += 1
234
- progress((step, total_steps), desc="Generating report")
235
  yield demographics_md + log(f"βœ… Step {step}/{total_steps}: Generating final report...", step)
236
 
237
  # Merge results for final output
@@ -364,6 +354,352 @@ if __name__ == "__main__":
364
  # SAMPLE_PDF = "sample_patient_chart.pdf" # Place a sample PDF in the same folder
365
 
366
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  # # ---------- JSON to Markdown ----------
368
  # def json_to_markdown(data) -> str:
369
  # try:
 
123
 
124
 
125
  # ---------- Processing Pipeline with Gradio Progress ----------
126
+ # --- MODIFICATION: Removed the `progress=gr.Progress()` argument ---
127
+ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, output_folder="outputs"):
128
  try:
129
  start = time.time()
130
  step = 0
 
139
  else: color = "#e5e7eb"
140
  bar_html += f'<div style="flex-grow: 1; background-color: {color}; border-radius: 3px;"></div>'
141
  bar_html += '</div>'
142
+ return f"<div style='padding-top:10px;'>{msg}{bar_html}<small>⏳ Elapsed: {elapsed:.1f} sec</small></div>"
143
 
144
  if pdf_file is None:
145
  yield log("⚠️ Please upload a patient chart PDF.", 0)
 
154
  file_name = os.path.splitext(os.path.basename(pdf_path))[0]
155
  print(f"[PROCESSING] {file_name}")
156
 
 
157
  # Step 1: Extract Demographics
158
  step += 1
159
+ # --- MODIFICATION: Removed progress() call ---
160
+ initial_progress_msg = log(f"🧍 Step {step}/{total_steps}: Extracting patient demographics...", step)
161
+ yield initial_progress_msg # Show initial message before demographics appear
162
  demographics_engine = PatientInfoExtractionEngine(pdf_path)
163
  demographics_info = demographics_engine.run()
164
  print(f"[DEMOGRAPHICS] Extracted: {demographics_info}")
165
 
 
166
  initial_report_data = {
167
  "file_name": file_name,
168
  "hcc_code": hcc_code_str,
 
172
  }
173
  demographics_md = json_to_markdown(initial_report_data)
174
  yield demographics_md
175
+ time.sleep(0.5)
176
+
 
 
 
177
  # Step 2: Diagnoses
178
  step += 1
 
179
  yield demographics_md + log(f"πŸ” Step {step}/{total_steps}: Extracting possible HCC Diagnoses...", step)
180
  diagnoses = HCCDiagnosisListEngine(hcc_code_str, model_version, csv_path).run()
181
  if not diagnoses:
 
184
 
185
  # Step 3: Chart checking
186
  step += 1
 
187
  yield demographics_md + log(f"πŸ“„ Step {step}/{total_steps}: Checking diagnoses in patient chart...", step)
188
  all_checked_results = ChartDiagnosisChecker(pdf_path).run(diagnoses)
189
  confirmed_diagnoses = [d for d in all_checked_results if d.get("answer_explicit", "").lower() == "yes" or d.get("answer_implicit", "").lower() == "yes"]
 
193
 
194
  # Step 4: Tests
195
  step += 1
 
196
  yield demographics_md + log(f"πŸ§ͺ Step {step}/{total_steps}: Finding relevant tests...", step)
197
  diagnoses_with_tests = TestFindingAgent(hcc_code=hcc_code_str, model_version=model_version).run(confirmed_diagnoses)
198
 
199
  # Step 5: Clinical Status
200
  step += 1
 
201
  yield demographics_md + log(f"βš•οΈ Step {step}/{total_steps}: Determining clinical status...", step)
202
  diagnoses_with_status = ClinicalStatusAgent().run(diagnoses_with_tests)
203
  active_diagnoses = [d for d in diagnoses_with_status if d.get("clinical_status") == "ACTIVE"]
204
 
205
  # Step 6: MEAT
206
  step += 1
 
207
  if active_diagnoses:
208
  yield demographics_md + log(f"πŸ– Step {step}/{total_steps}: Validating MEAT...", step)
209
  validated_meat_diagnoses = MEATValidatorAgent().run(active_diagnoses)
 
213
 
214
  # Step 7: Comorbidities
215
  step += 1
 
216
  diagnoses_passed_meat = [d for d in validated_meat_diagnoses if any(d.get("meat", {}).values())]
217
  if diagnoses_passed_meat:
218
  yield demographics_md + log(f"🀝 Step {step}/{total_steps}: Checking comorbidities...", step)
 
222
 
223
  # Step 8: Final Report
224
  step += 1
 
225
  yield demographics_md + log(f"βœ… Step {step}/{total_steps}: Generating final report...", step)
226
 
227
  # Merge results for final output
 
354
  # SAMPLE_PDF = "sample_patient_chart.pdf" # Place a sample PDF in the same folder
355
 
356
 
357
+ # # ---------- JSON to Markdown ----------
358
+ # def json_to_markdown(data) -> str:
359
+ # try:
360
+ # if isinstance(data, dict):
361
+ # file_name = data.get("file_name", "Unknown Patient")
362
+ # hcc_code = data.get("hcc_code", "N/A")
363
+ # model_version = data.get("model_version", "N/A")
364
+ # analyses = data.get("final_analysis", [])
365
+
366
+ # # Demographics
367
+ # patient_name = data.get("patient_name", "")
368
+ # dob = data.get("dob", "")
369
+ # age = data.get("age", "")
370
+ # gender = data.get("gender", "")
371
+ # address = data.get("address", "")
372
+ # phone = data.get("phone", "")
373
+ # patient_identifier = data.get("patient_identifier", "")
374
+ # else:
375
+ # return "<div style='color:red; font-weight:bold;'>⚠️ Invalid data format for report.</div>"
376
+
377
+ # md = f"""
378
+ # <div style="border:2px solid #4CAF50; padding:15px; border-radius:10px; background:#f9fdf9;">
379
+ # <h2 style="color:#2e7d32;">πŸ“‹ HCC Chart Validation Report </h2>
380
+ # <p><b>🧾 File Name:</b> {file_name}</p>
381
+ # <p><b>🏷️ HCC Code:</b> {hcc_code}</p>
382
+ # <p><b>βš™οΈ Model Version:</b> {model_version}</p>
383
+ # """
384
+
385
+ # # Add demographics
386
+ # if any([patient_name, dob, age, gender, address, phone, patient_identifier]):
387
+ # md += "<hr style='border:0;border-top:1px solid #c8e6c9;margin:10px 0;'/>"
388
+ # md += "<h3 style='color:#1b5e20;'>πŸ‘€ Patient Demographics</h3>"
389
+ # if patient_name: md += f"<p><b>Name:</b> {patient_name}</p>"
390
+ # if patient_identifier: md += f"<p><b>Patient Identifier:</b> {patient_identifier}</p>"
391
+ # if dob: md += f"<p><b>Date of Birth:</b> {dob}</p>"
392
+ # if age: md += f"<p><b>Age:</b> {age}</p>"
393
+ # if gender: md += f"<p><b>Gender:</b> {gender}</p>"
394
+ # if address: md += f"<p><b>Address:</b> {address}</p>"
395
+ # if phone: md += f"<p><b>Phone:</b> {phone}</p>"
396
+
397
+ # md += "</div><br/>"
398
+
399
+ # # Render analyses if they exist
400
+ # if analyses:
401
+ # for idx, diag in enumerate(analyses, 1):
402
+ # md += f"""
403
+ # <div style="border:1px solid #ccc; padding:12px; border-radius:8px; margin-bottom:12px;">
404
+ # <h3 style="color:#1565c0;">{idx}. {diag.get("diagnosis", "Unknown Diagnosis")}</h3>
405
+ # <p><b>ICD-10:</b> {diag.get("icd10", "N/A")}</p>
406
+ # <p><b>Reference:</b> <a href="{diag.get("reference","")}" target="_blank">{diag.get("reference","")}</a></p>
407
+ # """
408
+ # explicit_ans = diag.get("answer_explicit", "N/A")
409
+ # explicit_rat = diag.get("rationale_explicit", "")
410
+ # implicit_ans = diag.get("answer_implicit", "N/A")
411
+ # implicit_rat = diag.get("rationale_implicit", "")
412
+
413
+ # if explicit_ans.lower() == "yes":
414
+ # md += f"<p><b>Explicit:</b> {explicit_ans} β€” {explicit_rat}</p>"
415
+ # else:
416
+ # md += f"<p><b>Implicit:</b> {implicit_ans} β€” {implicit_rat}</p>"
417
+
418
+ # md += f"""
419
+ # <p><b>Clinical Status:</b> {diag.get("clinical_status","N/A")}</p>
420
+ # <p><b>Status Rationale:</b> {diag.get("status_rationale","")}</p>
421
+ # """
422
+ # if "tests" in diag:
423
+ # md += "<details><summary><b>πŸ§ͺ Tests & Procedures</b></summary><ul>"
424
+ # tests = diag["tests"]
425
+ # if "vitals" in tests:
426
+ # md += "<li><b>Vitals:</b><ul>"
427
+ # for k, v in tests["vitals"].items(): md += f"<li>{k}: {v}</li>"
428
+ # md += "</ul></li>"
429
+ # if "procedures" in tests:
430
+ # md += "<li><b>Procedures:</b><ul>"
431
+ # for k, v in tests["procedures"].items(): md += f"<li>{k}: {v}</li>"
432
+ # md += "</ul></li>"
433
+ # if "lab_test" in tests:
434
+ # md += "<li><b>Lab Tests:</b><ul>"
435
+ # for k, v in tests["lab_test"].items(): md += f"<li>{k}: {v}</li>"
436
+ # md += "</ul></li>"
437
+ # md += "</ul></details>"
438
+
439
+ # if "meat" in diag:
440
+ # md += "<details><summary><b>πŸ– MEAT Validation</b></summary><ul>"
441
+ # for k, v in diag["meat"].items():
442
+ # emoji = "βœ…" if v else "❌"
443
+ # md += f"<li>{k.capitalize()}: {emoji}</li>"
444
+ # md += "</ul>"
445
+ # md += f"<p><b>MEAT Rationale:</b> {diag.get('meat_rationale','')}</p>"
446
+ # md += "</details>"
447
+
448
+ # if "comorbidities" in diag and diag["comorbidities"]:
449
+ # md += "<details><summary><b>🩺 Comorbidities</b></summary><ul>"
450
+ # for c in diag["comorbidities"]:
451
+ # emoji = "βœ…" if c.get("is_present") else "❌"
452
+ # md += f"<li>{emoji} <b>{c.get('condition')}</b><br/><i>{c.get('rationale')}</i></li>"
453
+ # md += "</ul></details>"
454
+
455
+ # md += "</div>"
456
+ # return md
457
+ # except Exception as e:
458
+ # return f"<div style='color:red; font-weight:bold;'>⚠️ Error rendering report: {e}</div>"
459
+
460
+
461
+ # # ---------- Processing Pipeline with Gradio Progress ----------
462
+ # def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, output_folder="outputs", progress=gr.Progress()):
463
+ # try:
464
+ # start = time.time()
465
+ # step = 0
466
+ # total_steps = 8 # Total number of steps in the pipeline
467
+
468
+ # def log(msg, current_step=0):
469
+ # elapsed = time.time() - start
470
+ # bar_html = '<div style="display: flex; width: 100%; gap: 2px; height: 12px; margin: 8px 0 5px 0;">'
471
+ # for i in range(1, total_steps + 1):
472
+ # if i < current_step: color = "#1e40af"
473
+ # elif i == current_step: color = "#3b82f6"
474
+ # else: color = "#e5e7eb"
475
+ # bar_html += f'<div style="flex-grow: 1; background-color: {color}; border-radius: 3px;"></div>'
476
+ # bar_html += '</div>'
477
+ # return f"{msg}{bar_html}<small>⏳ Elapsed: {elapsed:.1f} sec</small>"
478
+
479
+ # if pdf_file is None:
480
+ # yield log("⚠️ Please upload a patient chart PDF.", 0)
481
+ # return
482
+ # hcc_code_str = str(hcc_code or "").strip()
483
+ # if not hcc_code_str:
484
+ # yield log("⚠️ Please enter a valid HCC Code before running validation.", 0)
485
+ # return
486
+
487
+ # os.makedirs(output_folder, exist_ok=True)
488
+ # pdf_path = pdf_file.name
489
+ # file_name = os.path.splitext(os.path.basename(pdf_path))[0]
490
+ # print(f"[PROCESSING] {file_name}")
491
+
492
+ # # --- MODIFICATION: Extract and show demographics first ---
493
+ # # Step 1: Extract Demographics
494
+ # step += 1
495
+ # progress((step, total_steps), desc="Extracting demographics")
496
+ # yield log(f"🧍 Step {step}/{total_steps}: Extracting patient demographics...", step)
497
+ # demographics_engine = PatientInfoExtractionEngine(pdf_path)
498
+ # demographics_info = demographics_engine.run()
499
+ # print(f"[DEMOGRAPHICS] Extracted: {demographics_info}")
500
+
501
+ # # Create and yield the initial report with only demographics
502
+ # initial_report_data = {
503
+ # "file_name": file_name,
504
+ # "hcc_code": hcc_code_str,
505
+ # "model_version": model_version,
506
+ # "final_analysis": [],
507
+ # **demographics_info
508
+ # }
509
+ # demographics_md = json_to_markdown(initial_report_data)
510
+ # yield demographics_md
511
+ # time.sleep(1) # Pause for a moment to show the demographics
512
+ # # --- END OF MODIFICATION ---
513
+
514
+ # # Subsequent steps will append progress below the initial demographic display
515
+
516
+ # # Step 2: Diagnoses
517
+ # step += 1
518
+ # progress((step, total_steps), desc="Extracting diagnoses")
519
+ # yield demographics_md + log(f"πŸ” Step {step}/{total_steps}: Extracting possible HCC Diagnoses...", step)
520
+ # diagnoses = HCCDiagnosisListEngine(hcc_code_str, model_version, csv_path).run()
521
+ # if not diagnoses:
522
+ # yield demographics_md + log(f"❌ No diagnoses found for HCC {hcc_code_str}.", step)
523
+ # return
524
+
525
+ # # Step 3: Chart checking
526
+ # step += 1
527
+ # progress((step, total_steps), desc="Checking chart")
528
+ # yield demographics_md + log(f"πŸ“„ Step {step}/{total_steps}: Checking diagnoses in patient chart...", step)
529
+ # all_checked_results = ChartDiagnosisChecker(pdf_path).run(diagnoses)
530
+ # confirmed_diagnoses = [d for d in all_checked_results if d.get("answer_explicit", "").lower() == "yes" or d.get("answer_implicit", "").lower() == "yes"]
531
+ # if not confirmed_diagnoses:
532
+ # yield demographics_md + log(f"❌ No confirmed diagnoses for HCC {hcc_code_str} in {file_name}.", step)
533
+ # return
534
+
535
+ # # Step 4: Tests
536
+ # step += 1
537
+ # progress((step, total_steps), desc="Finding tests")
538
+ # yield demographics_md + log(f"πŸ§ͺ Step {step}/{total_steps}: Finding relevant tests...", step)
539
+ # diagnoses_with_tests = TestFindingAgent(hcc_code=hcc_code_str, model_version=model_version).run(confirmed_diagnoses)
540
+
541
+ # # Step 5: Clinical Status
542
+ # step += 1
543
+ # progress((step, total_steps), desc="Determining clinical status")
544
+ # yield demographics_md + log(f"βš•οΈ Step {step}/{total_steps}: Determining clinical status...", step)
545
+ # diagnoses_with_status = ClinicalStatusAgent().run(diagnoses_with_tests)
546
+ # active_diagnoses = [d for d in diagnoses_with_status if d.get("clinical_status") == "ACTIVE"]
547
+
548
+ # # Step 6: MEAT
549
+ # step += 1
550
+ # progress((step, total_steps), desc="Validating MEAT")
551
+ # if active_diagnoses:
552
+ # yield demographics_md + log(f"πŸ– Step {step}/{total_steps}: Validating MEAT...", step)
553
+ # validated_meat_diagnoses = MEATValidatorAgent().run(active_diagnoses)
554
+ # else:
555
+ # validated_meat_diagnoses = []
556
+ # yield demographics_md + log("ℹ️ No ACTIVE diagnoses found. Skipping MEAT/Comorbidity.", step)
557
+
558
+ # # Step 7: Comorbidities
559
+ # step += 1
560
+ # progress((step, total_steps), desc="Checking comorbidities")
561
+ # diagnoses_passed_meat = [d for d in validated_meat_diagnoses if any(d.get("meat", {}).values())]
562
+ # if diagnoses_passed_meat:
563
+ # yield demographics_md + log(f"🀝 Step {step}/{total_steps}: Checking comorbidities...", step)
564
+ # comorbidity_results = ComorbidityCheckerAgent(pdf_path, hcc_code_str, model_version).run(diagnoses_passed_meat)
565
+ # else:
566
+ # comorbidity_results = []
567
+
568
+ # # Step 8: Final Report
569
+ # step += 1
570
+ # progress((step, total_steps), desc="Generating report")
571
+ # yield demographics_md + log(f"βœ… Step {step}/{total_steps}: Generating final report...", step)
572
+
573
+ # # Merge results for final output
574
+ # status_map = {d["diagnosis"]: d for d in diagnoses_with_status}
575
+ # meat_map = {d["diagnosis"]: d for d in validated_meat_diagnoses}
576
+ # comorbidity_map = {d["diagnosis"]: d for d in comorbidity_results}
577
+ # final_analysis = []
578
+ # for entry in all_checked_results:
579
+ # diag_name = entry["diagnosis"]
580
+ # updated_entry = entry.copy()
581
+ # if diag_name in status_map: updated_entry.update(status_map[diag_name])
582
+ # if diag_name in meat_map: updated_entry.update(meat_map[diag_name])
583
+ # if diag_name in comorbidity_map: updated_entry.update(comorbidity_map[diag_name])
584
+ # final_analysis.append(updated_entry)
585
+
586
+ # filtered_final_analysis = [e for e in final_analysis if e.get("answer_explicit", "").lower() == "yes" or e.get("answer_implicit", "").lower() == "yes"]
587
+
588
+ # output_data = {
589
+ # "file_name": file_name,
590
+ # "hcc_code": hcc_code_str,
591
+ # "model_version": model_version,
592
+ # "final_analysis": filtered_final_analysis,
593
+ # **demographics_info
594
+ # }
595
+
596
+ # elapsed = time.time() - start
597
+ # yield json_to_markdown(output_data) + f"<br/><div style='color:green;'>βœ… Completed in {elapsed:.1f} sec</div>"
598
+
599
+ # except Exception as e:
600
+ # print(f"[ERROR] {e}")
601
+ # yield f"<div style='color:red; font-weight:bold;'>⚠️ Error: {e}</div>"
602
+
603
+
604
+ # # ---------- Gradio Theme and Helpers ----------
605
+ # simple_theme = gr.themes.Soft(
606
+ # primary_hue=gr.themes.colors.blue,
607
+ # secondary_hue=gr.themes.colors.slate,
608
+ # neutral_hue=gr.themes.colors.slate,
609
+ # ).set(
610
+ # button_primary_background_fill="#1e40af",
611
+ # button_primary_background_fill_hover="#1d4ed8",
612
+ # button_primary_text_color="white",
613
+ # background_fill_primary="white",
614
+ # background_fill_secondary="#f8fafc",
615
+ # )
616
+
617
+ # def load_sample_pdf():
618
+ # if not os.path.exists(SAMPLE_PDF):
619
+ # raise FileNotFoundError(f"Sample PDF not found at {SAMPLE_PDF}")
620
+ # class PDFWrapper:
621
+ # def __init__(self, path):
622
+ # self.name = path
623
+ # return PDFWrapper(SAMPLE_PDF)
624
+
625
+ # def pdf_to_iframe(file):
626
+ # if file is None: return "<p style='color:orange;'>No PDF uploaded.</p>"
627
+ # try:
628
+ # with open(file.name, "rb") as f: pdf_bytes = f.read()
629
+ # encoded = base64.b64encode(pdf_bytes).decode("utf-8")
630
+ # return f'<iframe src="data:application/pdf;base64,{encoded}" width="100%" height="600px" style="border:1px solid #ccc;"></iframe>'
631
+ # except Exception as e:
632
+ # return f"<p style='color:red;'>Failed to display PDF: {e}</p>"
633
+
634
+
635
+ # # ---------- Gradio UI ----------
636
+ # with gr.Blocks(theme=simple_theme, title=APP_TITLE) as interface:
637
+ # gr.HTML(f"""
638
+ # <h1 style='text-align:center;color:#1e40af;'> 🏩 {APP_TITLE}</h1>
639
+ # <p style='text-align:center;color:#64748b;'>
640
+ # Upload a chart, set HCC + model version, and validate MEAT criteria.
641
+ # </p>
642
+ # """)
643
+
644
+ # with gr.Row():
645
+ # pdf_upload = gr.File(label="Upload Patient Chart (PDF)", file_types=[".pdf"], scale=1)
646
+ # hcc_code = gr.Textbox(label="HCC Code (e.g., 12)", placeholder="Enter HCC code", scale=1)
647
+ # model_version = gr.Dropdown(choices=["V24", "V28"], label="Model Version", value="V24", scale=1)
648
+ # run_btn = gr.Button("πŸš€ Run Validation", variant="primary", scale=1)
649
+
650
+ # with gr.Row():
651
+ # with gr.Column(scale=2):
652
+ # pdf_preview = gr.HTML(label="πŸ“‘ PDF Preview", value="<p>Upload a PDF to preview</p>")
653
+ # with gr.Column(scale=2):
654
+ # output_md = gr.Markdown(
655
+ # label="Validation Report",
656
+ # value="<div style='border:2px solid #1e40af; border-radius:12px; padding:15px; background-color:#f0f9ff;'>πŸ“„ Upload a PDF and click <b>Run Validation</b> to start.</div>",
657
+ # )
658
+
659
+ # pdf_upload.change(fn=pdf_to_iframe, inputs=pdf_upload, outputs=pdf_preview)
660
+
661
+ # run_btn.click(
662
+ # fn=process_pipeline,
663
+ # inputs=[pdf_upload, hcc_code, model_version],
664
+ # outputs=[output_md],
665
+ # )
666
+
667
+ # gr.Examples(
668
+ # examples=[[SAMPLE_PDF]],
669
+ # inputs=[pdf_upload],
670
+ # outputs=[output_md],
671
+ # fn=lambda x: process_pipeline(load_sample_pdf(), hcc_code="12", model_version="V24"),
672
+ # cache_examples=False
673
+ # )
674
+
675
+
676
+ # if __name__ == "__main__":
677
+ # interface.queue().launch(
678
+ # server_name="0.0.0.0",
679
+ # server_port=int(os.environ.get("PORT", 7860))
680
+ # )
681
+
682
+
683
+ # import os
684
+ # import gradio as gr
685
+ # import json
686
+ # import time
687
+ # import base64
688
+ # from dotenv import load_dotenv
689
+ # from ClinicalStatusAgent import ClinicalStatusAgent
690
+ # from TestFindingAgent import TestFindingAgent
691
+ # from ComorbidityCheckerAgent import ComorbidityCheckerAgent
692
+ # from HCCDiagnosisListEngine import HCCDiagnosisListEngine
693
+ # from chartdiagnosischecker import ChartDiagnosisChecker
694
+ # from MeatValidatorAgent import MEATValidatorAgent
695
+ # from PatientInfoExtractionEngine import PatientInfoExtractionEngine
696
+
697
+ # load_dotenv()
698
+ # APP_TITLE = "Risk Adjustment (HCC Chart Validation)"
699
+ # CSV_PATH = "hcc_mapping.csv"
700
+ # SAMPLE_PDF = "sample_patient_chart.pdf" # Place a sample PDF in the same folder
701
+
702
+
703
  # # ---------- JSON to Markdown ----------
704
  # def json_to_markdown(data) -> str:
705
  # try: