{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install monai","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:35:28.409026Z","iopub.execute_input":"2023-09-12T20:35:28.409389Z","iopub.status.idle":"2023-09-12T20:35:42.312999Z","shell.execute_reply.started":"2023-09-12T20:35:28.409358Z","shell.execute_reply":"2023-09-12T20:35:42.311949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROOT_PATH = '/kaggle/input/rsna-2023-abdominal-trauma-detection'\nRESIZE_DIM = 2 # 1mmx1mmx1mm voxel","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:35:42.315151Z","iopub.execute_input":"2023-09-12T20:35:42.315497Z","iopub.status.idle":"2023-09-12T20:35:42.320693Z","shell.execute_reply.started":"2023-09-12T20:35:42.315468Z","shell.execute_reply":"2023-09-12T20:35:42.319695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from glob import glob\nimport pandas as pd\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:35:42.321886Z","iopub.execute_input":"2023-09-12T20:35:42.322205Z","iopub.status.idle":"2023-09-12T20:35:42.699714Z","shell.execute_reply.started":"2023-09-12T20:35:42.322177Z","shell.execute_reply":"2023-09-12T20:35:42.698944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_paths = glob(f'{ROOT_PATH}/train_images/*/*/')\n\ntrain_df = pd.DataFrame(train_paths, columns=[\"image_path\"])\ntrain_df['patient_id'] = train_df.image_path.map(lambda x: x.split('/')[-3]).astype(int)\ntrain_df['series_id'] = train_df.image_path.map(lambda x: x.split('/')[-2]).astype(int)\nprint('train:')\nprint(f'# Size: {len(train_df)}')\ndisplay(train_df.head())","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-09-12T20:35:42.702025Z","iopub.execute_input":"2023-09-12T20:35:42.702472Z","iopub.status.idle":"2023-09-12T20:35:49.631422Z","shell.execute_reply.started":"2023-09-12T20:35:42.70244Z","shell.execute_reply":"2023-09-12T20:35:49.63063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"grouped_df = train_df.groupby([\"patient_id\", \"series_id\"])","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:35:49.632609Z","iopub.execute_input":"2023-09-12T20:35:49.633152Z","iopub.status.idle":"2023-09-12T20:35:49.638248Z","shell.execute_reply.started":"2023-09-12T20:35:49.633121Z","shell.execute_reply":"2023-09-12T20:35:49.637283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"index_df = pd.DataFrame([(patient_id, series_id) for (patient_id, series_id), group in grouped_df], columns=[\"patient_id\", \"series_id\"])\nindex_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:35:49.639727Z","iopub.execute_input":"2023-09-12T20:35:49.640855Z","iopub.status.idle":"2023-09-12T20:35:49.854463Z","shell.execute_reply.started":"2023-09-12T20:35:49.640807Z","shell.execute_reply":"2023-09-12T20:35:49.853489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path_df = index_df.copy()\npath_df[\"path\"] = f\"{ROOT_PATH}/train_images/\" + path_df[\"patient_id\"].astype(str) + \"/\" + path_df[\"series_id\"].astype(str)\npath_df = path_df.groupby('patient_id')['path'].agg(list).reset_index()\ndisplay(path_df.head())\npaths = path_df[\"path\"].to_list()\npaths[:5]","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:35:49.855853Z","iopub.execute_input":"2023-09-12T20:35:49.856541Z","iopub.status.idle":"2023-09-12T20:35:49.952111Z","shell.execute_reply.started":"2023-09-12T20:35:49.856505Z","shell.execute_reply":"2023-09-12T20:35:49.951074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import monai\nfrom monai.data import ImageDataset, DataLoader\nfrom monai.transforms import Compose, Spacing, EnsureChannelFirst, PadListDataCollate\n\ntransform = Compose([\n    EnsureChannelFirst(),\n    Spacing(pixdim=[RESIZE_DIM]*3),\n])\n\n# paths: List[List[str]] of length M\n# labels: nd.array of shape (M, C)\n# M: Number of unique patient_id\n# C: Number of classes of label array (one-hot-encoded)\n\ncheck_ds = ImageDataset(image_files=paths, reader=\"PydicomReader\", transform=transform)\ncheck_loader = DataLoader(check_ds, collate_fn = PadListDataCollate())\n\ntry:\n    for im in check_loader:\n        print(type(im), im.shape)\nexcept Exception as e:\n    print(\"Error:\")\n    print(repr(e))","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:45:14.408706Z","iopub.execute_input":"2023-09-12T20:45:14.409117Z","iopub.status.idle":"2023-09-12T20:45:32.135713Z","shell.execute_reply.started":"2023-09-12T20:45:14.409084Z","shell.execute_reply":"2023-09-12T20:45:32.134444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Hacky way to achieve this.","metadata":{}},{"cell_type":"code","source":"import torch\nfrom monai.transforms import Pad, EnsureChannelFirst\nfrom monai.data import Dataset, list_data_collate\n\ndef max_shape_pad(tensor_list):\n    shapes = np.array([tensor.shape for tensor in tensor_list])\n    target_shape = shapes.max(axis=0)\n    padded_tensors = []\n    for tensor in tensor_list:\n        current_shape = np.array(tensor.shape)\n        if (current_shape == target_shape).all():\n            padded_tensors.append(tensor)\n        else:\n            pad_dims = [(0, 0) for _ in range(len(target_shape))]  # Initialize symmetric padding dimensions\n            for dim in range(len(target_shape)):\n                if current_shape[dim] < target_shape[dim]:\n                    pad_total = target_shape[dim] - current_shape[dim]\n                    pad_before = pad_total // 2\n                    pad_after = pad_total - pad_before\n                    pad_dims[dim] = (pad_before, pad_after)\n            padded_tensor = Pad(to_pad=pad_dims)(tensor)\n            padded_tensors.append(padded_tensor)\n            \n    shapes = np.array([np.array(tensor.shape) for tensor in padded_tensors])\n    cat_tensors = torch.cat(padded_tensors, 0)\n    return cat_tensors\n\n# Example usage:\ntensor_list = [torch.tensor([[1, 2, 3, 4, 5 ,6]]), torch.tensor([[3, 4, 5]])]\npadded_tensors = max_shape_pad(tensor_list)\nprint(padded_tensors)\nfor tensor in padded_tensors:\n    print(tensor)\n","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:38:17.139216Z","iopub.execute_input":"2023-09-12T20:38:17.139594Z","iopub.status.idle":"2023-09-12T20:38:17.152664Z","shell.execute_reply.started":"2023-09-12T20:38:17.139564Z","shell.execute_reply":"2023-09-12T20:38:17.15163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from monai.data import Dataset, list_data_collate\nfrom monai.transforms import Resize\n\n\n# Define the CustomDataset (as provided in your previous response)\nclass CustomDataset(Dataset):\n    def __init__(self, image_files, labels, transform):\n        self.image_files = image_files\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.image_files)\n\n    def __getitem__(self, index):\n        img_paths = self.image_files[index]\n        img_list = [self.transform(path) for path in img_paths]\n        label = self.labels[index]\n        if len(img_list) > 1:\n            return max_shape_pad(img_list), label\n        else:\n            return img_list[0], label","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:38:17.340342Z","iopub.execute_input":"2023-09-12T20:38:17.341184Z","iopub.status.idle":"2023-09-12T20:38:17.349589Z","shell.execute_reply.started":"2023-09-12T20:38:17.341143Z","shell.execute_reply":"2023-09-12T20:38:17.34866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from monai.transforms import LoadImage\nfrom monai.data import pad_list_data_collate\n\ntransform = Compose([\n    LoadImage(reader=\"PydicomReader\", image_only=True, ensure_channel_first=False, dtype=np.float32),\n    EnsureChannelFirst(),\n    Spacing(pixdim=[RESIZE_DIM]*3),\n])\n\n# Create an instance of CustomDataset\ncheck_ds = CustomDataset(image_files=paths, labels = np.arange(len(paths)) ,transform=transform)\ncheck_loader = DataLoader(check_ds)\n\niterator = iter(check_loader)\nfor i in range(5):\n    im, label = next(iterator)\n    print(f\"iter {i}\")\n    print(type(im), im.shape, label)","metadata":{"execution":{"iopub.status.busy":"2023-09-12T20:39:45.766356Z","iopub.execute_input":"2023-09-12T20:39:45.766764Z","iopub.status.idle":"2023-09-12T20:40:26.51356Z","shell.execute_reply.started":"2023-09-12T20:39:45.766732Z","shell.execute_reply":"2023-09-12T20:40:26.512382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}],"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"}}