{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"The objective of this competition is to locate fractures in cervical spine (neck) CT images at both the level of a single vertebrae and the level of the patient as a whole. To stop neurologic degeneration and paralysis following trauma, it is crucial to locate any vertebral fractures as soon as possible.","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport glob\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport os\nimport nibabel as nib\nfrom tqdm import tqdm\nimport squarify as sq\n\n# installing pydicom dependencies\n!pip install pylibjpeg\n!pip install python_gdcm\n!pip install pylibjpeg_libjpeg\n!pip install glob2\n\nfrom glob import glob\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:19:09.500024Z","iopub.execute_input":"2022-08-19T19:19:09.50051Z","iopub.status.idle":"2022-08-19T19:20:08.196497Z","shell.execute_reply.started":"2022-08-19T19:19:09.500415Z","shell.execute_reply":"2022-08-19T19:20:08.194742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#declaring the path variables\nbase=\"../input/rsna-2022-cervical-spine-fracture-detection/\"\ndicom_path_var = base +\"train_images/\"\ndir_nii = base+\"segmentations/\"\nall_nii = glob(dir_nii + '*.nii')","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.19921Z","iopub.execute_input":"2022-08-19T19:20:08.199582Z","iopub.status.idle":"2022-08-19T19:20:08.217118Z","shell.execute_reply.started":"2022-08-19T19:20:08.19953Z","shell.execute_reply":"2022-08-19T19:20:08.21608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training Data Exploration","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(base + \"/train.csv\")\nbounding_box_df = pd.read_csv(base + \"/train_bounding_boxes.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.218822Z","iopub.execute_input":"2022-08-19T19:20:08.219326Z","iopub.status.idle":"2022-08-19T19:20:08.278318Z","shell.execute_reply.started":"2022-08-19T19:20:08.219281Z","shell.execute_reply":"2022-08-19T19:20:08.277413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_df.shape)\ntrain_df.head()\n","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.280866Z","iopub.execute_input":"2022-08-19T19:20:08.281194Z","iopub.status.idle":"2022-08-19T19:20:08.307636Z","shell.execute_reply.started":"2022-08-19T19:20:08.281155Z","shell.execute_reply":"2022-08-19T19:20:08.306374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* we have StudyInstanceUID of a patient\n* The patient level outcome, i.e. if any of the vertebrae are fractured.\n* 7 columns representing 7 vertebrates telling if which vertebrae got fractured (1) within the studyInstancUID","metadata":{}},{"cell_type":"code","source":"train_df.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.309309Z","iopub.execute_input":"2022-08-19T19:20:08.309799Z","iopub.status.idle":"2022-08-19T19:20:08.324518Z","shell.execute_reply.started":"2022-08-19T19:20:08.309763Z","shell.execute_reply":"2022-08-19T19:20:08.323672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(bounding_box_df.shape)\nbounding_box_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.325978Z","iopub.execute_input":"2022-08-19T19:20:08.32629Z","iopub.status.idle":"2022-08-19T19:20:08.340357Z","shell.execute_reply.started":"2022-08-19T19:20:08.326261Z","shell.execute_reply":"2022-08-19T19:20:08.339583Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bounding_box_df.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.341336Z","iopub.execute_input":"2022-08-19T19:20:08.341684Z","iopub.status.idle":"2022-08-19T19:20:08.355387Z","shell.execute_reply.started":"2022-08-19T19:20:08.341653Z","shell.execute_reply":"2022-08-19T19:20:08.353917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_patients = train_df.patient_overall.value_counts(normalize=True)\ntotal_patients","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.356738Z","iopub.execute_input":"2022-08-19T19:20:08.357249Z","iopub.status.idle":"2022-08-19T19:20:08.371867Z","shell.execute_reply.started":"2022-08-19T19:20:08.357213Z","shell.execute_reply":"2022-08-19T19:20:08.370433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"color_palette = sns.color_palette('pastel')\nkeys = [\"no fracture\", \"atleast 1 fracture\"]\nexplode = [0,0.1]\nplt.pie(total_patients ,labels = keys ,explode = explode, colors=color_palette,  autopct='%.2f%%')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.373492Z","iopub.execute_input":"2022-08-19T19:20:08.373892Z","iopub.status.idle":"2022-08-19T19:20:08.519938Z","shell.execute_reply.started":"2022-08-19T19:20:08.373859Z","shell.execute_reply":"2022-08-19T19:20:08.518313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Percentage people with atleast one vertebrae of the given study is fractured or not.\n\n47.6%","metadata":{}},{"cell_type":"code","source":"overall_fractures = train_df[[f\"C{i}\" for i in range(1,8)]].sum(axis=0)\npercentage_of_fracture = round((train_df[[f\"C{i}\" for i in range(1,8)]].sum(axis=0))/overall_fractures.sum()*100,2)\noverall_fractures.values\nlabels = [f'{overall_fractures.index[i]}  = {percentage_of_fracture[i]}%' for i in range(0,7)]\nprint(labels)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.526789Z","iopub.execute_input":"2022-08-19T19:20:08.528106Z","iopub.status.idle":"2022-08-19T19:20:08.552528Z","shell.execute_reply.started":"2022-08-19T19:20:08.528036Z","shell.execute_reply":"2022-08-19T19:20:08.55094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sq.plot(sizes=overall_fractures,label=labels,color= color_palette)\n\n","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.555308Z","iopub.execute_input":"2022-08-19T19:20:08.556762Z","iopub.status.idle":"2022-08-19T19:20:08.786575Z","shell.execute_reply.started":"2022-08-19T19:20:08.556665Z","shell.execute_reply":"2022-08-19T19:20:08.785409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x , y = overall_fractures.index, overall_fractures.values/overall_fractures.sum()\nfig, ax = plt.subplots(figsize=(10, 5), nrows=1, ncols=1)\nax.bar(x,y,color=color_palette)\nax.set_title(\"Individual vertebrae % fractured cases\")\nfor i in range(len(x)):\n    ax.text(i,y[i], f\"{round(y[i]*100, 2)}%\")\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:08.78825Z","iopub.execute_input":"2022-08-19T19:20:08.788869Z","iopub.status.idle":"2022-08-19T19:20:09.016827Z","shell.execute_reply.started":"2022-08-19T19:20:08.788821Z","shell.execute_reply":"2022-08-19T19:20:09.015592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Each vertebrae has following % of fractured cases within the training dataset\n\n* C1 = 10.11%\n* C2 = 19.74%\n* C3 = 5.06%\n* C4 = 7.48%\n* C5 = 11.22%\n* C6 = 19.18%\n* C7 = 27.22%","metadata":{}},{"cell_type":"markdown","source":"# Gathering common Bounding box ids and EDA","metadata":{}},{"cell_type":"code","source":"bounding_box_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:09.018961Z","iopub.execute_input":"2022-08-19T19:20:09.01977Z","iopub.status.idle":"2022-08-19T19:20:09.036385Z","shell.execute_reply.started":"2022-08-19T19:20:09.019721Z","shell.execute_reply":"2022-08-19T19:20:09.035304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bounding_box_df['StudyInstanceUID'] = bounding_box_df['StudyInstanceUID'].astype('str')\nbounding_box_df['slice_number'] = bounding_box_df['slice_number'].astype('str')\nbounding_box_df['x_min'] = bounding_box_df['x'].astype('int64')\nbounding_box_df['y_min'] = bounding_box_df['y'].astype('int64')\nbounding_box_df['x_max'] = bounding_box_df['x_min'] + bounding_box_df['width'].astype('int64')\nbounding_box_df['y_max'] = bounding_box_df['y_min'] + bounding_box_df['height'].astype('int64')\nbounding_box_df.drop(['x','y','width','height'], axis=1, inplace=True)\nbounding_box_df","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:09.038109Z","iopub.execute_input":"2022-08-19T19:20:09.039293Z","iopub.status.idle":"2022-08-19T19:20:09.073919Z","shell.execute_reply.started":"2022-08-19T19:20:09.039246Z","shell.execute_reply":"2022-08-19T19:20:09.07284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nvalid_dicom_ids = [x.split('/')[-1] for x in glob(dicom_path_var + '*')]\nids_also_in_train = bounding_box_df['StudyInstanceUID'].apply(lambda x : x if x in valid_dicom_ids else None)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:09.075371Z","iopub.execute_input":"2022-08-19T19:20:09.075794Z","iopub.status.idle":"2022-08-19T19:20:09.311903Z","shell.execute_reply.started":"2022-08-19T19:20:09.075758Z","shell.execute_reply":"2022-08-19T19:20:09.310415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nii_ids = [x.split('/')[-1][:-4] for x in all_nii]\nisin_nii_ids = bounding_box_df['StudyInstanceUID'].apply(lambda x : x if x in nii_ids else None)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:09.313653Z","iopub.execute_input":"2022-08-19T19:20:09.314023Z","iopub.status.idle":"2022-08-19T19:20:09.333199Z","shell.execute_reply.started":"2022-08-19T19:20:09.313987Z","shell.execute_reply":"2022-08-19T19:20:09.331913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"intersecting_dfs = bounding_box_df.iloc[isin_nii_ids.dropna().index]\nintersecting_dfs.reset_index(drop=True, inplace=True)\nintersecting_dfs","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:09.334906Z","iopub.execute_input":"2022-08-19T19:20:09.335767Z","iopub.status.idle":"2022-08-19T19:20:09.354416Z","shell.execute_reply.started":"2022-08-19T19:20:09.335693Z","shell.execute_reply":"2022-08-19T19:20:09.353024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Drawing few figures","metadata":{}},{"cell_type":"code","source":"#refered to https://www.kaggle.com/code/songseungwon/eda-let-s-draw-the-fracture-more-clearly\n\nfig = plt.figure(figsize=(12,12))\n\nfor i, row in intersecting_dfs.iterrows():\n    s_uid = row['StudyInstanceUID']\n    s_num = row['slice_number']\n    x_min = row['x_min']\n    x_max = row['x_max']\n    y_min = row['y_min']\n    y_max = row['y_max']\n    \n    nii = nib.load(dir_nii + s_uid + '.nii')\n    # (ref) discussion : Explaining Data and Submission in detail\n    nii = nii.get_fdata()[:, ::-1, ::-1].transpose(2,1,0)\n    nii = nii[int(s_num)]\n    \n    dicom = pydicom.read_file(dicom_path_var + s_uid + f'/{s_num}.dcm')\n    dicom = dicom.pixel_array\n    dicom = (dicom - np.min(dicom)) / np.max(dicom)\n    dicom = (dicom * 255).astype(np.uint8)\n    dicom = cv2.cvtColor(dicom, cv2.COLOR_GRAY2RGB)\n    cv2.rectangle(dicom, pt1=(x_min, y_min), pt2=(x_max, y_max), color=(255,0,0), thickness=3)\n    if i <= 8:\n        ax = fig.add_subplot(int(f'33{i+1}'))\n        ax.imshow(nii, alpha=1, cmap='gray')\n        ax.imshow(dicom, alpha=0.45)\n        ax.set_title(f'sample({i+1})\\n')\n        ax.axis('off')\n    else:\n        break;\n        \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T19:20:09.355651Z","iopub.execute_input":"2022-08-19T19:20:09.356006Z","iopub.status.idle":"2022-08-19T19:20:13.726118Z","shell.execute_reply.started":"2022-08-19T19:20:09.355962Z","shell.execute_reply":"2022-08-19T19:20:13.725019Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]}]}