Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -131,12 +131,16 @@ def json_to_markdown(data) -> str:
|
|
| 131 |
|
| 132 |
def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, output_folder="outputs"):
|
| 133 |
try:
|
|
|
|
|
|
|
| 134 |
if pdf_file is None:
|
| 135 |
-
|
|
|
|
| 136 |
|
| 137 |
hcc_code_str = str(hcc_code or "").strip()
|
| 138 |
if not hcc_code_str:
|
| 139 |
-
|
|
|
|
| 140 |
|
| 141 |
os.makedirs(output_folder, exist_ok=True)
|
| 142 |
pdf_path = pdf_file.name
|
|
@@ -144,15 +148,20 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
|
|
| 144 |
print(f"\n[PROCESSING] {patient_name}")
|
| 145 |
|
| 146 |
# Step 1: Get all possible HCC Diagnoses
|
|
|
|
| 147 |
diagnoses = HCCDiagnosisListEngine(hcc_code_str, model_version, csv_path).run()
|
|
|
|
|
|
|
| 148 |
if not diagnoses:
|
| 149 |
-
|
| 150 |
-
|
|
|
|
| 151 |
|
| 152 |
-
# Step 2: Check
|
|
|
|
| 153 |
all_checked_results = ChartDiagnosisChecker(pdf_path).run(diagnoses)
|
|
|
|
| 154 |
|
| 155 |
-
# --- First Checkpoint: Confirmed Diagnoses (explicit OR implicit = yes) ---
|
| 156 |
confirmed_diagnoses = [
|
| 157 |
d for d in all_checked_results
|
| 158 |
if d.get("answer_explicit", "").lower() == "yes"
|
|
@@ -160,7 +169,7 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
|
|
| 160 |
]
|
| 161 |
|
| 162 |
if not confirmed_diagnoses:
|
| 163 |
-
|
| 164 |
output_data = {
|
| 165 |
"patient_id": patient_name,
|
| 166 |
"hcc_code": hcc_code_str,
|
|
@@ -171,35 +180,38 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
|
|
| 171 |
with open(outpath, "w", encoding="utf-8") as f:
|
| 172 |
json.dump(output_data, f, indent=2, ensure_ascii=False)
|
| 173 |
print(f"[DONE] Saved basic chart check report to {outpath}")
|
| 174 |
-
|
|
|
|
| 175 |
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
# Step 3: Run TestFindingAgent
|
| 179 |
diagnoses_with_tests = TestFindingAgent(hcc_code=hcc_code_str, model_version=model_version).run(confirmed_diagnoses)
|
|
|
|
| 180 |
|
| 181 |
-
# Step 4:
|
|
|
|
| 182 |
diagnoses_with_status = ClinicalStatusAgent().run(diagnoses_with_tests)
|
|
|
|
| 183 |
|
| 184 |
-
# --- Second Checkpoint: Filter ACTIVE diagnoses ---
|
| 185 |
active_diagnoses = [d for d in diagnoses_with_status if d.get("clinical_status") == "ACTIVE"]
|
| 186 |
|
| 187 |
validated_meat_diagnoses = []
|
| 188 |
if active_diagnoses:
|
| 189 |
-
|
| 190 |
validated_meat_diagnoses = MEATValidatorAgent().run(active_diagnoses)
|
|
|
|
| 191 |
else:
|
| 192 |
-
|
| 193 |
|
| 194 |
-
# --- Third Checkpoint: Diagnoses passing MEAT ---
|
| 195 |
diagnoses_passed_meat = [d for d in validated_meat_diagnoses if any(d.get("meat", {}).values())]
|
| 196 |
|
| 197 |
comorbidity_results = []
|
| 198 |
if diagnoses_passed_meat:
|
| 199 |
-
|
| 200 |
comorbidity_results = ComorbidityCheckerAgent(pdf_path, hcc_code_str, model_version).run(diagnoses_passed_meat)
|
|
|
|
| 201 |
|
| 202 |
-
#
|
| 203 |
status_map = {d["diagnosis"]: d for d in diagnoses_with_status}
|
| 204 |
meat_map = {d["diagnosis"]: d for d in validated_meat_diagnoses}
|
| 205 |
comorbidity_map = {d["diagnosis"]: d for d in comorbidity_results}
|
|
@@ -217,31 +229,29 @@ def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, outpu
|
|
| 217 |
else:
|
| 218 |
final_analysis.append(entry)
|
| 219 |
|
| 220 |
-
# --- Final Filter: Keep only YES answers ---
|
| 221 |
filtered_final_analysis = [
|
| 222 |
e for e in final_analysis
|
| 223 |
if e.get("answer_explicit", "").lower() == "yes"
|
| 224 |
or e.get("answer_implicit", "").lower() == "yes"
|
| 225 |
]
|
| 226 |
|
| 227 |
-
# Save report
|
| 228 |
output_data = {
|
| 229 |
"patient_id": patient_name,
|
| 230 |
"hcc_code": hcc_code_str,
|
| 231 |
"model_version": model_version,
|
| 232 |
"final_analysis": filtered_final_analysis
|
| 233 |
}
|
| 234 |
-
# outpath = os.path.join(output_folder, f"{patient_name}.json")
|
| 235 |
-
# with open(outpath, "w", encoding="utf-8") as f:
|
| 236 |
-
# json.dump(output_data, f, indent=2, ensure_ascii=False)
|
| 237 |
-
# print(f"[DONE] Saved final report to {outpath}")
|
| 238 |
|
| 239 |
-
#
|
| 240 |
-
|
|
|
|
|
|
|
|
|
|
| 241 |
|
| 242 |
except Exception as e:
|
| 243 |
print(f"[ERROR] {e}")
|
| 244 |
-
|
|
|
|
| 245 |
|
| 246 |
|
| 247 |
|
|
|
|
| 131 |
|
| 132 |
def process_pipeline(pdf_file, hcc_code, model_version, csv_path=CSV_PATH, output_folder="outputs"):
|
| 133 |
try:
|
| 134 |
+
start = time.time()
|
| 135 |
+
|
| 136 |
if pdf_file is None:
|
| 137 |
+
yield "<div style='color:orange; font-weight:bold;'>⚠️ Please upload a patient chart PDF.</div>"
|
| 138 |
+
return
|
| 139 |
|
| 140 |
hcc_code_str = str(hcc_code or "").strip()
|
| 141 |
if not hcc_code_str:
|
| 142 |
+
yield "<div style='color:orange; font-weight:bold;'>⚠️ Please enter a valid HCC Code before running validation.</div>"
|
| 143 |
+
return
|
| 144 |
|
| 145 |
os.makedirs(output_folder, exist_ok=True)
|
| 146 |
pdf_path = pdf_file.name
|
|
|
|
| 148 |
print(f"\n[PROCESSING] {patient_name}")
|
| 149 |
|
| 150 |
# Step 1: Get all possible HCC Diagnoses
|
| 151 |
+
yield "🔍 Step 1: Extracting possible HCC Diagnoses..."
|
| 152 |
diagnoses = HCCDiagnosisListEngine(hcc_code_str, model_version, csv_path).run()
|
| 153 |
+
yield f"⏳ Elapsed: {time.time() - start:.1f} sec"
|
| 154 |
+
|
| 155 |
if not diagnoses:
|
| 156 |
+
msg = f"<b>❌ No diagnoses found for HCC {hcc_code_str}.</b>"
|
| 157 |
+
yield msg
|
| 158 |
+
return
|
| 159 |
|
| 160 |
+
# Step 2: Check patient chart
|
| 161 |
+
yield "📄 Step 2: Checking diagnoses in patient chart..."
|
| 162 |
all_checked_results = ChartDiagnosisChecker(pdf_path).run(diagnoses)
|
| 163 |
+
yield f"⏳ Elapsed: {time.time() - start:.1f} sec"
|
| 164 |
|
|
|
|
| 165 |
confirmed_diagnoses = [
|
| 166 |
d for d in all_checked_results
|
| 167 |
if d.get("answer_explicit", "").lower() == "yes"
|
|
|
|
| 169 |
]
|
| 170 |
|
| 171 |
if not confirmed_diagnoses:
|
| 172 |
+
msg = f"<b>❌ No confirmed diagnoses for HCC {hcc_code_str} in {patient_name}. Report saved.</b>"
|
| 173 |
output_data = {
|
| 174 |
"patient_id": patient_name,
|
| 175 |
"hcc_code": hcc_code_str,
|
|
|
|
| 180 |
with open(outpath, "w", encoding="utf-8") as f:
|
| 181 |
json.dump(output_data, f, indent=2, ensure_ascii=False)
|
| 182 |
print(f"[DONE] Saved basic chart check report to {outpath}")
|
| 183 |
+
yield msg
|
| 184 |
+
return
|
| 185 |
|
| 186 |
+
# Step 3: Tests
|
| 187 |
+
yield "🧪 Step 3: Finding relevant tests..."
|
|
|
|
| 188 |
diagnoses_with_tests = TestFindingAgent(hcc_code=hcc_code_str, model_version=model_version).run(confirmed_diagnoses)
|
| 189 |
+
yield f"⏳ Elapsed: {time.time() - start:.1f} sec"
|
| 190 |
|
| 191 |
+
# Step 4: Clinical Status
|
| 192 |
+
yield "⚕️ Step 4: Determining clinical status..."
|
| 193 |
diagnoses_with_status = ClinicalStatusAgent().run(diagnoses_with_tests)
|
| 194 |
+
yield f"⏳ Elapsed: {time.time() - start:.1f} sec"
|
| 195 |
|
|
|
|
| 196 |
active_diagnoses = [d for d in diagnoses_with_status if d.get("clinical_status") == "ACTIVE"]
|
| 197 |
|
| 198 |
validated_meat_diagnoses = []
|
| 199 |
if active_diagnoses:
|
| 200 |
+
yield "🍖 Step 5: Validating MEAT..."
|
| 201 |
validated_meat_diagnoses = MEATValidatorAgent().run(active_diagnoses)
|
| 202 |
+
yield f"⏳ Elapsed: {time.time() - start:.1f} sec"
|
| 203 |
else:
|
| 204 |
+
yield "ℹ️ No ACTIVE diagnoses found. Skipping MEAT/Comorbidity."
|
| 205 |
|
|
|
|
| 206 |
diagnoses_passed_meat = [d for d in validated_meat_diagnoses if any(d.get("meat", {}).values())]
|
| 207 |
|
| 208 |
comorbidity_results = []
|
| 209 |
if diagnoses_passed_meat:
|
| 210 |
+
yield "🤝 Step 6: Checking comorbidities..."
|
| 211 |
comorbidity_results = ComorbidityCheckerAgent(pdf_path, hcc_code_str, model_version).run(diagnoses_passed_meat)
|
| 212 |
+
yield f"⏳ Elapsed: {time.time() - start:.1f} sec"
|
| 213 |
|
| 214 |
+
# Merge results
|
| 215 |
status_map = {d["diagnosis"]: d for d in diagnoses_with_status}
|
| 216 |
meat_map = {d["diagnosis"]: d for d in validated_meat_diagnoses}
|
| 217 |
comorbidity_map = {d["diagnosis"]: d for d in comorbidity_results}
|
|
|
|
| 229 |
else:
|
| 230 |
final_analysis.append(entry)
|
| 231 |
|
|
|
|
| 232 |
filtered_final_analysis = [
|
| 233 |
e for e in final_analysis
|
| 234 |
if e.get("answer_explicit", "").lower() == "yes"
|
| 235 |
or e.get("answer_implicit", "").lower() == "yes"
|
| 236 |
]
|
| 237 |
|
|
|
|
| 238 |
output_data = {
|
| 239 |
"patient_id": patient_name,
|
| 240 |
"hcc_code": hcc_code_str,
|
| 241 |
"model_version": model_version,
|
| 242 |
"final_analysis": filtered_final_analysis
|
| 243 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
|
| 245 |
+
# Final Report
|
| 246 |
+
yield "✅ Step 7: Generating final report..."
|
| 247 |
+
elapsed = time.time() - start
|
| 248 |
+
final_report = json_to_markdown(output_data) + f"<br/><div style='color:green;'>✅ Completed in {elapsed:.1f} sec</div>"
|
| 249 |
+
yield final_report
|
| 250 |
|
| 251 |
except Exception as e:
|
| 252 |
print(f"[ERROR] {e}")
|
| 253 |
+
yield f"<div style='color:red; font-weight:bold;'>⚠️ Error: {e}</div>"
|
| 254 |
+
|
| 255 |
|
| 256 |
|
| 257 |
|