| import os |
| import google.generativeai as genai |
| from src.config import CLASSES, GEMINI_API_KEY as CONFIG_API_KEY |
| from src.prompts import build_radiology_prompt |
|
|
| |
| |
| api_key = CONFIG_API_KEY or os.environ.get("GEMINI_API_KEY") or os.environ.get("GOOGLE_API_KEY") |
| if api_key: |
| genai.configure(api_key=api_key) |
| print("Gemini API Client berhasil dikonfigurasi menggunakan API Key.") |
| else: |
| print("Warning: GEMINI_API_KEY tidak ditemukan di config.py maupun environment. Mengaktifkan sistem laporan lokal fallback.") |
|
|
| def generate_radiology_report(predicted_idx, confidence, modality="MRI"): |
| """ |
| Menghasilkan laporan radiologi detail. |
| Mencoba menggunakan API Gemini terlebih dahulu, dan menggunakan generator lokal jika API tidak tersedia. |
| """ |
| class_name = CLASSES[predicted_idx] |
| |
| |
| suspected_patterns = { |
| "Alzheimer": "Atrofi kortikal difus bilateral, pelebaran sulkus otak, dan pembesaran sistem ventrikel (ventrikulomegali) kompensatorik.", |
| "Intracranial_Hemorrhage": "Lesi hiperdens akut (fokus pendarahan aktif) intraaksial/ekstraaksial dengan potensi efek massa.", |
| "Normal": "Arsitektur parenkim otak normal, batas substansia alba-grisea tegas, sistem ventrikel dan sulkus kortikal dalam batas normal.", |
| "Stroke_Iskemik": "Area hipodensitas fokal (infark serebri) akut/subakut yang sesuai dengan vaskularisasi arteri serebri tertentu.", |
| "Tumor": "Massa soliter/multipel intraaksial dengan edema perifokal (vasogenik) luas serta pendesakan garis tengah (midline shift)." |
| } |
| |
| attention_regions = { |
| "Alzheimer": "Lobus Temporal Medial, terutama daerah Hipokampus bilateral.", |
| "Intracranial_Hemorrhage": "Parenkim serebral (lobus frontal/temporal) atau ruang subdural/epidural.", |
| "Normal": "Seluruh parenkim serebri dan serebelum secara simetris.", |
| "Stroke_Iskemik": "Korteks serebri atau ganglia basalis (terutama teritori Arteri Serebri Media/MCA).", |
| "Tumor": "Lobus frontal/parietal parenkim serebral, atau fosa posterior serebelum." |
| } |
|
|
| result_data = { |
| "predicted_class": class_name, |
| "confidence": f"{confidence:.2f}%", |
| "visual_summary": { |
| "modality": modality, |
| "suspected_pattern": suspected_patterns.get(class_name, "Pola visual atipikal."), |
| "attention_region": attention_regions.get(class_name, "Area kortikal serebri.") |
| } |
| } |
|
|
| |
| if api_key: |
| try: |
| prompt = build_radiology_prompt(result_data) |
| |
| model = genai.GenerativeModel("gemini-1.5-flash") |
| response = model.generate_content(prompt) |
| if response.text: |
| return response.text.strip() |
| except Exception as e: |
| print(f"Gagal memanggil Gemini API: {str(e)}. Menggunakan laporan medis lokal.") |
|
|
| |
| return get_local_fallback_report(class_name, confidence, modality, suspected_patterns[class_name], attention_regions[class_name]) |
|
|
| def get_local_fallback_report(class_name, confidence, modality, pattern, region): |
| """Menghasilkan teks laporan medis radiologi standar yang terstruktur""" |
| |
| indonesian_names = { |
| "Alzheimer": "Penyakit Alzheimer / Atrofi Serebral Kronis", |
| "Intracranial_Hemorrhage": "Pendarahan Intrakranial (Intracranial Hemorrhage)", |
| "Normal": "Kondisi Otak Normal (Normal Brain Scan)", |
| "Stroke_Iskemik": "Stroke Iskemik (Infark Serebri)", |
| "Tumor": "Neoplasma Otak / Tumor Serebral" |
| } |
| |
| display_name = indonesian_names.get(class_name, class_name) |
| |
| report = f"""LAPORAN RADIOLOGI EVALUASI SCAN OTAK |
| Modalitas Pemeriksaan : {modality}-Scan Kepala (Brain Imaging) |
| Identitas Temuan : Deteksi Otomatis Sistem AI Terintegrasi |
| Status AI : Analisis Selesai (Confidence Level: {confidence:.2f}%) |
| Dugaan Klinis Utama : {display_name} |
| |
| 1. RINGKASAN TEMUAN (FINDINGS SUMMARY): |
| Pemeriksaan penunjang citra {modality} kepala menunjukkan adanya indikasi kelainan terfokus. Peta visual atensi AI (XAI) mendeteksi fokus anomali pada: {region}. |
| Pola visual yang dominan diidentifikasi sebagai: '{pattern}'. |
| |
| 2. ANALISIS KLINIS (CLINICAL ANALYSIS):""" |
|
|
| if class_name == "Alzheimer": |
| report += """ |
| * Tampak adanya reduksi volume parenkim otak global yang signifikan (Atrofi Serebral). |
| * Sulkus kortikal serebri melebar disertai pendalaman girus serebri secara difus, menonjol di lobus temporal dan parietal. |
| * Sistem ventrikel lateral kiri dan kanan melebar simetris, konsisten dengan hydrocephalus ex-vacuo sekunder akibat hilangnya jaringan otak. |
| * Tidak ditemukan tanda-tanda pendarahan akut maupun space-occupying lesion (massa tumor).""" |
| |
| elif class_name == "Intracranial_Hemorrhage": |
| report += """ |
| * Tampak visualisasi area lesi densitas tinggi (hiperdens) homogen lokal pada jaringan parenkim otak. |
| * Lesi disertai visualisasi edema perifokal (ring-like edema) tipis di sekitarnya. |
| * Terdeteksi sedikit efek massa lokal berupa kompresi ringan pada sulkus serebri yang bersebelahan. |
| * Rekomendasi perhatian ketat terhadap potensi peningkatan tekanan intrakranial (TIK).""" |
| |
| elif class_name == "Normal": |
| report += """ |
| * Parenkim serebri dan serebelum menunjukkan intensitas dan struktur sinyal homogen normal. |
| * Batas substansia alba (white matter) dan grisea (grey matter) tegas dan simetris di kedua hemisfer serebri. |
| * Sistem ventrikel lateral, ventrikel III, dan IV berada dalam posisi sentral dengan ukuran dan konfigurasi normal. |
| * Tidak tampak area hipodensitas lokal (infark serebri), pendarahan intrakranial, maupun massa neoplasma yang dicurigai.""" |
| |
| elif class_name == "Stroke_Iskemik": |
| report += """ |
| * Terdeteksi area lesi fokal hipodensitas parenkim serebri yang menunjukkan batas kurang tegas di daerah korteks/subkorteks. |
| * Visualisasi lesi selaras dengan batas vaskularisasi suplai darah serebral, menandakan adanya hambatan perfusi arteri (iskemia akut/subakut). |
| * Ditemukan edema sitotoksik minimal di area terinfark tanpa pergeseran midline serebri yang signifikan.""" |
| |
| elif class_name == "Tumor": |
| report += """ |
| * Tampak massa lesi berbatas tegas dengan kontur ireguler yang menempati ruang serebral (space-occupying lesion). |
| * Lesi dikelilingi oleh area edema vasogenik luas yang menekan sulkus kortikal dan jaringan parenkim sekitarnya. |
| * Tampak kompresi parsial pada tanduk ventrikel lateral homolateral serta pergeseran minor garis tengah serebral (midline shift).""" |
|
|
| report += f""" |
| |
| 3. TINGKAT KEYAKINAN (CONFIDENCE LEVEL ANALYSIS): |
| * Model klasifikasi Vision Transformer (Marksnb/brain-hybrid-efficientnet-vit) mendeteksi tanda visual penyakit '{class_name}' dengan tingkat keyakinan {confidence:.2f}%. |
| * Keakuratan klasifikasi divalidasi oleh cross-attention map yang secara presisi mengunci koordinat lesi di {region}. |
| |
| 4. REKOMENDASI PEMERIKSAAN LANJUTAN (RECOMMENDATIONS):""" |
|
|
| if class_name == "Alzheimer": |
| report += """ |
| * Disarankan melakukan korelasi klinis melalui asesmen kognitif menyeluruh (MMSE, MoCA). |
| * Evaluasi lanjutan dengan MRI resolusi tinggi (3T) sekuens volumetri hipokampus untuk menilai tingkat atrofi secara kuantitatif.""" |
| elif class_name == "Intracranial_Hemorrhage": |
| report += """ |
| * Diperlukan tindakan darurat (cito) konsultasi dengan Dokter Spesialis Bedah Saraf. |
| * Direkomendasikan CT-Scan non-kontras evaluasi ulang berkala (serial scan) dalam 12-24 jam untuk memantau perkembangan volume pendarahan.""" |
| elif class_name == "Normal": |
| report += """ |
| * Tidak diperlukan evaluasi radiologi lanjutan segera jika tidak terdapat kecurigaan gejala klinis baru. |
| * Disarankan kontrol berkala sesuai dengan anjuran dokter pengirim.""" |
| elif class_name == "Stroke_Iskemik": |
| report += """ |
| * Disarankan melakukan CT-Angiografi (CTA) atau MR-Angiografi (MRA) segera untuk menilai patensi pembuluh darah serebral. |
| * Pemeriksaan MRI kepala sekuens DWI/ADC (Diffusion-Weighted Imaging) untuk konfirmasi area infark akut (ischemic penumbra).""" |
| elif class_name == "Tumor": |
| report += """ |
| * Segera konsultasikan ke Spesialis Bedah Saraf / Onkologi. |
| * Direkomendasikan pemeriksaan MRI kepala dengan kontras (gadolinium) sekuens multiplanar untuk detail morfologi neoplasma. |
| * Rencanakan biopsi histopatologi untuk penentuan stadium dan jenis sel tumor secara definitif.""" |
|
|
| report += "\n\n*Catatan: Laporan ini dihasilkan secara otomatis oleh sistem kecerdasan buatan (AI) sebagai opini sekunder radiologi. Hasil akhir harus selalu divalidasi dan ditandatangani oleh Dokter Spesialis Radiologi (Sp.Rad).*" |
| return report |
|
|