{"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":"#### Reference:\n\n1. https://www.kaggle.com/code/itsuki9180/a-segmentation-is-in-reverse-order\n1. https://www.kaggle.com/code/samuelcortinhas/rnsa-3d-model-train-pytorch\n1. https://www.kaggle.com/code/andradaolteanu/rsna-fracture-detection-dicom-images-explore#2.-Image-Data-%5B.dcm%5D\n1. https://www.kaggle.com/code/weixinxu/submit-baseline\n1. https://www.kaggle.com/code/mlwhiz/bilstm-pytorch-and-keras\n\n#### Modeling Reference:\n1. http://dx.doi.org/10.3174/ajnr.A7094\n1. https://blog.devgenius.io/resnet50-6b42934db431\n1. https://www.kaggle.com/code/samuelcortinhas/rnsa-3d-model-train-pytorch#Torch-dataloaders","metadata":{"id":"Ual0RqSlW4F0"}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"## Downloads","metadata":{"id":"_qtBuug5W4F3"}},{"cell_type":"code","source":"INTERNET = True\n\nif INTERNET == True:\n    !python --version\n    \n    !pip install monai\n    !pip install -q segmentation_models_pytorch\n    \n    !pip install pydicom\n    !pip install python-gdcm\n    !pip install pylibjpeg pylibjpeg-libjpeg pydicom","metadata":{"id":"yu3ndgUrW4F4","outputId":"8deeeda2-d82e-45e3-e279-287271b7ba53","execution":{"iopub.status.busy":"2023-03-31T12:03:51.837063Z","iopub.execute_input":"2023-03-31T12:03:51.837829Z","iopub.status.idle":"2023-03-31T12:05:02.735064Z","shell.execute_reply.started":"2023-03-31T12:03:51.837762Z","shell.execute_reply":"2023-03-31T12:05:02.733762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Import Libraries","metadata":{"id":"LA_kCUmHW4F5"}},{"cell_type":"code","source":"import os\nimport sys\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nfrom PIL import Image\nimport cv2\nimport re\nimport gc\nfrom tqdm import tqdm\nimport math\n\nimport matplotlib.pyplot as plt\nfrom matplotlib.patches import Rectangle\n\nimport skimage.transform as skTrans\nfrom skimage import exposure\n\nimport pydicom as dicom\nimport nibabel as nib\n\nimport albumentations as alb\nfrom albumentations.pytorch import ToTensorV2\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.cuda.amp import autocast, GradScaler\nfrom torch.optim.lr_scheduler import OneCycleLR\n\nimport tensorflow as tf\n\nfrom monai.transforms import Resize\nimport monai.transforms as transforms\n\nimport segmentation_models_pytorch as smp\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.model_selection import KFold, StratifiedKFold","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:02.738228Z","iopub.execute_input":"2023-03-31T12:05:02.738692Z","iopub.status.idle":"2023-03-31T12:05:23.178331Z","shell.execute_reply.started":"2023-03-31T12:05:02.738647Z","shell.execute_reply":"2023-03-31T12:05:23.176794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Config","metadata":{"id":"wxZqi55oW4F7"}},{"cell_type":"code","source":"SEED = 1927550\nIMG_SIZE = 512\nBATCH = 3\nEPOCH = 50\nCLASS = 9\nhidden1 = 128\nhidden2 = 64\nWORK = 'kaggle'\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\n\ntrainlosslog = []\ntrainacclog = []\nvalidlosslog = []\nvalidacclog = []","metadata":{"id":"OZCsaDR3W4F7","execution":{"iopub.status.busy":"2023-03-31T12:05:23.18026Z","iopub.execute_input":"2023-03-31T12:05:23.180639Z","iopub.status.idle":"2023-03-31T12:05:23.188592Z","shell.execute_reply.started":"2023-03-31T12:05:23.180601Z","shell.execute_reply":"2023-03-31T12:05:23.186679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"encoder_backbone = 'timm-efficientnet-b5'\nbest_acc = 0\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\n\n\nif WORK == 'kaggle':\n    work_path = '/kaggle/input'\nelif WORK == 'colab':\n    work_path = '/content/drive/MyDrive/Colab_Notebooks'\nelif WORK == 'jupyter':\n    work_path = 'G:/내 드라이브/Colab_Notebooks'\n\ntry:\n    os.mkdir('train_images')\n    os.mkdir('segmentations')\nexcept: pass\n    \nbase_path = f'{work_path}/rsna-2022-cervical-spine-fracture-detection'\ntrain_path = f'{base_path}/train_images'\nsegmentation_path = f'{base_path}/segmentations'\n\n# dataframe setting\ntrain_df = pd.read_csv(f\"{base_path}/train.csv\")\nss_df = pd.read_csv(f\"{base_path}/sample_submission.csv\")\nseg_df = pd.DataFrame({'mask_file': os.listdir(segmentation_path)})\n#ss_df = pd.read_csv(f\"{base_path}/sample_submission.csv\")\n#test_df = pd.read_csv(f\"{base_path}/test.csv\")\n\nseg_df['StudyInstanceUID'] = seg_df['mask_file'].apply(lambda x: x[:-4])\nseg_df['mask_file'] = seg_df['mask_file'].apply(lambda x: os.path.join(base_path, 'segmentations', x))\ndf = train_df.merge(seg_df, on='StudyInstanceUID', how='left')\ndf['image_folder'] = df['StudyInstanceUID'].apply(lambda x: os.path.join(base_path, 'train_images', x))\ndf['mask_file'].fillna('', inplace=True)\n\ndf_seg = df.query('mask_file != \"\"').reset_index(drop=True)\ndf_seg['fold'] = -1\n\nseg_revert = [\n    '1.2.826.0.1.3680043.1363',\n    '1.2.826.0.1.3680043.20120',\n    '1.2.826.0.1.3680043.2243',\n    '1.2.826.0.1.3680043.24606',\n    '1.2.826.0.1.3680043.32071'\n]","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:23.191877Z","iopub.execute_input":"2023-03-31T12:05:23.192303Z","iopub.status.idle":"2023-03-31T12:05:23.290306Z","shell.execute_reply.started":"2023-03-31T12:05:23.192246Z","shell.execute_reply":"2023-03-31T12:05:23.289043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vert_class = {\n    1: 'C1',\n    2: 'C2',\n    3: 'C3',\n    4: 'C4',\n    5: 'C5',\n    6: 'C6',\n    7: 'C7'\n}","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:23.292009Z","iopub.execute_input":"2023-03-31T12:05:23.292374Z","iopub.status.idle":"2023-03-31T12:05:23.297079Z","shell.execute_reply.started":"2023-03-31T12:05:23.292339Z","shell.execute_reply":"2023-03-31T12:05:23.296171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Useful Functions","metadata":{"id":"r7lLzzm6W4F8"}},{"cell_type":"code","source":"def load_dicom(uid, path, size=IMG_SIZE):\n    levels = [400, 600, 700]\n    windows = [1800, 2800, 4000]\n    path = sorted(path, key=lambda p: int(os.path.splitext(os.path.basename(p))[0]))\n    \n    depth_img = []\n    ImagePositionPatient_z = []\n    PatientUID = []\n    \n    for index, filename in enumerate(path):\n        windowed_img = []\n        for idx, level in enumerate(levels):\n            window = windows[idx]\n            maximum = level + window/2\n            minimum = level - window/2\n            \n            img_data = dicom.read_file(filename)\n            img = img_data.pixel_array\n            img = img.clip(minimum, maximum)\n            img = cv2.resize(img, (size, size), interpolation=cv2.INTER_LINEAR)\n            img = img - np.min(img)\n            img = img / (np.max(img) + 1e-4)\n            img = (img * 255).astype(np.uint16)\n\n            windowed_img.append(img)\n        \n        imgpos = img_data.ImagePositionPatient\n        ImagePositionPatient_z.append(imgpos[2])\n        PatientUID.append(f'{uid}_{index}')\n        \n        depth_img.append(windowed_img)\n        del(windowed_img)\n    \n    # image orientation: (depth, width, height, channel)\n    img = np.asarray(depth_img).transpose(0, 2, 3, 1)\n    del(depth_img)\n    \n    return img, ImagePositionPatient_z, PatientUID","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:23.29845Z","iopub.execute_input":"2023-03-31T12:05:23.298894Z","iopub.status.idle":"2023-03-31T12:05:23.312599Z","shell.execute_reply.started":"2023-03-31T12:05:23.29886Z","shell.execute_reply":"2023-03-31T12:05:23.311144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_nii(StudyInstanceUID, path, tot_class=CLASS, size=IMG_SIZE):\n    segment = nib.load(path).get_fdata() # convert to numpy array\n    # conversion from axial to sagittal view\n    seg = segment[:, ::-1, ::-1].transpose(2, 1, 0)\n    shape = seg.shape\n\n    masked = []\n    for idx in range(shape[2]): # for each depth\n        each_seg = seg[:, :, idx]\n        each_seg = cv2.resize(each_seg, (IMG_SIZE, IMG_SIZE), interpolation=cv2.INTER_LINEAR)\n        each_seg = each_seg.astype(np.uint16) * 255\n        \n        mask_7_class = []\n        for cl in range(tot_class):\n            mask_7_class.append(each_seg)\n\n        masked.append(mask_7_class)\n        del(mask_7_class)\n\n    mask = np.asarray(masked)\n    del(masked)\n\n    # image orientation: (depth, width, height, channel)\n    return mask.transpose(0, 2, 3, 1)","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:23.314271Z","iopub.execute_input":"2023-03-31T12:05:23.315007Z","iopub.status.idle":"2023-03-31T12:05:23.329745Z","shell.execute_reply.started":"2023-03-31T12:05:23.314953Z","shell.execute_reply":"2023-03-31T12:05:23.328375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def NormalizeData(data):\n    return (data - np.min(data)) / (np.max(data) - np.min(data))","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:23.331291Z","iopub.execute_input":"2023-03-31T12:05:23.331768Z","iopub.status.idle":"2023-03-31T12:05:23.346229Z","shell.execute_reply.started":"2023-03-31T12:05:23.331722Z","shell.execute_reply":"2023-03-31T12:05:23.344952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mode(arr):\n    vals, counts = np.unique(arr/255, return_counts=True)\n    max = 0\n    max_idx = 0\n\n    for idx in range(len(counts)):\n        if vals[idx] != 0:\n            if counts[idx] > max:\n                max = counts[idx]\n                max_idx = idx\n\n    return vals[max_idx]","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:23.347902Z","iopub.execute_input":"2023-03-31T12:05:23.34827Z","iopub.status.idle":"2023-03-31T12:05:23.357252Z","shell.execute_reply.started":"2023-03-31T12:05:23.348236Z","shell.execute_reply":"2023-03-31T12:05:23.356267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## test on Normalization and getting mask data","metadata":{}},{"cell_type":"code","source":"dcm_path = glob('/kaggle/input/rsna-2022-cervical-spine-fracture-detection/train_images/1.2.826.0.1.3680043.10633/*')\nimage, pos_z, patientid = load_dicom('1.2.826.0.1.3680043.10633', dcm_path)","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:23.360931Z","iopub.execute_input":"2023-03-31T12:05:23.361958Z","iopub.status.idle":"2023-03-31T12:05:51.289503Z","shell.execute_reply.started":"2023-03-31T12:05:23.361896Z","shell.execute_reply":"2023-03-31T12:05:51.287759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.DataFrame(list(zip(patientid, pos_z)), columns=['id', 'ImagePositionPatient_z'])\ndf","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:51.291333Z","iopub.execute_input":"2023-03-31T12:05:51.291759Z","iopub.status.idle":"2023-03-31T12:05:51.325988Z","shell.execute_reply.started":"2023-03-31T12:05:51.29172Z","shell.execute_reply":"2023-03-31T12:05:51.324079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"norm = NormalizeData(list(df['ImagePositionPatient_z']))\ndf = pd.DataFrame(list(zip(list(df['id']), norm)), columns=['id', 'ImagePositionPatient_z'])\ndf","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:51.328709Z","iopub.execute_input":"2023-03-31T12:05:51.329734Z","iopub.status.idle":"2023-03-31T12:05:51.34853Z","shell.execute_reply.started":"2023-03-31T12:05:51.329677Z","shell.execute_reply":"2023-03-31T12:05:51.347145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nii_path = '/kaggle/input/rsna-2022-cervical-spine-fracture-detection/segmentations/1.2.826.0.1.3680043.10633.nii'\nmask = load_nii('1.2.826.0.1.3680043.10633', nii_path, 3)\nlength = len(mask)//2\nindex = 200\nvert_list = np.unique(mask[length][index, :])/255\n\nif len(vert_list) > 1: print(vert_list[len(vert_list)-2:])\nelse: print(vert_list)\nplt.figure(figsize=(5, 5))\nplt.plot([0, 512], [index, index], color='red', linewidth=3)\nplt.imshow(mask[length])\nplt.axis('off')\nplt.show()\n\ndel(mask)","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:51.350322Z","iopub.execute_input":"2023-03-31T12:05:51.350756Z","iopub.status.idle":"2023-03-31T12:05:55.857685Z","shell.execute_reply.started":"2023-03-31T12:05:51.350715Z","shell.execute_reply":"2023-03-31T12:05:55.852157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nii_path = '/kaggle/input/rsna-2022-cervical-spine-fracture-detection/segmentations/1.2.826.0.1.3680043.1363.nii'\ndcm_path = glob('/kaggle/input/rsna-2022-cervical-spine-fracture-detection/train_images/1.2.826.0.1.3680043.1363/*.dcm')\nmask = load_nii('1.2.826.0.1.3680043.1363', nii_path, 3)\nmaskid_list = sorted(dcm_path, key=lambda p: int(os.path.splitext(os.path.basename(p))[0]))\n\nfor idx, maskid in enumerate(maskid_list):\n    maskid_list[idx] = int(maskid.split('/')[-1].split('.')[0])\n\nindex = 126\nlength = len(mask)//2\nreal_idx = len(maskid_list) - 1 - index\nidx_list = NormalizeData(maskid_list) * 512\nvert_list = np.unique(mask[length][round(idx_list[real_idx]), :])/255\n\nif len(vert_list) > 1: print(vert_list[len(vert_list)-2:])\nelse: print(vert_list)\nplt.figure(figsize=(5, 5))\nplt.plot([0, 512], [round(idx_list[real_idx]), round(idx_list[real_idx])], color='red', linewidth=3)\nplt.imshow(mask[length])\nplt.axis('off')\nplt.show()\n\ndel(mask)","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:55.859907Z","iopub.execute_input":"2023-03-31T12:05:55.860382Z","iopub.status.idle":"2023-03-31T12:05:58.172097Z","shell.execute_reply.started":"2023-03-31T12:05:55.860332Z","shell.execute_reply":"2023-03-31T12:05:58.170117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## test on printing images","metadata":{}},{"cell_type":"code","source":"UID = '1.2.826.0.1.3680043.1363'\npath_train = glob(f'{train_path}/{UID}/*')\npath_seg = f'{segmentation_path}/{UID}.nii'\n\n# convert train images\nimage, ImagePositionPatient_z, PatientUID = load_dicom(UID, path_train)\n# convert segmentation images\nmasks = load_nii(UID, path_seg, 3) # channel 3 to test printing","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:05:58.174209Z","iopub.execute_input":"2023-03-31T12:05:58.175166Z","iopub.status.idle":"2023-03-31T12:06:05.945528Z","shell.execute_reply.started":"2023-03-31T12:05:58.175119Z","shell.execute_reply":"2023-03-31T12:06:05.944197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(image.shape)\nnew_image = image[:, ::-1, ::-1, :].transpose(1, 2, 0, 3)\nprint_image = new_image[:, new_image.shape[1]//2, :]\nrot_image = cv2.rotate(print_image, cv2.ROTATE_180)\nrot_image = cv2.rotate(rot_image, cv2.ROTATE_90_CLOCKWISE)\nrot_image = cv2.flip(rot_image, 1)\nif UID not in seg_revert:\n    rot_image = cv2.flip(rot_image, 0)\nrot_image = cv2.resize(rot_image, (512, 512))\n    \nplt.figure(figsize=(5, 5))\nplt.imshow(rot_image)\nplt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:06:05.946951Z","iopub.execute_input":"2023-03-31T12:06:05.94731Z","iopub.status.idle":"2023-03-31T12:06:06.211822Z","shell.execute_reply.started":"2023-03-31T12:06:05.947276Z","shell.execute_reply":"2023-03-31T12:06:06.210797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_masks = []\nfor mask in masks:\n    if len(np.unique(mask)) > 1:\n        new_masks.append(mask)\n        \nrow = len(new_masks)//8\nplt.subplots(row, 8, figsize=(20, 50))\nfor num, mask in enumerate(new_masks):\n    if (num+1 <= row*8):\n        plt.subplot(row, 8, num+1)\n        plt.imshow(mask)\n        plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:06:06.213469Z","iopub.execute_input":"2023-03-31T12:06:06.213837Z","iopub.status.idle":"2023-03-31T12:06:27.101746Z","shell.execute_reply.started":"2023-03-31T12:06:06.213803Z","shell.execute_reply":"2023-03-31T12:06:27.100779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"length = len(new_masks)//2\nindex = 200\nvert_list = np.unique(new_masks[length][index, :])/255\n\nif len(vert_list) > 1: print(vert_list[len(vert_list)-2:])\nelse: print(vert_list)\nplt.figure(figsize=(5, 5))\nplt.plot([0, 512], [index, index], color='red', linewidth=3)\nplt.imshow(new_masks[length])\nplt.axis('off')\nplt.show()\n\ndel(new_masks)","metadata":{"execution":{"iopub.status.busy":"2023-03-31T12:06:27.103035Z","iopub.execute_input":"2023-03-31T12:06:27.104019Z","iopub.status.idle":"2023-03-31T12:06:27.226399Z","shell.execute_reply.started":"2023-03-31T12:06:27.103964Z","shell.execute_reply":"2023-03-31T12:06:27.224995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## preprocessing","metadata":{}},{"cell_type":"code","source":"studyuid_list = []\nmask_vert = []\n\n# images are loaded from C7 to C1.\n# it is evident from the axial images that index 120 displays the jaws\n# and 200 has ears in it\nfor idx in tqdm(range(len(df_seg))):\n    df = df_seg.iloc[idx]\n    uid = df['StudyInstanceUID']\n    img = df['image_folder']\n    image_path = glob(f'{img}/*.dcm')\n    mask_path = df['mask_file']\n\n    image, ImagePositionPatient_z, PatientUID = load_dicom(uid, image_path)\n    mask = load_nii(uid, mask_path)\n    \n    new_masks = []\n    for each_mask in mask:\n        if len(np.unique(each_mask)) > 1:\n            new_masks.append(each_mask)\n    length = len(new_masks)//2\n    \n    # width, height, depth, channel\n    new_image = image[:, ::-1, ::-1, :].transpose(1, 2, 0, 3)\n    data = NormalizeData(list(ImagePositionPatient_z))*511\n    \n    for index in range(len(PatientUID)):\n        id_index = round(data[index])\n        uid_id = PatientUID[index]\n        \n        if uid in seg_revert:\n            id_index = round(data[len(PatientUID)-index-1])\n            vert = mode(new_masks[length][id_index, :])\n        else:\n            vert = mode(new_masks[length][id_index, :])\n            \n        studyuid_list.append(uid_id)\n        mask_vert.append(vert)\n    \n    del(image)\n    del(mask)\n    del(ImagePositionPatient_z)\n    del(PatientUID)\n    del(new_masks)\n    del(new_image)\n    del(each_mask)","metadata":{"id":"3AA2ZCh7W4F_","execution":{"iopub.status.busy":"2023-03-31T12:06:27.229385Z","iopub.execute_input":"2023-03-31T12:06:27.230499Z","iopub.status.idle":"2023-03-31T14:01:22.419283Z","shell.execute_reply.started":"2023-03-31T12:06:27.23043Z","shell.execute_reply":"2023-03-31T14:01:22.415312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_save = pd.DataFrame(list(zip(studyuid_list, mask_vert)), columns=['id', 'vertebrae'])\ndf_save.to_csv('vert_list.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-03-31T14:01:22.424313Z","iopub.execute_input":"2023-03-31T14:01:22.424889Z","iopub.status.idle":"2023-03-31T14:01:22.552405Z","shell.execute_reply.started":"2023-03-31T14:01:22.424838Z","shell.execute_reply":"2023-03-31T14:01:22.551089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.rmdir('/kaggle/working/train_images')\nos.rmdir('/kaggle/working/segmentations')","metadata":{"execution":{"iopub.status.busy":"2023-03-31T14:01:22.554885Z","iopub.execute_input":"2023-03-31T14:01:22.555745Z","iopub.status.idle":"2023-03-31T14:01:22.565601Z","shell.execute_reply.started":"2023-03-31T14:01:22.555706Z","shell.execute_reply":"2023-03-31T14:01:22.564212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}