{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.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":71549,"databundleVersionId":8561470,"sourceType":"competition"}],"dockerImageVersionId":30715,"isInternetEnabled":false,"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\n# import numpy as np # linear algebra\n# import 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\n# import os\n# dataset = []\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         dataset.append(os.path.join(dirname, filename))\n# #         print(os.path.join(dirname, filename))\n# #     print(dirname)\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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-06-05T19:57:10.149639Z","iopub.execute_input":"2024-06-05T19:57:10.150066Z","iopub.status.idle":"2024-06-05T19:57:10.156589Z","shell.execute_reply.started":"2024-06-05T19:57:10.150032Z","shell.execute_reply":"2024-06-05T19:57:10.155229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import seaborn as sns\n\nimport matplotlib.pyplot as plt\nimport os\nimport time\nimport numpy as np\nimport glob\nimport json\nimport collections\nimport torch\nimport torch.nn as nn\n\nimport pydicom as dicom\nimport matplotlib.patches as patches\n\nfrom matplotlib import animation, rc\nimport pandas as pd\n\nimport pydicom as dicom # dicom\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:10.159039Z","iopub.execute_input":"2024-06-05T19:57:10.159537Z","iopub.status.idle":"2024-06-05T19:57:10.182091Z","shell.execute_reply.started":"2024-06-05T19:57:10.159498Z","shell.execute_reply":"2024-06-05T19:57:10.180751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# read data\npath = '../input/rsna-2024-lumbar-spine-degenerative-classification/'\n\ndf_train_main  = pd.read_csv(path + 'train.csv')\ndf_train_label = pd.read_csv(path + 'train_label_coordinates.csv')\ndf_train_desc  = pd.read_csv(path + 'train_series_descriptions.csv')\ndf_test_desc   = pd.read_csv(path + 'test_series_descriptions.csv')\ndf_sub         = pd.read_csv(path + 'sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:10.183667Z","iopub.execute_input":"2024-06-05T19:57:10.184030Z","iopub.status.idle":"2024-06-05T19:57:10.381574Z","shell.execute_reply.started":"2024-06-05T19:57:10.184001Z","shell.execute_reply":"2024-06-05T19:57:10.380209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_main.head(2)\n","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:10.384698Z","iopub.execute_input":"2024-06-05T19:57:10.385076Z","iopub.status.idle":"2024-06-05T19:57:10.425644Z","shell.execute_reply.started":"2024-06-05T19:57:10.385045Z","shell.execute_reply":"2024-06-05T19:57:10.424577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_desc.head(1)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:10.426999Z","iopub.execute_input":"2024-06-05T19:57:10.427352Z","iopub.status.idle":"2024-06-05T19:57:10.439473Z","shell.execute_reply.started":"2024-06-05T19:57:10.427323Z","shell.execute_reply":"2024-06-05T19:57:10.438266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for f in ['instance_number','condition','level']:\n    print(df_train_label[f].value_counts())\n    print('-'*50);print();","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:10.440854Z","iopub.execute_input":"2024-06-05T19:57:10.441249Z","iopub.status.idle":"2024-06-05T19:57:10.478261Z","shell.execute_reply.started":"2024-06-05T19:57:10.441208Z","shell.execute_reply":"2024-06-05T19:57:10.477021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.crosstab(df_train_label.condition, df_train_label.level)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:10.480228Z","iopub.execute_input":"2024-06-05T19:57:10.480670Z","iopub.status.idle":"2024-06-05T19:57:10.534132Z","shell.execute_reply.started":"2024-06-05T19:57:10.480630Z","shell.execute_reply":"2024-06-05T19:57:10.532976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Merging tables","metadata":{}},{"cell_type":"code","source":"df_train_1 = pd.merge(left = df_train_label,right=df_train_main,how='left', on = ['study_id']).reset_index(drop=True)\ndf_train = pd.merge(left=df_train_1,right=df_train_desc,how='left',on=['study_id','series_id']).reset_index(drop=True)\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:10.535799Z","iopub.execute_input":"2024-06-05T19:57:10.536202Z","iopub.status.idle":"2024-06-05T19:57:10.768416Z","shell.execute_reply.started":"2024-06-05T19:57:10.536140Z","shell.execute_reply":"2024-06-05T19:57:10.767252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"default_color_1 = 'black'\nsns.scatterplot(data=df_train, x='x', y='y', color=default_color_1, s = 20,  alpha=0.2)\n\nplt.grid()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:10.770468Z","iopub.execute_input":"2024-06-05T19:57:10.770901Z","iopub.status.idle":"2024-06-05T19:57:11.240624Z","shell.execute_reply.started":"2024-06-05T19:57:10.770864Z","shell.execute_reply":"2024-06-05T19:57:11.239377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image Printing","metadata":{}},{"cell_type":"code","source":"df_train_label[df_train_label.study_id==4003253]","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:11.245874Z","iopub.execute_input":"2024-06-05T19:57:11.246377Z","iopub.status.idle":"2024-06-05T19:57:11.268573Z","shell.execute_reply.started":"2024-06-05T19:57:11.246332Z","shell.execute_reply":"2024-06-05T19:57:11.267171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.series_description","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:11.270266Z","iopub.execute_input":"2024-06-05T19:57:11.270649Z","iopub.status.idle":"2024-06-05T19:57:11.283875Z","shell.execute_reply.started":"2024-06-05T19:57:11.270614Z","shell.execute_reply":"2024-06-05T19:57:11.282734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_label['series_description'] = df_train.series_description","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:11.285357Z","iopub.execute_input":"2024-06-05T19:57:11.285775Z","iopub.status.idle":"2024-06-05T19:57:11.294418Z","shell.execute_reply.started":"2024-06-05T19:57:11.285730Z","shell.execute_reply":"2024-06-05T19:57:11.293332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mrt(id, ser, inst,train_label_coordinates):\n    lag=20\n    path2 = path+'train_images/' + str(id) +'/' + str(ser)+'/' + str(inst) + '.dcm'\n\n    ds = dicom.dcmread(path2)\n    fig, ax = plt.subplots(figsize=(16, 8))\n    from matplotlib.colors import LogNorm \n\n    ax.imshow(ds.pixel_array, cmap ='CMRmap')     # Display the image\n\n    # Create a legend\n    legend_elements = []\n\n    # Plot the coordinates for the current condition\n    ab = train_label_coordinates[(train_label_coordinates.study_id==id) & \n                                          (train_label_coordinates.instance_number==inst)&\n                                         (train_label_coordinates.series_id==ser)]\n\n    a = 25 * max(ds.pixel_array.shape)/640\n    for _, row in ab.iterrows():\n        x, y = row['x'], row['y']\n\n        rect2 = patches.Rectangle((x - a, y - a), 2*a, 2*a, linewidth=2, edgecolor='white', facecolor='none')\n        rect1 = patches.Rectangle((x - a, y - a), 2*a, 2*a, linewidth=2, facecolor='white', alpha = 0.25)\n\n        ax.add_patch(rect2)\n        ax.add_patch(rect1)\n\n        # Add the condition to the legend\n        legend_elements.append(patches.Patch(facecolor='none', edgecolor='r', ))\n\n    # Add title\n    title = f\"{ab.series_description.unique()}, Study: {id}, Series: {ser}, Instance: {inst}\"\n    ax.set_title(title, fontsize=20)\n\n    # Display additional columns:\n    for _, row in ab.iterrows():\n        text = f\"level {row['level']}, {row['condition']}\"\n        ax.text(row['x'] + lag, row['y']+np.random.randint(-15, 15), text, fontsize=10, color='white', verticalalignment='center_baseline')\n    \n    plt.show() ","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:11.295851Z","iopub.execute_input":"2024-06-05T19:57:11.296863Z","iopub.status.idle":"2024-06-05T19:57:11.313064Z","shell.execute_reply.started":"2024-06-05T19:57:11.296821Z","shell.execute_reply":"2024-06-05T19:57:11.311791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Case #1\nid = 4003253\nser= 702807833\ninst=8\n\nmrt(id, ser, inst,df_train_label)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:11.314413Z","iopub.execute_input":"2024-06-05T19:57:11.314808Z","iopub.status.idle":"2024-06-05T19:57:11.878252Z","shell.execute_reply.started":"2024-06-05T19:57:11.314777Z","shell.execute_reply":"2024-06-05T19:57:11.877178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"id = 4003253\nser= 2448190387\ninst=11\nmrt(id, ser, inst,df_train_label)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:11.879737Z","iopub.execute_input":"2024-06-05T19:57:11.880071Z","iopub.status.idle":"2024-06-05T19:57:12.382021Z","shell.execute_reply.started":"2024-06-05T19:57:11.880044Z","shell.execute_reply":"2024-06-05T19:57:12.380595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def MR3d(id, ser):\n    \n    path_to_folder = path + \"train_images/\"+str(id)+'/'+str(ser)\n    def load_dicom(path):\n        dicom = pydicom.read_file(path)\n        data = dicom.pixel_array\n        data = data - np.min(data)\n        if np.max(data) != 0:\n            data = data / np.max(data)\n        data = (data * 255).astype(np.uint8)\n        return data\n\n    rc('animation', html='jshtml')\n\n    def load_dicom(filename):\n        ds = pydicom.dcmread(filename)\n        return ds.pixel_array\n\n    def load_dicom_line(path):\n        t_paths = sorted(\n            glob.glob(os.path.join(path, \"*\")), \n            key=lambda x: int(os.path.splitext(os.path.basename(x))[0].split(\"-\")[-1]),\n        )\n        images = []\n        for filename in t_paths:\n            data = load_dicom(filename)\n            if data.max() == 0:\n                continue\n            images.append(data)\n        return images\n\n    def create_animation(ims):\n        fig = plt.figure(figsize=(6, 6))\n        plt.axis('off')\n        im = plt.imshow(ims[0], cmap=\"CMRmap\")\n        text = plt.text(0.05, 0.05, f'Slide {1}', transform=fig.transFigure, fontsize=16, color='darkblue')\n\n        def animate_func(i):\n            im.set_array(ims[i])\n            return [im]\n        plt.title(f'id = {id}, series = {ser}')\n        \n        plt.close()  \n\n        return animation.FuncAnimation(fig, animate_func, frames=len(ims), interval=1000//10) #24\n\n    images = load_dicom_line(path_to_folder)\n    \n    return create_animation(images)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:12.383742Z","iopub.execute_input":"2024-06-05T19:57:12.384190Z","iopub.status.idle":"2024-06-05T19:57:12.403404Z","shell.execute_reply.started":"2024-06-05T19:57:12.384133Z","shell.execute_reply":"2024-06-05T19:57:12.402114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"id = 4003253\nser= 702807833\n\nMR3d(id, ser)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:12.404593Z","iopub.execute_input":"2024-06-05T19:57:12.404981Z","iopub.status.idle":"2024-06-05T19:57:15.807005Z","shell.execute_reply.started":"2024-06-05T19:57:12.404950Z","shell.execute_reply":"2024-06-05T19:57:15.805269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"id = 100206310\nser= 1012284084\nMR3d(id, ser)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:15.808363Z","iopub.execute_input":"2024-06-05T19:57:15.808720Z","iopub.status.idle":"2024-06-05T19:57:27.399229Z","shell.execute_reply.started":"2024-06-05T19:57:15.808689Z","shell.execute_reply":"2024-06-05T19:57:27.397252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"id = 100206310\nser= 1012284084\ninst=12\nmrt(id, ser, inst,df_train_label)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:27.401979Z","iopub.execute_input":"2024-06-05T19:57:27.402719Z","iopub.status.idle":"2024-06-05T19:57:27.973414Z","shell.execute_reply.started":"2024-06-05T19:57:27.402660Z","shell.execute_reply":"2024-06-05T19:57:27.972007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submission","metadata":{}},{"cell_type":"code","source":"df_unpivoted = df_train_main.melt(id_vars='study_id', var_name='condition', value_name='status')\ndf_unpivoted.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:27.974813Z","iopub.execute_input":"2024-06-05T19:57:27.975230Z","iopub.status.idle":"2024-06-05T19:57:27.998061Z","shell.execute_reply.started":"2024-06-05T19:57:27.975174Z","shell.execute_reply":"2024-06-05T19:57:27.996967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"frequency_table = df_unpivoted.groupby('condition')['status'].value_counts(normalize=True).unstack(fill_value=0)\nfrequency_table = frequency_table.reset_index()\nfrequency_table.rename(columns={ 'Normal/Mild': 'normal_mild', 'Moderate': 'moderate', 'Severe': 'severe'}, inplace=True)\nfrequency_table","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:27.999580Z","iopub.execute_input":"2024-06-05T19:57:27.999911Z","iopub.status.idle":"2024-06-05T19:57:28.052616Z","shell.execute_reply.started":"2024-06-05T19:57:27.999883Z","shell.execute_reply":"2024-06-05T19:57:28.050884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_images_dir = \"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_images\"\n\n\n# Get all unique IDs from the filenames in the test images directory\ntest_ids = [filename.split('.')[0] for filename in os.listdir(test_images_dir)]\n#test_ids =[4003252, 4003253]\nunique_ids = list(set(test_ids))\n\n# Generate the row_ids needed for submission by repeating each unique_id for each condition from df_train_main\nconditions = ['left_neural_foraminal_narrowing_l1_l2',\n              'left_neural_foraminal_narrowing_l2_l3',\n              'left_neural_foraminal_narrowing_l3_l4',\n              'left_neural_foraminal_narrowing_l4_l5',\n              'left_neural_foraminal_narrowing_l5_s1',\n              'left_subarticular_stenosis_l1_l2',\n              'left_subarticular_stenosis_l2_l3',\n              'left_subarticular_stenosis_l3_l4',\n              'left_subarticular_stenosis_l4_l5',\n              'left_subarticular_stenosis_l5_s1',\n              'right_neural_foraminal_narrowing_l1_l2',\n              'right_neural_foraminal_narrowing_l2_l3',\n              'right_neural_foraminal_narrowing_l3_l4',\n              'right_neural_foraminal_narrowing_l4_l5',\n              'right_neural_foraminal_narrowing_l5_s1',\n              'right_subarticular_stenosis_l1_l2',\n              'right_subarticular_stenosis_l2_l3',\n              'right_subarticular_stenosis_l3_l4',\n              'right_subarticular_stenosis_l4_l5',\n              'right_subarticular_stenosis_l5_s1',\n              'spinal_canal_stenosis_l1_l2',\n              'spinal_canal_stenosis_l2_l3',\n              'spinal_canal_stenosis_l3_l4',\n              'spinal_canal_stenosis_l4_l5',\n              'spinal_canal_stenosis_l5_s1']\n\nrow_ids = [f\"{id}_{condition}\" for id in unique_ids for condition in conditions]\n\n# Create DataFrame\ndf_submission = pd.DataFrame(row_ids, columns=['row_id'])\ndf_submission['normal_mild'] = 0.333333\ndf_submission['moderate']    = 0.333333\ndf_submission['severe']      = 0.333333\n","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:28.054430Z","iopub.execute_input":"2024-06-05T19:57:28.054906Z","iopub.status.idle":"2024-06-05T19:57:28.070363Z","shell.execute_reply.started":"2024-06-05T19:57:28.054866Z","shell.execute_reply":"2024-06-05T19:57:28.068863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:28.072142Z","iopub.execute_input":"2024-06-05T19:57:28.072595Z","iopub.status.idle":"2024-06-05T19:57:28.095999Z","shell.execute_reply.started":"2024-06-05T19:57:28.072556Z","shell.execute_reply":"2024-06-05T19:57:28.094937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T19:57:28.097581Z","iopub.execute_input":"2024-06-05T19:57:28.097945Z","iopub.status.idle":"2024-06-05T19:57:28.110067Z","shell.execute_reply.started":"2024-06-05T19:57:28.097909Z","shell.execute_reply":"2024-06-05T19:57:28.108570Z"},"trusted":true},"execution_count":null,"outputs":[]}]}