{"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":"code","source":"!pip install /kaggle/input/rsna-monai-essential/monai-1.2.0-202306081546-py3-none-any.whl\n!pip install /kaggle/input/rsna-monai-essential/pylibjpeg-1.4.0-py3-none-any.whl\n!pip install /kaggle/input/rsna-monai-essential/python_gdcm-3.0.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:24:44.770082Z","iopub.execute_input":"2023-10-13T13:24:44.771021Z","iopub.status.idle":"2023-10-13T13:26:24.785911Z","shell.execute_reply.started":"2023-10-13T13:24:44.770976Z","shell.execute_reply":"2023-10-13T13:26:24.784769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install /kaggle/input/rsna-monai-essential/munch-4.0.0-py2.py3-none-any.whl\n\n!cp -r /kaggle/input/rsna-monai-essential/efficientnet_pytorch-0.7.1/efficientnet_pytorch-0.7.1 .\n!cp -r /kaggle/input/rsna-monai-essential/pretrainedmodels-0.7.4/pretrainedmodels-0.7.4 .\n\n!pip install ./efficientnet_pytorch-0.7.1\n!pip install ./pretrainedmodels-0.7.4","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:26:24.788441Z","iopub.execute_input":"2023-10-13T13:26:24.788789Z","iopub.status.idle":"2023-10-13T13:28:06.645507Z","shell.execute_reply.started":"2023-10-13T13:26:24.788755Z","shell.execute_reply":"2023-10-13T13:28:06.64439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !cp -r /kaggle/input/segmentation-models-pytorch-custome/segmentation_models.pytorch/segmentation_models.pytorch .","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:28:06.647337Z","iopub.execute_input":"2023-10-13T13:28:06.647676Z","iopub.status.idle":"2023-10-13T13:28:06.652743Z","shell.execute_reply.started":"2023-10-13T13:28:06.647644Z","shell.execute_reply":"2023-10-13T13:28:06.65178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -U /kaggle/input/rsna-monai-essential/timm-0.9.7-py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:28:06.655376Z","iopub.execute_input":"2023-10-13T13:28:06.655671Z","iopub.status.idle":"2023-10-13T13:28:39.722071Z","shell.execute_reply.started":"2023-10-13T13:28:06.655644Z","shell.execute_reply":"2023-10-13T13:28:39.720998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install /kaggle/input/segmentation-models-pytorch-custome/segmentation_models_pytorch-0.3.3-py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:28:39.723572Z","iopub.execute_input":"2023-10-13T13:28:39.723902Z","iopub.status.idle":"2023-10-13T13:29:11.773008Z","shell.execute_reply.started":"2023-10-13T13:28:39.723869Z","shell.execute_reply":"2023-10-13T13:29:11.771907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport os\nimport cv2\nimport glob\nimport gdcm\nimport pydicom\nimport zipfile\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport segmentation_models_pytorch as smp\nfrom scipy import ndimage as ndi\nimport nibabel\nfrom joblib import Parallel, delayed\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom collections import OrderedDict\nfrom scipy import stats","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:29:11.775005Z","iopub.execute_input":"2023-10-13T13:29:11.775395Z","iopub.status.idle":"2023-10-13T13:29:17.844952Z","shell.execute_reply.started":"2023-10-13T13:29:11.775362Z","shell.execute_reply":"2023-10-13T13:29:17.844044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport torch\nimport gdcm\nfrom torch.utils.tensorboard import SummaryWriter\nfrom torch.utils.data import Dataset\nimport pandas as pd\nimport monai\nfrom monai.data import ImageDataset, DataLoader\nfrom monai.transforms import EnsureChannelFirst, Compose, RandRotate90, Resize, ToTensor, AddChannel, ScaleIntensity\nimport matplotlib.pyplot as plt\nfrom pathlib import Path\nimport os\nimport glob\nimport tqdm\nfrom PIL import Image\nimport pydicom\nimport cv2\nfrom torch.nn.parameter import Parameter\nimport torch.nn.functional as F\n\nfrom torch import nn\nimport scipy\nimport albumentations\nimport torchvision\nimport gc\ngc.enable()\n\nimport timm\nimport time","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-10-13T13:29:59.28183Z","iopub.execute_input":"2023-10-13T13:29:59.282161Z","iopub.status.idle":"2023-10-13T13:30:10.833984Z","shell.execute_reply.started":"2023-10-13T13:29:59.282133Z","shell.execute_reply":"2023-10-13T13:30:10.833003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import Counter\n\ndef standardize_pixel_array(dcm: pydicom.dataset.FileDataset) -> np.ndarray:\n    \"\"\"\n    Source : https://www.kaggle.com/competitions/rsna-2023-abdominal-trauma-detection/discussion/427217\n    \"\"\"\n    # Correct DICOM pixel_array if PixelRepresentation == 1.\n    pixel_array = dcm.pixel_array\n    if dcm.PixelRepresentation == 1:\n        bit_shift = dcm.BitsAllocated - dcm.BitsStored\n        dtype = pixel_array.dtype \n        pixel_array = (pixel_array << bit_shift).astype(dtype) >>  bit_shift\n\n    intercept = float(dcm.RescaleIntercept)\n    slope = float(dcm.RescaleSlope)\n    center = int(dcm.WindowCenter)\n    width = int(dcm.WindowWidth)\n    low = center - width / 2\n    high = center + width / 2    \n\n    pixel_array = (pixel_array * slope) + intercept\n\n    # HU filter to isolate the body region\n    # min_hu = -150\n    # max_hu = 1000\n    # body_mask = np.where((pixel_array > min_hu) & (pixel_array < max_hu), 1, 0)\n    # pixel_array = pixel_array * body_mask\n\n    # Window-level clipping\n    pixel_array = np.clip(pixel_array, low, high)\n\n    return pixel_array\n\n\ndef pydicom_load_series(dir_path):\n    imgs_b = {}\n    for f in sorted(glob.glob(dir_path + '*')):\n        if 'test_images/3124/5842/514.dcm' in f:\n            continue\n        dicom = pydicom.dcmread(f)\n        pos_z = dicom[(0x20, 0x32)].value[-1]\n        img = standardize_pixel_array(dicom)\n        img = (img - img.min()) / (img.max() - img.min() + 1e-6)\n        if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n            img = 1 - img\n        imgs_b[pos_z] = img\n    # fix for error shape\n    ws, hs = [x.shape[0] for x in imgs_b.values()], [x.shape[1] for x in imgs_b.values()]\n    mws, mhs = stats.mode(ws)[0][0], stats.mode(hs)[0][0]\n    imgs = {k: v for k, v in imgs_b.items() if v.shape[0] == mws and v.shape[1] == mhs}\n    img_lst = sorted([(k, v) for k, v in imgs.items()], key=lambda x: x[0], reverse=False)\n    # single image fix\n    try:\n        arr = np.stack([x[1] for x in img_lst], -1)# if x[1].shape[0] == mws and x[1].shape[1] == mhs], -1)\n    except:\n        print('WTF')\n        arr = np.zeros((256, 256, len(img_lst)))\n    original_spacing_A = (float(dicom.PixelSpacing[0]), float(dicom.PixelSpacing[1]), float(dicom.SliceThickness))\n    return arr, original_spacing_A, [float(x) for x in imgs.keys()]\n\n\ndef resample_volume(volume, original_spacing, target_spacing):\n    # Calculate the resampling factor\n    zoom_factors = [\n        orig_spac/targ_spac for orig_spac, targ_spac in zip(original_spacing, target_spacing)\n    ]\n\n    # Resample the volume using scipy's ndimage.zoom function\n    resampled_volume = scipy.ndimage.zoom(volume, zoom_factors, order=1)  # order=1 represents bilinear interpolation\n\n    return resampled_volume\n\nimage_size = 384\ntransforms_valid = albumentations.Compose([\n    albumentations.Resize(image_size, image_size),\n])\n\ntensor_tfms = torchvision.transforms.Compose([\n            torchvision.transforms.ToTensor(),\n            torchvision.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n        ])","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:30:10.835802Z","iopub.execute_input":"2023-10-13T13:30:10.836137Z","iopub.status.idle":"2023-10-13T13:30:10.850795Z","shell.execute_reply.started":"2023-10-13T13:30:10.836106Z","shell.execute_reply":"2023-10-13T13:30:10.849843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"body_model = smp.Unet(\n    encoder_name=\"efficientnet-b0\",        # choose encoder, e.g. mobilenet_v2 or efficientnet-b7\n    encoder_weights=None,     # use `imagenet` pre-trained weights for encoder initialization\n    in_channels=3,                  # model input channels (1 for gray-scale images, 3 for RGB, etc.)\n    classes=1,                      # model output channels (number of classes in your dataset)\n).cuda()\n\nbody_model.load_state_dict(torch.load('/kaggle/input/segmentation-model-v2/body_model_v2.pth'))\n_ = body_model.eval()\n\nother_model = smp.Unet(\n    encoder_name=\"efficientnet-b0\",        # choose encoder, e.g. mobilenet_v2 or efficientnet-b7\n    encoder_weights=None,     # use `imagenet` pre-trained weights for encoder initialization\n    in_channels=3,                  # model input channels (1 for gray-scale images, 3 for RGB, etc.)\n    classes=4,                      # model output channels (number of classes in your dataset)\n).cuda()\n\nother_model.load_state_dict(torch.load('/kaggle/input/segmentation-model-v2/4_classes_seg_model_v2.pth'))\n_ = other_model.eval()","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:30:10.852405Z","iopub.execute_input":"2023-10-13T13:30:10.853016Z","iopub.status.idle":"2023-10-13T13:30:17.432288Z","shell.execute_reply.started":"2023-10-13T13:30:10.85298Z","shell.execute_reply":"2023-10-13T13:30:17.431346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cases = ['/kaggle/input/rsna-2023-abdominal-trauma-detection/train_images/32541/51775/']","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:30:17.434425Z","iopub.execute_input":"2023-10-13T13:30:17.434773Z","iopub.status.idle":"2023-10-13T13:30:17.439601Z","shell.execute_reply.started":"2023-10-13T13:30:17.434741Z","shell.execute_reply":"2023-10-13T13:30:17.438474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# debug for size\n# !mkdir crop_test\n# !cp -r /kaggle/input/rsna-2023-abdominal-trauma-detection/train_images/44515/ crop_test\n# !cp /kaggle/input/rsna-2023-abdominal-trauma-detection/train_images/26501/22032/172.dcm ./crop_test/44515/12236","metadata":{"execution":{"iopub.status.busy":"2023-10-13T13:30:17.44111Z","iopub.execute_input":"2023-10-13T13:30:17.441461Z","iopub.status.idle":"2023-10-13T13:30:17.451395Z","shell.execute_reply.started":"2023-10-13T13:30:17.441431Z","shell.execute_reply":"2023-10-13T13:30:17.450497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cases = glob.glob('/kaggle/input/rsna-2023-abdominal-trauma-detection/train_images/*/*/')[:50]\ncases = glob.glob('/kaggle/input/rsna-2023-abdominal-trauma-detection/test_images/*/*/')\n# cases = glob.glob('./crop_test/*/*/')[:5]\n\nN = 14","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:00:09.636322Z","iopub.execute_input":"2023-10-13T14:00:09.636646Z","iopub.status.idle":"2023-10-13T14:00:09.643Z","shell.execute_reply.started":"2023-10-13T14:00:09.636621Z","shell.execute_reply":"2023-10-13T14:00:09.642022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def gem(x, p=3, eps=1e-6):\n    return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1. / p)\n\n\nclass GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6):\n        super(GeM, self).__init__()\n        self.p = Parameter(torch.ones(1) * p)\n        self.eps = eps\n\n    def forward(self, x):\n        return gem(x, p=self.p, eps=self.eps)\n\n    def __repr__(self):\n        return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + ', ' + 'eps=' + str(\n            self.eps) + ')'\n\n\nclass TwoHeadUnet(smp.Unet):\n    def __init__(self, encoder_name='densenet121', n_class=4, pretrained=True, dropout=0.5, pool='AdaptiveAvgPool2d'):\n        smp.Unet.__init__(self, encoder_name=encoder_name, decoder_channels=(128, 64, 32, 16, 8),\n                          encoder_weights=None, in_channels=3, classes=n_class)\n\n        if pool == 'AdaptiveAvgPool2d':\n            self.pooling = nn.AdaptiveAvgPool2d(1)\n        elif pool == 'gem':\n            self.pooling = GeM()\n\n        n_features = self.encoder.out_channels[-1]\n\n        self.bowel_head = nn.Linear(n_features, 2)\n        self.extravasation_head = nn.Linear(n_features, 2)\n        self.kidney_head = nn.Linear(n_features, 3)\n        self.liver_head = nn.Linear(n_features, 3)\n        self.spleen_head = nn.Linear(n_features, 3)\n        self.any_head = nn.Linear(n_features, 2)\n\n        self.dropout = nn.Dropout(dropout)\n\n    @property\n    def model(self):\n        return self.encoder\n\n    def infer(self, x):\n        \"\"\"Sequentially pass `x` trough model`s encoder, decoder and heads\"\"\"\n        features = self.encoder(x)\n        return self.classification_head(features[-1])\n\n    def forward(self, x, N):\n        \"\"\"Sequentially pass `x` trough model`s encoder, decoder and heads\"\"\"\n\n        self.check_input_shape(x)\n\n        features = self.encoder(x)\n#         decoder_output = self.decoder(*features)\n\n#         masks = self.segmentation_head(decoder_output)\n        masks = None\n        x = self.pooling(features[-1])\n        x = self.dropout(nn.Flatten()(x))\n        x = x.reshape(-1, N, x.shape[-1]).max(1)[0]\n        return (masks, self.bowel_head(x), self.extravasation_head(x), self.kidney_head(x),\n                self.liver_head(x), self.spleen_head(x), self.any_head(x))\n        \n\nmodels = []\nfor file in glob.glob('/kaggle/input/rsna-ddp-2-pvtb2-naive-24-4-14-pretrain/ddp_2_pvtb2_naive_24_4_14_pretrain.yaml.upload/*.pth'):\n    print(file)\n    if 'seg_model.pth' in file: continue\n#     print(file)\n    model = TwoHeadUnet(encoder_name='pvt2_b2', pool='gem')\n    \n    od = torch.load(file, map_location='cpu')\n    nw = OrderedDict()\n    for k, v in od.items():\n        nw[k.replace('module.', '')] = v\n\n    model.load_state_dict(nw)\n    model = model.cuda()\n    model = model.eval()    \n    models.append(model)\n    \nfor file in glob.glob('/kaggle/input/ddp-2-pvtb3-naive-30-3-14-pretrain-1xlr/ddp_2_pvtb3_naive_30_3_14_pretrain_1xlr.yaml.upload/*.pth'):\n    print(file)\n    if 'seg_model.pth' in file: continue\n#     print(file)\n    model = TwoHeadUnet(encoder_name='pvt2_b3', pool='gem')\n    \n    od = torch.load(file, map_location='cpu')\n    nw = OrderedDict()\n    for k, v in od.items():\n        nw[k.replace('module.', '')] = v\n\n    model.load_state_dict(nw)\n    model = model.cuda()\n    model = model.eval()    \n    models.append(model)\n\n\nfor file in glob.glob('/kaggle/input/rsna-ddp-2-pvtb4-naive-24-2-14-pretrain-step2/ddp_2_pvtb4_naive_24_2_14_pretrain_step2.yaml.upload/*.pth'):\n    print(file)\n    if 'seg_model.pth' in file: continue\n#     print(file)\n    model = TwoHeadUnet(encoder_name='pvt2_b4', pool='gem')\n    \n    od = torch.load(file, map_location='cpu')\n    nw = OrderedDict()\n    for k, v in od.items():\n        nw[k.replace('module.', '')] = v\n\n    model.load_state_dict(nw)\n    model = model.cuda()\n    model = model.eval()    \n    models.append(model)\n\n    \nfor file in glob.glob('/kaggle/input/ddp-2-maxvit-t-naive-14-3-16-pretrain-207/ddp_2_maxvit_t_naive_14_3_16_pretrain_207.yaml.upload/*.pth'):\n    print(file)\n    if 'seg_model.pth' in file: continue\n#     print(file)\n    model = TwoHeadUnet(encoder_name='tu-maxvit_tiny_tf_384', pool='gem')\n    \n    od = torch.load(file, map_location='cpu')\n    nw = OrderedDict()\n    for k, v in od.items():\n        nw[k.replace('module.', '')] = v\n\n    model.load_state_dict(nw)\n    model = model.cuda()\n    model = model.eval()    \n    models.append(model)\n\nlen(models)\n# model = SimpleNet()\n# model.load_state_dict(torch.load('/kaggle/input/rsna-preprocessed-25d-model/0_18_0.4009.pth'))\n# model = model.cuda()\n# model = model.eval()","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:00:11.709457Z","iopub.execute_input":"2023-10-13T14:00:11.709785Z","iopub.status.idle":"2023-10-13T14:01:06.091454Z","shell.execute_reply.started":"2023-10-13T14:00:11.70976Z","shell.execute_reply":"2023-10-13T14:01:06.09041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_body_mask(resampled_volume_A):\n    ipt = [cv2.resize((resampled_volume_A[:, :, i]).astype(np.uint8), (512, 512)\n                 ) for i in range(resampled_volume_A.shape[2])]\n\n    ipt = [tensor_tfms(np.stack([e]*3, -1)) for e in ipt]\n\n    ipt = torch.stack(ipt)\n\n    with torch.no_grad():\n        BS = 32\n        preds = []\n        for i in range(0, len(ipt), BS):\n            with torch.cuda.amp.autocast():\n                r = body_model(ipt[i:i+BS].cuda())\n            r = torch.sigmoid(r.float())\n            r = torch.nn.functional.interpolate(\n                r, size=(resampled_volume_A.shape[0], resampled_volume_A.shape[1])\n            ).cpu().numpy()\n            preds.append(r)\n        preds = np.concatenate(preds)\n    \n    del ipt\n    gc.collect()\n    preds = preds > 0.5\n    return preds\n\n\ndef get_other_mask(resampled_volume_A):\n    ipt = [cv2.resize((resampled_volume_A[:, :, i]).astype(np.uint8), (512, 512)\n                 ) for i in range(resampled_volume_A.shape[2])]\n\n    ipt = [tensor_tfms(np.stack([e]*3, -1)) for e in ipt]\n\n    ipt = torch.stack(ipt)\n\n    with torch.no_grad():\n#         with torch.cuda.amp.autocast():\n#             r = other_model(ipt.cuda())\n#         r = torch.sigmoid(r.float())\n#         r = torch.nn.functional.interpolate(\n#             r, size=(resampled_volume_A.shape[0], resampled_volume_A.shape[1])\n#         ).cpu().numpy()\n        BS = 32\n        preds = []\n        for i in range(0, len(ipt), BS):\n            with torch.cuda.amp.autocast():\n                r = other_model(ipt[i:i+BS].cuda())\n            r = torch.sigmoid(r.float())\n            r = torch.nn.functional.interpolate(\n                r, size=(resampled_volume_A.shape[0], resampled_volume_A.shape[1])\n            ).cpu().numpy()\n            preds.append(r)\n        preds = np.concatenate(preds)\n    del ipt\n    gc.collect()\n    preds = preds > 0.5\n    return preds\n\ndef get_clean_body_mask(bd_mask):\n    new_bd_mask = np.zeros_like(bd_mask)\n    for mi in range(bd_mask.shape[0]):\n        sub = bd_mask[mi]\n\n        lbl, i = ndi.label(sub)\n        max_label, max_value = -1, 0\n        for pi in range(1, i+1):\n            if lbl[lbl == pi].sum() > max_value:\n                max_value = lbl[lbl == pi].sum()\n                max_label = pi\n        new_bd_mask[mi] = lbl == max_label\n    return new_bd_mask\n\ndef get_single_roi(other_mask):\n    if other_mask.sum() == 0:\n        zmin, zmax = 0, other_mask.shape[0]\n    else:\n        z = np.where(other_mask.reshape(other_mask.shape[0], -1).sum(1) > 150)[0]\n        zmin, zmax = z.min(), z.max()\n            \n    if zmax - zmin < 8:\n        zmin, zmax = 0, other_mask.shape[0]\n#     else:\n        \n    return zmin, zmax","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:01:06.093519Z","iopub.execute_input":"2023-10-13T14:01:06.093884Z","iopub.status.idle":"2023-10-13T14:01:06.106565Z","shell.execute_reply.started":"2023-10-13T14:01:06.09385Z","shell.execute_reply":"2023-10-13T14:01:06.10557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predicts = []\npids = []\nfor case in tqdm.tqdm(cases):\n    pid = case.split('/')[-3]\n    pids.append(pid)\n    try:\n        t0 = time.time()\n        arr2, os, zaxis = pydicom_load_series(case)\n        # single image fix\n        target_spacing = (1.0, 1.0, 10)  # For example, 1mm x 1mm x 1mm\n        middle = resample_volume(arr2, \n                                             [os[0], os[1], (max(zaxis) - min(zaxis)) / len(zaxis)], \n                                             target_spacing)\n        if middle.shape[-1] == 0:\n            middle = np.zeros((middle.shape[0], middle.shape[1], 2))\n\n        raw = (middle * 255.0).astype(np.uint8)\n        print(middle.shape)\n        print(f'T1: {time.time() - t0}')\n        body_mask = get_body_mask(raw)[:, 0, :, :]\n        other_mask = get_other_mask(raw)\n        \n        print(body_mask.shape, other_mask.shape)\n        \n        clean_body_mask = body_mask#get_clean_body_mask(body_mask)\n        left, right = get_single_roi(other_mask)\n        \n        raw = raw[:, :, left:right]\n        body_mask = body_mask[left:right]\n\n        p, s = case.split('/')[-3], case.split('/')[-2]\n        del arr2, middle, other_mask\n        gc.collect()\n        \n        print(f'T2: {time.time() - t0}')\n        vols = []\n        for i in range(1):\n            w, h, d = raw.shape\n            slices = []\n            \n            # sample\n            sel = []\n            if d < N:\n                sel = list(range(d))\n            else:\n                # gap = d / N\n                gap = int(np.floor(d / N))\n                offset = d - gap * (N - 1)\n                start = offset // 2\n                # print(d)\n                for i in range(N):\n                    sel.append(int(round(start + gap * i)))\n            while len(sel) < N:\n                sel.append(sel[-1])\n\n#             gap = int(np.floor(d / N))\n#             offset = d - gap * (N-1)\n#             start = offset // 2\n            for se in sel:\n                if se < d:\n                    mask = body_mask[se]\n                    if mask.sum() < 128 * 128:\n                        slices.append(raw[:, :,se])\n                    else:\n                        croped = raw[:, :, se]*mask\n                        x, y = np.where(mask > 0)\n                        slices.append(croped[x.min():x.max(), y.min():y.max()])\n#                 else:\n#                     slices.append(raw[:, :, -1])\n\n            slices = [transforms_valid(image=e)['image'] for e in slices]\n            slices = [tensor_tfms(np.stack([e]*3, -1)) for e in slices]\n\n            vol = np.stack(slices, 0).astype(np.float32)\n            vols.append(vol)\n        vol = np.concatenate(vols)\n        n, c, w, h = vol.shape\n        print(f'T3: {time.time() - t0}')\n\n        with torch.no_grad():    \n            agg = []\n            for model in models:\n                with torch.cuda.amp.autocast():\n                    outputs = model(torch.tensor(vol).cuda(), N)[1:]\n                    outputs2 = model(torch.tensor(vol).cuda().flip(-1), N)[1:]\n                pred = torch.cat([(torch.softmax(e.float(), 1)+torch.softmax(outputs2[i].float(), 1))/2 for i, e in enumerate(outputs)], 1).cpu().numpy()\n                pred = pred.mean(0).reshape(1, pred.shape[1])\n                agg.append(pred)\n            predicts.append(np.stack(agg).mean(0))\n        print(f'T4: {time.time() - t0}')\n\n    except:\n        raise\n        predicts.append(torch.tensor(np.array([[0.94424, 0.05576, 0.81774, 0.18226, 0.86099, 0.09626, \n                                                0.04275, 0.79468, 0.16624, 0.03908, 0.75401, 0.1573, 0.08869, 0.42141, 0.57869]])))\n#     break","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:01:06.107995Z","iopub.execute_input":"2023-10-13T14:01:06.10834Z","iopub.status.idle":"2023-10-13T14:01:32.069888Z","shell.execute_reply.started":"2023-10-13T14:01:06.10831Z","shell.execute_reply":"2023-10-13T14:01:32.068853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred = np.concatenate(predicts)\n\ncols = 'bowel_healthy,bowel_injury,extravasation_healthy,extravasation_injury,kidney_healthy,kidney_low,kidney_high,liver_healthy,liver_low,liver_high,spleen_healthy,spleen_low,spleen_high'.split(',')\ncols, len(cols)\n\npred_df = pd.DataFrame(pred[:, :-2], columns=cols)\npred_df['any_injury'] = pred[:, -1]\n\npred_df['patient_id'] = pids","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:01:32.072274Z","iopub.execute_input":"2023-10-13T14:01:32.072848Z","iopub.status.idle":"2023-10-13T14:01:32.092621Z","shell.execute_reply.started":"2023-10-13T14:01:32.072815Z","shell.execute_reply":"2023-10-13T14:01:32.091783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pred_df['bowel_injury'] = pred_df['bowel_injury'] * 1\n# pred_df['extravasation_injury'] = pred_df['extravasation_injury'] * 1.2\n# pred_df['kidney_low'] = pred_df['kidney_low'] * 1.2\n# pred_df['kidney_high'] = pred_df['kidney_high'] * 1.4\n# pred_df['liver_low'] = pred_df['liver_low'] * 1.2\n# pred_df['liver_high'] = pred_df['liver_high'] * 1.4\n# pred_df['spleen_low'] = pred_df['spleen_low'] * 1.2\n# pred_df['spleen_high'] = pred_df['spleen_high'] * 1.4","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:01:32.093746Z","iopub.execute_input":"2023-10-13T14:01:32.094537Z","iopub.status.idle":"2023-10-13T14:01:32.098885Z","shell.execute_reply.started":"2023-10-13T14:01:32.094506Z","shell.execute_reply":"2023-10-13T14:01:32.098038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df = pred_df.groupby('patient_id').mean()\npred_df['bowel_injury'] = pred_df['bowel_injury'] * 1\npred_df['extravasation_injury'] = pred_df['extravasation_injury'] * 1","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:01:32.100256Z","iopub.execute_input":"2023-10-13T14:01:32.100849Z","iopub.status.idle":"2023-10-13T14:01:32.127688Z","shell.execute_reply.started":"2023-10-13T14:01:32.10082Z","shell.execute_reply":"2023-10-13T14:01:32.126555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df.to_csv('submission.csv')","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:01:32.129056Z","iopub.execute_input":"2023-10-13T14:01:32.129397Z","iopub.status.idle":"2023-10-13T14:01:32.149159Z","shell.execute_reply.started":"2023-10-13T14:01:32.129369Z","shell.execute_reply":"2023-10-13T14:01:32.148379Z"},"trusted":true},"execution_count":null,"outputs":[]}]}