{"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":30746,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install fastcore","metadata":{"execution":{"iopub.status.busy":"2024-08-01T06:59:55.263741Z","iopub.execute_input":"2024-08-01T06:59:55.264154Z","iopub.status.idle":"2024-08-01T07:00:09.100730Z","shell.execute_reply.started":"2024-08-01T06:59:55.264105Z","shell.execute_reply":"2024-08-01T07:00:09.099362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nfrom pathlib import Path\nimport random\nimport os\nimport gc\nimport glob\nimport re\nfrom fastcore.xtras import *\nfrom fastcore.nb_imports import *","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-08-01T07:00:09.102902Z","iopub.execute_input":"2024-08-01T07:00:09.104660Z","iopub.status.idle":"2024-08-01T07:00:09.450906Z","shell.execute_reply.started":"2024-08-01T07:00:09.104617Z","shell.execute_reply":"2024-08-01T07:00:09.449930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nfrom pathlib import Path\nimport os\nimport gc\nimport random\nimport re\nfrom fastcore.xtras import *\nfrom fastcore.nb_imports import *\nfrom typing import List, Dict, Optional, Union\n\nclass TrainingData:\n    def __init__(self,input_root,train_csv,label_csv,series_csv,folder_re):\n        if not os.path.exists(input_root):\n            raise ValueError(f\"{input_root} directory does not exits\")\n        \n        self.input_root:str = Path(input_root)\n        for csv_file in [train_csv,label_csv,series_csv]:\n            if not os.path.exists(os.path.join(self.input_root,csv_file)):\n                raise FileNotFound(f\"CSV file not found {csv_file}\")\n        \n        def _read_csv(file_name):\n            df = pd.read_csv(os.path.join(self.input_root,file_name),low_memory=False)\n            return df\n        self.train_df:pd.DataFrame = _read_csv(train_csv)\n        self.label_df:pd.DataFrame = _read_csv(label_csv)\n        self.series_df:pd.DataFrame = _read_csv(series_csv)\n        self.train_images_loc:Path = self.input_root/\"train_images/\"\n        if not self.train_images_loc.exists():\n            raise FileNotFound(f\"{self.train_images_loc} not found\")\n    \n        self.folder_re:str = folder_re\n        self.study_ids: Optional[List[int]] = None\n        self.transformed_train:Optional[pd.DataFrame]=None\n        self.train_labels_merged:Optional[pd.DataFrame]=None\n        self.final_df:Optional[pd.DataFrame]=None\n        \n    \n    \n    def get_train_images(self):\n        train_images = globtastic(self.train_images_loc,recursive=True,folder_re=self.folder_re,skip_folder_re=\".DS\")\n        try:\n            self.study_ids = list(set([path.split(\"/\")[-3] for path in train_images]))\n        except ValueError:\n            raise ValueError(\"Could not extract study_ids from train_image path\")\n        return train_images\n    \n    def _transform_row(self,row):\n        new_rows = []\n        for key in row.keys():\n            df = {}\n            df['study_id'] = row['study_id']\n            if key == 'study_id': \n                continue\n            splits = key.split(\"_\")\n            df['condition'] = \" \".join(splits[:-2]).title()\n            df['level'] = splits[-2].capitalize()+\"/\"+splits[-1].capitalize()\n            df['severity'] = row[key]\n            new_rows.append(df)\n        return pd.DataFrame(new_rows)\n\n    def transform_train_df(self):\n        if type(self.study_ids) is not list:\n            self.study_ids = [self.study_ids]\n        print(f\"Number of patients : {self.study_ids}\")\n        filtered_df = self.train_df[self.train_df['study_id'].isin(map(int,self.study_ids))]\n        filtered_melted = filtered_df.melt(id_vars=['study_id'],var_name='condition_level',value_name='severity')\n        def get_condition(x):\n            return \" \".join(x['condition_level'].split(\"_\")[:-2]).title()\n        \n        def get_level(x):\n            return \"/\".join(x['condition_level'].split(\"_\")[-2:]).title()\n        filtered_melted['condition'] = filtered_melted.apply(get_condition,axis=1)\n        filtered_melted['level'] = filtered_melted.apply(get_level,axis=1)\n        self.transformed_train = filtered_melted\n        return self.transformed_train\n\n    def merge_labels(self,label_df):\n        transformed_train = self.transform_train_df() if self.transformed_train is None else self.transformed_train \n        self.train_labels_merged = transformed_train.merge(label_df,how=\"inner\"\n                      ,on=['study_id','condition','level']\n                      )\n        return self.train_labels_merged\n    \n    def merge_series_desc(self,label_df,series_desc):\n        train_labels_merged = self.merge_labels(label_df=self.label_df) if self.train_labels_merged is None else self.train_labels_merged\n        self.final_df = train_labels_merged.merge(series_desc,how=\"inner\"\n                                      ,on=['study_id','series_id'])\n        return self.final_df\n    \n    \n    def add_columns(self):\n        def construct_img_path(x):\n            img_path = f\"{self.input_root}/train_images/{str(x['study_id'])}/{str(x['series_id'])}/{str(x['instance_number'])}.dcm\"\n            return img_path\n\n        def img_exists(x):\n            return os.path.exists(x['img_path'])\n    \n        self.final_df['img_path'] = self.final_df.apply(construct_img_path,axis=1)\n        self.final_df['img_exits'] = self.final_df.apply(img_exists,axis=1)\n\n    \n    ","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:46:50.762158Z","iopub.execute_input":"2024-08-01T19:46:50.762730Z","iopub.status.idle":"2024-08-01T19:46:50.795779Z","shell.execute_reply.started":"2024-08-01T19:46:50.762686Z","shell.execute_reply":"2024-08-01T19:46:50.794537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_data = TrainingData(\"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification\"\n                            ,\"train.csv\"\n                            ,\"train_label_coordinates.csv\"\n                            ,\"train_series_descriptions.csv\"\n                            ,folder_re=r's/394.*|s/2481.*|s/282.*')\n\ntraining_data.train_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:46:51.090829Z","iopub.execute_input":"2024-08-01T19:46:51.091253Z","iopub.status.idle":"2024-08-01T19:46:51.254660Z","shell.execute_reply.started":"2024-08-01T19:46:51.091217Z","shell.execute_reply":"2024-08-01T19:46:51.253321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_images = training_data.get_train_images()\nlen(train_images)","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:46:51.419398Z","iopub.execute_input":"2024-08-01T19:46:51.420403Z","iopub.status.idle":"2024-08-01T19:46:56.241552Z","shell.execute_reply.started":"2024-08-01T19:46:51.420364Z","shell.execute_reply":"2024-08-01T19:46:56.240184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_data.study_ids","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:46:56.243836Z","iopub.execute_input":"2024-08-01T19:46:56.244490Z","iopub.status.idle":"2024-08-01T19:46:56.252604Z","shell.execute_reply.started":"2024-08-01T19:46:56.244448Z","shell.execute_reply":"2024-08-01T19:46:56.251334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_data.transform_train_df().head()","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:46:56.254416Z","iopub.execute_input":"2024-08-01T19:46:56.254909Z","iopub.status.idle":"2024-08-01T19:46:56.291282Z","shell.execute_reply.started":"2024-08-01T19:46:56.254868Z","shell.execute_reply":"2024-08-01T19:46:56.289969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_df = training_data.merge_series_desc(label_df=training_data.label_df,series_desc=training_data.series_df)\ntraining_data.add_columns()","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:46:56.293870Z","iopub.execute_input":"2024-08-01T19:46:56.294307Z","iopub.status.idle":"2024-08-01T19:46:56.565667Z","shell.execute_reply.started":"2024-08-01T19:46:56.294266Z","shell.execute_reply":"2024-08-01T19:46:56.564388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_df.head(30)","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:47:24.479760Z","iopub.execute_input":"2024-08-01T19:47:24.480731Z","iopub.status.idle":"2024-08-01T19:47:24.525816Z","shell.execute_reply.started":"2024-08-01T19:47:24.480687Z","shell.execute_reply":"2024-08-01T19:47:24.524653Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_df[final_df['img_exits']==False].shape","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:49:12.922499Z","iopub.execute_input":"2024-08-01T19:49:12.923647Z","iopub.status.idle":"2024-08-01T19:49:12.933684Z","shell.execute_reply.started":"2024-08-01T19:49:12.923596Z","shell.execute_reply":"2024-08-01T19:49:12.932606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from fastai.basics import *\nfrom fastai.callback.all import *\nfrom fastai.vision.all import *\nfrom fastai.medical.imaging import *","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:49:14.350935Z","iopub.execute_input":"2024-08-01T19:49:14.352005Z","iopub.status.idle":"2024-08-01T19:49:14.358697Z","shell.execute_reply.started":"2024-08-01T19:49:14.351970Z","shell.execute_reply":"2024-08-01T19:49:14.357246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"row = final_df[(final_df['condition']=='Spinal Canal Stenosis') & (final_df['level']=='L1/L2')].sample(1).iloc[0]\nmri_sample = Path(row['img_path']).dcmread()\nmri_sample.show()\nprint(row['condition'],row['level'],row['severity'],row['series_description'],row['study_id'])","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:49:16.177114Z","iopub.execute_input":"2024-08-01T19:49:16.177686Z","iopub.status.idle":"2024-08-01T19:49:16.451018Z","shell.execute_reply.started":"2024-08-01T19:49:16.177642Z","shell.execute_reply":"2024-08-01T19:49:16.449632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df=pd.read_csv(\"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train.csv\")\n","metadata":{"execution":{"iopub.status.busy":"2024-08-01T19:11:31.072210Z","iopub.execute_input":"2024-08-01T19:11:31.072625Z","iopub.status.idle":"2024-08-01T19:11:31.095746Z","shell.execute_reply.started":"2024-08-01T19:11:31.072592Z","shell.execute_reply":"2024-08-01T19:11:31.094624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n\n# Create a sample DataFrame\ndf = pd.DataFrame({\n    'Name': ['John', 'Jane', 'Mike'],\n    'Math': [90, 85, 70],\n    'Science': [95, 80, 75],\n    'History': [88, 92, 78]\n})\n\n# Melt the DataFrame\nmelted_df = df.melt(id_vars=['Name'], \n                    var_name='Subject', \n                    value_name='Score')\n\nprint(melted_df)","metadata":{"execution":{"iopub.status.busy":"2024-08-01T18:28:10.752813Z","iopub.execute_input":"2024-08-01T18:28:10.753251Z","iopub.status.idle":"2024-08-01T18:28:10.773759Z","shell.execute_reply.started":"2024-08-01T18:28:10.753212Z","shell.execute_reply":"2024-08-01T18:28:10.772332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df)","metadata":{"execution":{"iopub.status.busy":"2024-08-01T18:28:22.064836Z","iopub.execute_input":"2024-08-01T18:28:22.065245Z","iopub.status.idle":"2024-08-01T18:28:22.077194Z","shell.execute_reply.started":"2024-08-01T18:28:22.065215Z","shell.execute_reply":"2024-08-01T18:28:22.075790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.melt(id_vars=['study_id'],var_name='condition',value_name='severity')","metadata":{"execution":{"iopub.status.busy":"2024-08-01T18:31:08.556707Z","iopub.execute_input":"2024-08-01T18:31:08.558882Z","iopub.status.idle":"2024-08-01T18:31:08.586834Z","shell.execute_reply.started":"2024-08-01T18:31:08.558843Z","shell.execute_reply":"2024-08-01T18:31:08.585618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}