{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":99552,"databundleVersionId":13190393,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport shutil\nimport pandas as pd\n\n# Path to competition data\ndataset_path = \"/kaggle/input/rsna-intracranial-aneurysm-detection\"\n\n# Your chosen SeriesInstanceUID\nseries_uid = \"1.2.826.0.1.3680043.8.498.10023411164590664678534044036963716636\"\n\n# Copy series images\nseries_path = f\"{dataset_path}/series/{series_uid}\"\nif os.path.exists(series_path):\n    shutil.copytree(series_path, f\"/kaggle/working/{series_uid}_images\")\n\n# Copy segmentation if available\nseg_path = f\"{dataset_path}/segmentations/series/{series_uid}\"\nif os.path.exists(seg_path):\n    shutil.copytree(seg_path, f\"/kaggle/working/{series_uid}_segmentation\")\n\nprint(\"Patient data copied to working directory.\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:51:16.635757Z","iopub.execute_input":"2025-08-14T05:51:16.63611Z","iopub.status.idle":"2025-08-14T05:51:18.585035Z","shell.execute_reply.started":"2025-08-14T05:51:16.636085Z","shell.execute_reply":"2025-08-14T05:51:18.584098Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nimages_dir = f\"/kaggle/working/{series_uid}_images\"\nprint(\"Number of DICOM files:\", len(os.listdir(images_dir)))\nprint(\"First 5 files:\", os.listdir(images_dir)[:5])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:51:23.220665Z","iopub.execute_input":"2025-08-14T05:51:23.22158Z","iopub.status.idle":"2025-08-14T05:51:23.230255Z","shell.execute_reply.started":"2025-08-14T05:51:23.221546Z","shell.execute_reply":"2025-08-14T05:51:23.228768Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pydicom\n\n# Pick the first file\ndicom_path = os.path.join(images_dir, os.listdir(images_dir)[0])\ndcm = pydicom.dcmread(dicom_path)\n\n# Show metadata\nprint(dcm)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:51:27.406051Z","iopub.execute_input":"2025-08-14T05:51:27.406411Z","iopub.status.idle":"2025-08-14T05:51:27.419428Z","shell.execute_reply.started":"2025-08-14T05:51:27.406384Z","shell.execute_reply":"2025-08-14T05:51:27.418525Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport pydicom\nimport os\n\n# Kaggle will automatically have dataset mounted in /kaggle/input\nbase_path = \"/kaggle/input/rsna-intracranial-aneurysm-detection\"\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:51:47.957089Z","iopub.execute_input":"2025-08-14T05:51:47.957937Z","iopub.status.idle":"2025-08-14T05:51:47.963157Z","shell.execute_reply.started":"2025-08-14T05:51:47.957907Z","shell.execute_reply":"2025-08-14T05:51:47.961988Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.read_csv(f\"{base_path}/train.csv\")\ntrain_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:51:54.617303Z","iopub.execute_input":"2025-08-14T05:51:54.61761Z","iopub.status.idle":"2025-08-14T05:51:54.645765Z","shell.execute_reply.started":"2025-08-14T05:51:54.617586Z","shell.execute_reply":"2025-08-14T05:51:54.64484Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(train_df.shape)     # Rows, columns\nprint(train_df.info())    # Data types, null values\ntrain_df.describe()       # Numeric column summary\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:52:04.181654Z","iopub.execute_input":"2025-08-14T05:52:04.181994Z","iopub.status.idle":"2025-08-14T05:52:04.237375Z","shell.execute_reply.started":"2025-08-14T05:52:04.181972Z","shell.execute_reply":"2025-08-14T05:52:04.236539Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,4))\nsns.heatmap(train_df.isnull(), cbar=False)\nplt.title(\"Missing Values Overview\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:52:10.425267Z","iopub.execute_input":"2025-08-14T05:52:10.425652Z","iopub.status.idle":"2025-08-14T05:52:10.899953Z","shell.execute_reply.started":"2025-08-14T05:52:10.425625Z","shell.execute_reply":"2025-08-14T05:52:10.899016Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.countplot(data=train_df, x=\"Aneurysm Present\")\nplt.title(\"Aneurysm Presence Distribution\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:52:15.690506Z","iopub.execute_input":"2025-08-14T05:52:15.690884Z","iopub.status.idle":"2025-08-14T05:52:15.828033Z","shell.execute_reply.started":"2025-08-14T05:52:15.690858Z","shell.execute_reply":"2025-08-14T05:52:15.827161Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Convert PatientAge to numeric\ntrain_df[\"PatientAge\"] = pd.to_numeric(train_df[\"PatientAge\"], errors='coerce')\n\n# Age distribution\nplt.hist(train_df[\"PatientAge\"].dropna(), bins=20, color='skyblue', edgecolor='black')\nplt.title(\"Patient Age Distribution\")\nplt.xlabel(\"Age\")\nplt.ylabel(\"Count\")\nplt.show()\n\n# Sex distribution\nsns.countplot(data=train_df, x=\"PatientSex\")\nplt.title(\"Sex Distribution\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:52:31.389926Z","iopub.execute_input":"2025-08-14T05:52:31.390239Z","iopub.status.idle":"2025-08-14T05:52:31.728003Z","shell.execute_reply.started":"2025-08-14T05:52:31.390217Z","shell.execute_reply":"2025-08-14T05:52:31.726669Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"artery_cols = train_df.columns[4:-1]  # skip first 4 cols, last is target\n\nartery_sums = train_df[artery_cols].sum().sort_values(ascending=False)\nartery_sums.plot(kind='bar', figsize=(12,5))\nplt.title(\"Aneurysm Count by Artery\")\nplt.ylabel(\"Count\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:52:40.132118Z","iopub.execute_input":"2025-08-14T05:52:40.132482Z","iopub.status.idle":"2025-08-14T05:52:40.478914Z","shell.execute_reply.started":"2025-08-14T05:52:40.132455Z","shell.execute_reply":"2025-08-14T05:52:40.478116Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"numeric_df = train_df.select_dtypes(include=[np.number])\nplt.figure(figsize=(10,8))\nsns.heatmap(numeric_df.corr(), cmap=\"coolwarm\", annot=False)\nplt.title(\"Correlation Heatmap\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:52:47.14676Z","iopub.execute_input":"2025-08-14T05:52:47.147961Z","iopub.status.idle":"2025-08-14T05:52:47.619824Z","shell.execute_reply.started":"2025-08-14T05:52:47.147925Z","shell.execute_reply":"2025-08-14T05:52:47.618642Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pydicom\nimport matplotlib.pyplot as plt\n\nbase_path = \"/kaggle/input/rsna-intracranial-aneurysm-detection\"\n\n# Look inside the 'series' folder\nseries_root = os.path.join(base_path, \"series\")\nprint(os.listdir(series_root)[:5])  # See first few series IDs\n\n# Match only existing series from train.csv\navailable_series = set(os.listdir(series_root))\ntrain_df = train_df[train_df[\"SeriesInstanceUID\"].isin(available_series)]\n\n# Pick a sample series\nsample_series_id = train_df[\"SeriesInstanceUID\"].iloc[0]\nseries_path = os.path.join(series_root, sample_series_id)\n\n# Pick one DICOM file from that series\nsample_file = os.listdir(series_path)[0]\ndcm = pydicom.dcmread(os.path.join(series_path, sample_file))\n\n# Show image\nplt.imshow(dcm.pixel_array, cmap=plt.cm.gray)\nplt.title(f\"Sample Image from Series {sample_series_id}\")\nplt.axis(\"off\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:52:53.156787Z","iopub.execute_input":"2025-08-14T05:52:53.157211Z","iopub.status.idle":"2025-08-14T05:52:53.502539Z","shell.execute_reply.started":"2025-08-14T05:52:53.157185Z","shell.execute_reply":"2025-08-14T05:52:53.501505Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"available_series = set(os.listdir(series_root))\ntrain_df = train_df[train_df[\"SeriesInstanceUID\"].isin(available_series)]\nprint(f\"After filtering: {len(train_df)} rows\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:53:02.971568Z","iopub.execute_input":"2025-08-14T05:53:02.972747Z","iopub.status.idle":"2025-08-14T05:53:02.992094Z","shell.execute_reply.started":"2025-08-14T05:53:02.972693Z","shell.execute_reply":"2025-08-14T05:53:02.991009Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pos_ratio = train_df[\"Aneurysm Present\"].mean()\nprint(f\"Aneurysm Positive Ratio: {pos_ratio:.2%}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:53:18.336641Z","iopub.execute_input":"2025-08-14T05:53:18.337055Z","iopub.status.idle":"2025-08-14T05:53:18.343142Z","shell.execute_reply.started":"2025-08-14T05:53:18.337028Z","shell.execute_reply":"2025-08-14T05:53:18.342177Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# Ensure PatientAge is numeric\ntrain_df['PatientAge'] = pd.to_numeric(train_df['PatientAge'], errors='coerce')\n\n# 1️⃣ Modality Distribution\nplt.figure(figsize=(6,4))\nsns.countplot(data=train_df, x='Modality', order=train_df['Modality'].value_counts().index, palette='viridis')\nplt.title(\"Distribution of Scan Modalities\")\nplt.ylabel(\"Number of Scans\")\nplt.xlabel(\"Modality\")\nplt.xticks(rotation=30)\nplt.show()\n\n# 2️⃣ Aneurysm Prevalence by Modality\nplt.figure(figsize=(6,4))\nsns.barplot(\n    x='Modality',\n    y='Aneurysm Present',\n    data=train_df,\n    order=train_df['Modality'].value_counts().index,\n    palette='coolwarm'\n)\nplt.title(\"Aneurysm Prevalence by Modality\")\nplt.ylabel(\"Proportion with Aneurysm\")\nplt.xlabel(\"Modality\")\nplt.xticks(rotation=30)\nplt.show()\n\n# 3️⃣ Age Distribution per Modality\nplt.figure(figsize=(6,4))\nsns.boxplot(\n    x='Modality',\n    y='PatientAge',\n    data=train_df,\n    order=train_df['Modality'].value_counts().index,\n    palette='Set2'\n)\nplt.title(\"Age Distribution per Modality\")\nplt.xlabel(\"Modality\")\nplt.ylabel(\"Patient Age\")\nplt.xticks(rotation=30)\nplt.show()\n\n# 4️⃣ Crosstab: Modality vs Aneurysm Count\nmodality_crosstab = pd.crosstab(train_df['Modality'], train_df['Aneurysm Present'])\nmodality_crosstab['Positive_Ratio'] = modality_crosstab[1] / modality_crosstab.sum(axis=1)\nprint(\"\\nModality vs Aneurysm Counts & Positive Ratio:\")\nprint(modality_crosstab.sort_values(by='Positive_Ratio', ascending=False))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:53:27.632163Z","iopub.execute_input":"2025-08-14T05:53:27.632521Z","iopub.status.idle":"2025-08-14T05:53:28.265775Z","shell.execute_reply.started":"2025-08-14T05:53:27.632495Z","shell.execute_reply":"2025-08-14T05:53:28.264772Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport pydicom\nfrom ipywidgets import interact, IntSlider\nimport ast\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:53:39.127481Z","iopub.execute_input":"2025-08-14T05:53:39.128198Z","iopub.status.idle":"2025-08-14T05:53:39.133421Z","shell.execute_reply.started":"2025-08-14T05:53:39.128169Z","shell.execute_reply":"2025-08-14T05:53:39.132158Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"BASE_PATH = '/kaggle/input/rsna-intracranial-aneurysm-detection/'\nTRAIN_CSV_PATH = os.path.join(BASE_PATH, 'train.csv')\nLOCALIZERS_PATH = os.path.join(BASE_PATH, 'train_localizers.csv')\nSERIES_DIR = os.path.join(BASE_PATH, 'series')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:46:52.233629Z","iopub.execute_input":"2025-08-14T05:46:52.234041Z","iopub.status.idle":"2025-08-14T05:46:52.239962Z","shell.execute_reply.started":"2025-08-14T05:46:52.234011Z","shell.execute_reply":"2025-08-14T05:46:52.239056Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load CSVs\ntrain_df = pd.read_csv(TRAIN_CSV_PATH)\nlocalizers_df = pd.read_csv(LOCALIZERS_PATH)\n\n# Filter only CTA scans\ntrain_df = train_df[train_df['Modality'] == 'CTA'].copy()\nprint(f\"Filtered to {len(train_df)} CTA scans\")\ntrain_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:47:08.446902Z","iopub.execute_input":"2025-08-14T05:47:08.447359Z","iopub.status.idle":"2025-08-14T05:47:08.546244Z","shell.execute_reply.started":"2025-08-14T05:47:08.447327Z","shell.execute_reply":"2025-08-14T05:47:08.545201Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label_columns = train_df.columns[5:]\ntrain_df['aneurysm_present'] = train_df[label_columns].sum(axis=1) > 0\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:48:12.57646Z","iopub.execute_input":"2025-08-14T05:48:12.577245Z","iopub.status.idle":"2025-08-14T05:48:12.590622Z","shell.execute_reply.started":"2025-08-14T05:48:12.577215Z","shell.execute_reply":"2025-08-14T05:48:12.589394Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(6, 4))\nsns.countplot(x='aneurysm_present', data=train_df)\nplt.title('Aneurysm Presence (CTA only)')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:48:25.442655Z","iopub.execute_input":"2025-08-14T05:48:25.443095Z","iopub.status.idle":"2025-08-14T05:48:25.708294Z","shell.execute_reply.started":"2025-08-14T05:48:25.443066Z","shell.execute_reply":"2025-08-14T05:48:25.707207Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, axes = plt.subplots(1, 2, figsize=(14, 6))\n\nsns.histplot(data=train_df, x='PatientAge', hue='aneurysm_present',\n             kde=True, ax=axes[0], palette='viridis')\naxes[0].set_title('Age Distribution (CTA)')\n\nsns.countplot(data=train_df, x='PatientSex', hue='aneurysm_present',\n              ax=axes[1], palette='magma')\naxes[1].set_title('Sex Distribution (CTA)')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:48:43.132033Z","iopub.execute_input":"2025-08-14T05:48:43.132393Z","iopub.status.idle":"2025-08-14T05:48:43.847991Z","shell.execute_reply.started":"2025-08-14T05:48:43.132371Z","shell.execute_reply":"2025-08-14T05:48:43.846846Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label_columns = train_df.columns[5:-1]\nlocation_counts = train_df[label_columns].sum().sort_values(ascending=False)\n\nplt.figure(figsize=(8, 6))\nsns.barplot(x=location_counts.values, y=location_counts.index, palette='crest')\nplt.title('Aneurysm Frequency by Location (CTA)')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:49:10.07621Z","iopub.execute_input":"2025-08-14T05:49:10.07652Z","iopub.status.idle":"2025-08-14T05:49:10.352291Z","shell.execute_reply.started":"2025-08-14T05:49:10.076496Z","shell.execute_reply":"2025-08-14T05:49:10.351207Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def explore_3d_scan(series_uid):\n    series_path = os.path.join(SERIES_DIR, series_uid)\n    dicom_files = [pydicom.dcmread(os.path.join(series_path, f)) for f in os.listdir(series_path)]\n    dicom_files.sort(key=lambda x: float(x.ImagePositionPatient[2]), reverse=True)\n\n    def show_slice(slice_index):\n        plt.imshow(dicom_files[slice_index].pixel_array, cmap=plt.cm.bone)\n        plt.title(f\"Slice {slice_index} - {series_uid}\")\n        plt.axis('off')\n        plt.show()\n\n    interact(show_slice, slice_index=IntSlider(min=0, max=len(dicom_files)-1, step=1, value=len(dicom_files)//2))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:49:31.307214Z","iopub.execute_input":"2025-08-14T05:49:31.307525Z","iopub.status.idle":"2025-08-14T05:49:31.315015Z","shell.execute_reply.started":"2025-08-14T05:49:31.307502Z","shell.execute_reply":"2025-08-14T05:49:31.313633Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cta_uid = \"1.2.826.0.1.3680043.8.498.10030095840917973694487307992374923817\"\nexplore_3d_scan(cta_uid)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:49:52.000172Z","iopub.execute_input":"2025-08-14T05:49:52.000543Z","iopub.status.idle":"2025-08-14T05:49:56.900133Z","shell.execute_reply.started":"2025-08-14T05:49:52.000513Z","shell.execute_reply":"2025-08-14T05:49:56.899263Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def visualize_aneurysm_on_slice(series_uid, sop_uid, coords_str):\n    series_path = os.path.join(SERIES_DIR, series_uid)\n\n    target_slice_path = \"\"\n    for fname in os.listdir(series_path):\n        dcm_path = os.path.join(series_path, fname)\n        with pydicom.dcmread(dcm_path, stop_before_pixels=True) as dcm:\n            if dcm.SOPInstanceUID == sop_uid:\n                target_slice_path = dcm_path\n                break\n    \n    if not target_slice_path:\n        print(\"SOPInstanceUID not found.\")\n        return\n\n    target_slice = pydicom.dcmread(target_slice_path)\n    coords = ast.literal_eval(coords_str)\n\n    fig, axes = plt.subplots(1, 2, figsize=(12, 6))\n    axes[0].imshow(target_slice.pixel_array, cmap=plt.cm.bone)\n    axes[0].set_title(\"Original Slice\")\n    axes[0].axis('off')\n\n    axes[1].imshow(target_slice.pixel_array, cmap=plt.cm.bone)\n    axes[1].scatter([coords['x']], [coords['y']], c='red', s=400, marker='+')\n    axes[1].set_title(\"Aneurysm Marked\")\n    axes[1].axis('off')\n\n    plt.show()\n\n# Try marking aneurysm for your scan\ncta_localizer = localizers_df[localizers_df['SeriesInstanceUID'] == cta_uid]\nif not cta_localizer.empty:\n    first_row = cta_localizer.iloc[0]\n    visualize_aneurysm_on_slice(first_row['SeriesInstanceUID'],\n                                first_row['SOPInstanceUID'],\n                                first_row['coordinates'])\nelse:\n    print(\"No aneurysm coordinates found for this scan.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-14T05:50:19.023559Z","iopub.execute_input":"2025-08-14T05:50:19.023956Z","iopub.status.idle":"2025-08-14T05:50:19.570666Z","shell.execute_reply.started":"2025-08-14T05:50:19.02393Z","shell.execute_reply":"2025-08-14T05:50:19.56947Z"}},"outputs":[],"execution_count":null}]}