{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n#    for filename in filenames:\n#       print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\nimport shutil\nfrom collections import defaultdict\nimport polars as pl\nimport pydicom\nimport kaggle_evaluation.rsna_inference_server\n\nD_COL = 'SeriesInstanceUID'\n\nLABEL_COLS = [\n    'Left Infraclinoid Internal Carotid Artery',\n    'Right Infraclinoid Internal Carotid Artery',\n    'Left Supraclinoid Internal Carotid Artery',\n    'Right Supraclinoid Internal Carotid Artery',\n    'Left Middle Cerebral Artery',\n    'Right Middle Cerebral Artery',\n    'Anterior Communicating Artery',\n    'Left Anterior Cerebral Artery',\n    'Right Anterior Cerebral Artery',\n    'Left Posterior Communicating Artery',\n    'Right Posterior Communicating Artery',\n    'Basilar Tip',\n    'Other Posterior Circulation',\n    'Aneurysm Present',\n]\n\n# All tags (other than PixelData and SeriesInstanceUID) that may be in a test set dcm file\nDICOM_TAG_ALLOWLIST = [\n    'BitsAllocated',\n    'BitsStored',\n    'Columns',\n    'FrameOfReferenceUID',\n    'HighBit',\n    'ImageOrientationPatient',\n    'ImagePositionPatient',\n    'InstanceNumber',\n    'Modality',\n    'PatientID',\n    'PhotometricInterpretation',\n    'PixelRepresentation',\n    'PixelSpacing',\n    'PlanarConfiguration',\n    'RescaleIntercept',\n    'RescaleSlope',\n    'RescaleType',\n    'Rows',\n    'SOPClassUID',\n    'SOPInstanceUID',\n    'SamplesPerPixel',\n    'SliceThickness',\n    'SpacingBetweenSlices',\n    'StudyInstanceUID',\n    'TransferSyntaxUID',\n]\n\n# Replace this function with your inference code.\n# You can return either a Pandas or Polars dataframe, though Polars is recommended.\n# Each prediction (except the very first) must be returned within 30 minutes of the series being provided.\ndef predict(series_path: str) -> pl.DataFrame | pd.DataFrame:\n    \"\"\"Make a prediction.\"\"\"\n    # --------- Replace this section with your own prediction code ---------\n    series_id = os.path.basename(series_path)\n    \n    all_filepaths = []\n    for root, _, files in os.walk(series_path):\n        for file in files:\n            if file.endswith('.dcm'):\n                all_filepaths.append(os.path.join(root, file))\n    all_filepaths.sort()\n    \n    # Collect tags from the dicoms\n    tags = defaultdict(list)\n    tags['SeriesInstanceUID'] = series_id\n    global dcms\n    for filepath in all_filepaths:\n        ds = pydicom.dcmread(filepath, force=True)\n        tags['filepath'].append(filepath)\n        for tag in DICOM_TAG_ALLOWLIST:\n            tags[tag].append(getattr(ds, tag, None))\n        # The image is in ds.PixelData\n\n    # ... do some machine learning magic ...\n    predictions = pl.DataFrame(\n        data=[[series_id] + [0.5] * len(LABEL_COLS)],\n        schema=[ID_COL, *LABEL_COLS],\n        orient='row',\n    )\n    # ----------------------------------------------------------------------\n\n    if isinstance(predictions, pl.DataFrame):\n        assert predictions.columns == [ID_COL, *LABEL_COLS]\n    elif isinstance(predictions, pd.DataFrame):\n        assert (predictions.columns == [ID_COL, *LABEL_COLS]).all()\n    else:\n        raise TypeError('The predict function must return a DataFrame')\n\n    # ----------------------------- IMPORTANT ------------------------------\n    # You MUST have the following code in your `predict` function\n    # to prevent \"out of disk space\" errors. This is a temporary workaround\n    # as we implement improvements to our evaluation system.\n    shutil.rmtree('/kaggle/shared', ignore_errors=True)\n    # ----------------------------------------------------------------------\n    \n    return predictions.drop(ID_COL)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-08-01T20:10:19.67883Z","iopub.execute_input":"2025-08-01T20:10:19.679144Z","iopub.status.idle":"2025-08-01T20:10:19.691471Z","shell.execute_reply.started":"2025-08-01T20:10:19.679114Z","shell.execute_reply":"2025-08-01T20:10:19.690342Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ID_COL = 'SeriesInstanceUID'\n\nLABEL_COLS = [\n    'Left Infraclinoid Internal Carotid Artery',\n    'Right Infraclinoid Internal Carotid Artery',\n    'Left Supraclinoid Internal Carotid Artery',\n    'Right Supraclinoid Internal Carotid Artery',\n    'Left Middle Cerebral Artery',\n    'Right Middle Cerebral Artery',\n    'Anterior Communicating Artery',\n    'Left Anterior Cerebral Artery',\n    'Right Anterior Cerebral Artery',\n    'Left Posterior Communicating Artery',\n    'Right Posterior Communicating Artery',\n    'Basilar Tip',\n    'Other Posterior Circulation',\n    'Aneurysm Present',\n]\n\n# All tags (other than PixelData and SeriesInstanceUID) that may be in a test set dcm file\nDICOM_TAG_ALLOWLIST = [\n    'BitsAllocated',\n    'BitsStored',\n    'Columns',\n    'FrameOfReferenceUID',\n    'HighBit',\n    'ImageOrientationPatient',\n    'ImagePositionPatient',\n    'InstanceNumber',\n    'Modality',\n    'PatientID',\n    'PhotometricInterpretation',\n    'PixelRepresentation',\n    'PixelSpacing',\n    'PlanarConfiguration',\n    'RescaleIntercept',\n    'RescaleSlope',\n    'RescaleType',\n    'Rows',\n    'SOPClassUID',\n    'SOPInstanceUID',\n    'SamplesPerPixel',\n    'SliceThickness',\n    'SpacingBetweenSlices',\n    'StudyInstanceUID',\n    'TransferSyntaxUID',\n]\n\n# Replace this function with your inference code.\n# You can return either a Pandas or Polars dataframe, though Polars is recommended.\n# Each prediction (except the very first) must be returned within 30 minutes of the series being provided.\ndef predict(series_path: str) -> pl.DataFrame | pd.DataFrame:\n    \"\"\"Make a prediction.\"\"\"\n    # --------- Replace this section with your own prediction code ---------\n    series_id = os.path.basename(series_path)\n    \n    all_filepaths = []\n    for root, _, files in os.walk(series_path):\n        for file in files:\n            if file.endswith('.dcm'):\n                all_filepaths.append(os.path.join(root, file))\n    all_filepaths.sort()\n    \n    # Collect tags from the dicoms\n    tags = defaultdict(list)\n    tags['SeriesInstanceUID'] = series_id\n    global dcms\n    for filepath in all_filepaths:\n        ds = pydicom.dcmread(filepath, force=True)\n        tags['filepath'].append(filepath)\n        for tag in DICOM_TAG_ALLOWLIST:\n            tags[tag].append(getattr(ds, tag, None))\n        # The image is in ds.PixelData\n\n    # ... do some machine learning magic ...\n    predictions = pl.DataFrame(\n        data=[[series_id] + [0.5] * len(LABEL_COLS)],\n        schema=[ID_COL, *LABEL_COLS],\n        orient='row',\n    )\n    # ----------------------------------------------------------------------\n\n    if isinstance(predictions, pl.DataFrame):\n        assert predictions.columns == [ID_COL, *LABEL_COLS]\n    elif isinstance(predictions, pd.DataFrame):\n        assert (predictions.columns == [ID_COL, *LABEL_COLS]).all()\n    else:\n        raise TypeError('The predict function must return a DataFrame')\n\n    # ----------------------------- IMPORTANT ------------------------------\n    # You MUST have the following code in your `predict` function\n    # to prevent \"out of disk space\" errors. This is a temporary workaround\n    # as we implement improvements to our evaluation system.\n    shutil.rmtree('/kaggle/shared', ignore_errors=True)\n    # ----------------------------------------------------------------------\n    \n    return predictions.drop(ID_COL)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-01T20:10:19.692586Z","iopub.execute_input":"2025-08-01T20:10:19.692935Z","iopub.status.idle":"2025-08-01T20:10:19.730861Z","shell.execute_reply.started":"2025-08-01T20:10:19.692904Z","shell.execute_reply":"2025-08-01T20:10:19.729767Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inference_server = kaggle_evaluation.rsna_inference_server.RSNAInferenceServer(predict)\n\nif os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n    inference_server.serve()\nelse:\n    inference_server.run_local_gateway()\n    display(pl.read_parquet('/kaggle/working/submission.parquet'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-01T20:10:19.731795Z","iopub.execute_input":"2025-08-01T20:10:19.732195Z","iopub.status.idle":"2025-08-01T20:10:25.582364Z","shell.execute_reply.started":"2025-08-01T20:10:19.732164Z","shell.execute_reply":"2025-08-01T20:10:25.581495Z"}},"outputs":[],"execution_count":null}]}