{"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":"Inspired from\n1. https://www.kaggle.com/chumajin/brain-tumor-eda-for-starter-english-version\n2. https://www.kaggle.com/furcifer/torch-efficientnet3d-for-mri-no-train","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport pydicom\nimport matplotlib.pyplot as plt\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport glob\nimport cv2\nimport torch\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset,DataLoader\nfrom torch import optim\n\nimport warnings\nwarnings.filterwarnings('ignore')\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nnp.seterr(divide='ignore', invalid='ignore')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.read_csv(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv\")\nlabels.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-22T06:16:22.932498Z","iopub.execute_input":"2021-07-22T06:16:22.932831Z","iopub.status.idle":"2021-07-22T06:16:22.96776Z","shell.execute_reply.started":"2021-07-22T06:16:22.932796Z","shell.execute_reply":"2021-07-22T06:16:22.966736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.MGMT_value.value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-07-22T06:16:22.973394Z","iopub.execute_input":"2021-07-22T06:16:22.973711Z","iopub.status.idle":"2021-07-22T06:16:22.985661Z","shell.execute_reply.started":"2021-07-22T06:16:22.973662Z","shell.execute_reply":"2021-07-22T06:16:22.984622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom(path , voi_lut=True, fix_monochrome=True , image_size = 256):\n    dicom = pydicom.read_file(path)\n    # VOI LUT (if available by DICOM device) is used to\n    # transform raw DICOM data to \"human-friendly\" view\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n    # depending on this value, X-ray may look inverted - fix that:\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    data = cv2.resize(data, (image_size, image_size))\n    return data","metadata":{"execution":{"iopub.status.busy":"2021-07-22T06:16:22.98727Z","iopub.execute_input":"2021-07-22T06:16:22.987581Z","iopub.status.idle":"2021-07-22T06:16:22.996368Z","shell.execute_reply.started":"2021-07-22T06:16:22.987552Z","shell.execute_reply":"2021-07-22T06:16:22.995241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#min depth should be 20 , delete the files which have less than depth 20\ndef load_3d(path , image_size = 256 , depth =32):\n    flair = sorted(glob.glob(f\"{path}/FLAIR/*.dcm\"))\n    t1w = sorted(glob.glob(f\"{path}/T1w/*.dcm\"))\n    t1wce = sorted(glob.glob(f\"{path}/T1wCE/*.dcm\"))\n    t2w = sorted(glob.glob(f\"{path}/T2w/*.dcm\"))\n    \n    depth_per_source = depth // 4\n    \n    flair_img = np.array([load_dicom(a , image_size) for a in flair[len(flair)//2 - depth_per_source//2:len(flair)//2 + depth_per_source//2]]).T\n    if flair_img.shape[-1] < depth_per_source:\n        n_zero = depth_per_source - flair_img.shape[-1]\n        flair_img = np.concatenate((flair_img, np.zeros((image_size, image_size, n_zero))), axis = -1)\n    \n    t1w_img = np.array([load_dicom(a , image_size) for a in t1w[len(t1w)//2 - depth_per_source//2:len(t1w)//2 + depth_per_source//2]]).T\n    if t1w_img.shape[-1] < depth_per_source:\n        n_zero = depth_per_source - t1w_img.shape[-1]\n        t1w_img = np.concatenate((t1w_img, np.zeros((image_size, image_size, n_zero))), axis = -1)\n    \n    t1wce_img = np.array([load_dicom(a , image_size) for a in t1wce[len(t1wce)//2 - depth_per_source//2:len(t1wce)//2 + depth_per_source//2]]).T\n    \n    if t1wce_img.shape[-1] < depth_per_source:\n        n_zero = depth_per_source - t1wce_img.shape[-1]\n        t1wce_img = np.concatenate((t1wce_img, np.zeros((image_size, image_size, n_zero))), axis = -1)\n  \n    t2w_img = np.array([load_dicom(a , image_size) for a in t2w[len(t2w)//2 - depth_per_source//2:len(t2w)//2 + depth_per_source//2]]).T\n    if t2w_img.shape[-1] < depth_per_source:\n        n_zero = depth_per_source - t2w_img.shape[-1]\n        t2w_img = np.concatenate((t2w_img, np.zeros((image_size, image_size, n_zero))), axis = -1)\n        \n    \n    \n    image_3d =  np.concatenate((flair_img, t1w_img, t1wce_img, t2w_img), axis = -1) #shpe= height x width x depth\n    image_3d = torch.tensor(image_3d)\n    image_3d = image_3d.permute(2 , 1 ,0)\n    \n    return image_3d\n    ","metadata":{"execution":{"iopub.status.busy":"2021-07-22T06:16:22.997798Z","iopub.execute_input":"2021-07-22T06:16:22.998104Z","iopub.status.idle":"2021-07-22T06:16:23.01507Z","shell.execute_reply.started":"2021-07-22T06:16:22.998072Z","shell.execute_reply":"2021-07-22T06:16:23.014014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"l = load_3d(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification/train/00121\")\nl.shape #depth , width , height","metadata":{"execution":{"iopub.status.busy":"2021-07-22T07:07:22.566983Z","iopub.execute_input":"2021-07-22T07:07:22.56743Z","iopub.status.idle":"2021-07-22T07:07:22.802337Z","shell.execute_reply.started":"2021-07-22T07:07:22.567391Z","shell.execute_reply":"2021-07-22T07:07:22.801542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(12, 12))\nfor i in range(32): \n    plt.subplot(4, 8, i+1)\n    plt.imshow(l[i])\n    plt.axis(\"off\")\n    ","metadata":{"execution":{"iopub.status.busy":"2021-07-22T07:07:24.495227Z","iopub.execute_input":"2021-07-22T07:07:24.495783Z","iopub.status.idle":"2021-07-22T07:07:26.430349Z","shell.execute_reply.started":"2021-07-22T07:07:24.495729Z","shell.execute_reply":"2021-07-22T07:07:26.429513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels[\"imfolder\"] = ['{0:05d}'.format(s) for s in labels[\"BraTS21ID\"]]\npath = \"../input/rsna-miccai-brain-tumor-radiogenomic-classification/train\"\nlabels['path'] = [os.path.join(path ,f) for f in labels[\"imfolder\"]]\ntrain = labels","metadata":{"execution":{"iopub.status.busy":"2021-07-22T06:34:53.371145Z","iopub.execute_input":"2021-07-22T06:34:53.371547Z","iopub.status.idle":"2021-07-22T06:34:53.380183Z","shell.execute_reply.started":"2021-07-22T06:34:53.37151Z","shell.execute_reply":"2021-07-22T06:34:53.378908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-22T06:34:58.880664Z","iopub.execute_input":"2021-07-22T06:34:58.88105Z","iopub.status.idle":"2021-07-22T06:34:58.893526Z","shell.execute_reply.started":"2021-07-22T06:34:58.881017Z","shell.execute_reply":"2021-07-22T06:34:58.892392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#torch dataset\nclass Brain(Dataset):\n    def __init__(self , df , image_size = 256 , depth =32):\n        self.df = df\n        self.img_size =image_size\n        self.d = depth\n    \n    def __len__(self):\n        return(len(self.df))\n    \n    def __getitem__(self , idx):\n        img_path = self.df.loc[idx,'path']\n        img_3d = load_3d(img_path , self.img_size , self.d)\n        img_3d = img_3d.unsqueeze(0) # channel_length , deth , width , height\n        \n        target = self.df.loc[idx,'MGMT_value']\n        \n        return img_3d , torch.tensor(target)\n        ","metadata":{"execution":{"iopub.status.busy":"2021-07-22T07:04:59.178746Z","iopub.execute_input":"2021-07-22T07:04:59.179438Z","iopub.status.idle":"2021-07-22T07:04:59.188995Z","shell.execute_reply.started":"2021-07-22T07:04:59.179392Z","shell.execute_reply":"2021-07-22T07:04:59.187907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = Brain(train)\nloader = DataLoader(data,shuffle=True,batch_size=2)\ni ,t = next(iter(loader))","metadata":{"execution":{"iopub.status.busy":"2021-07-22T07:11:46.725487Z","iopub.execute_input":"2021-07-22T07:11:46.726067Z","iopub.status.idle":"2021-07-22T07:11:47.484705Z","shell.execute_reply.started":"2021-07-22T07:11:46.72603Z","shell.execute_reply":"2021-07-22T07:11:47.483737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"i.shape , t","metadata":{"execution":{"iopub.status.busy":"2021-07-22T07:12:09.1261Z","iopub.execute_input":"2021-07-22T07:12:09.126791Z","iopub.status.idle":"2021-07-22T07:12:09.133692Z","shell.execute_reply.started":"2021-07-22T07:12:09.126735Z","shell.execute_reply":"2021-07-22T07:12:09.132605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Now the data is ready , to be fed through a 3D CNN model, this is just a base idea, you can add many things like how you will handle the differnt sources, augmentations , image size etc etc","metadata":{}}]}