{"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":"# Install timm package from local directory\n!pip install '/kaggle/input/timm-pack/timm_package/timm-0.6.12-py3-none-any.whl'","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-08-14T07:43:22.413207Z","iopub.execute_input":"2023-08-14T07:43:22.414118Z","iopub.status.idle":"2023-08-14T07:43:54.046311Z","shell.execute_reply.started":"2023-08-14T07:43:22.414084Z","shell.execute_reply":"2023-08-14T07:43:54.04509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The medical images provided are in (two types of) Dicom format, and in order to read these \n# we will need to install and import the required dependent libraries:\n\n'''\n## If Online : install required packages for dcm processing \n!pip install -qU pylibjpeg pylibjpeg-openjpeg pylibjpeg-libjpeg pydicom python-gdcm dicomsdl\n\n#import all the required dicom packages\nimport gdcm\nimport pydicom\nimport pylibjpeg\nimport dicomsdl\n'''\n\n!pip install pylibjpeg --no-index --find-links=file:///kaggle/input/read-dicom-set\n!pip install pylibjpeg-openjpeg --no-index --find-links=file:///kaggle/input/read-dicom-set\n!pip install pylibjpeg-libjpeg --no-index --find-links=file:///kaggle/input/read-dicom-set\n!pip install pydicom --no-index --find-links=file:///kaggle/input/read-dicom-set\n!pip install python-gdcm --no-index --find-links=file:///kaggle/input/read-dicom-set\n!pip install dicomsdl --no-index --find-links=file:///kaggle/input/read-dicom-set","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:43:54.049199Z","iopub.execute_input":"2023-08-14T07:43:54.049875Z","iopub.status.idle":"2023-08-14T07:45:03.784794Z","shell.execute_reply.started":"2023-08-14T07:43:54.04983Z","shell.execute_reply":"2023-08-14T07:45:03.783438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\nimport torch\nimport torch.nn as nn\nfrom torchvision import transforms\n\nimport os\n\n#import pydicom as dicom\nimport pydicom\nimport cv2\nimport PIL\nfrom PIL import Image\n\nimport timm\nimport torch.optim as optim\nfrom sklearn import model_selection\nfrom sklearn.metrics import f1_score\n\nfrom tqdm.autonotebook import tqdm\n#from torchvision import models\n\nfrom joblib import Parallel, delayed\n\n\n\nimport gc\ngc.collect()\ntorch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:03.787042Z","iopub.execute_input":"2023-08-14T07:45:03.787454Z","iopub.status.idle":"2023-08-14T07:45:04.064881Z","shell.execute_reply.started":"2023-08-14T07:45:03.787412Z","shell.execute_reply":"2023-08-14T07:45:04.063827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def set_seed(seed = 42):\n    '''Sets the seed of the entire notebook so results are the same every time we run.\n    This is for REPRODUCIBILITY.'''\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    # When running on the CuDNN backend, two further options must be set\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    # Set a fixed value for the hash seed\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    print('> SEEDING DONE')\n    \nset_seed(42)","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:04.067923Z","iopub.execute_input":"2023-08-14T07:45:04.068294Z","iopub.status.idle":"2023-08-14T07:45:04.08176Z","shell.execute_reply.started":"2023-08-14T07:45:04.06826Z","shell.execute_reply":"2023-08-14T07:45:04.080683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config :\n    BATCH_SIZE = 1 #1 works, 16 threws exception\n    #MODEL_PATH = '/kaggle/input/efficientb4-model/model.bin'\n    # if resnet\n    #MODEL_PATH = '/kaggle/input/resnet18/model.bin'\n    \n    # if efficientnet \n    MODEL_PATH = '/kaggle/input/tf_efficientnetv2_s/model.bin'\n\n    NUM_CLASSES = 1","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:04.083378Z","iopub.execute_input":"2023-08-14T07:45:04.08372Z","iopub.status.idle":"2023-08-14T07:45:04.091458Z","shell.execute_reply.started":"2023-08-14T07:45:04.083689Z","shell.execute_reply":"2023-08-14T07:45:04.090549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Dataset:\n    def __init__(self, df, transform=None):\n        self.df = df.copy()\n        self.transform = transform\n     \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        \n        patient_id = self.df.loc[idx, 'patient_id']\n        image_id = self.df.loc[idx, 'image_id']\n        prediction_id = self.df.loc[idx, 'prediction_id']\n        \n        # Get and preprocess images\n        # This path should be changed\n        #png_path = '/kaggle/input/rsna-png-images-same-format-as-original/output/rsna_pngs/train_images'\n        #png_path = '/kaggle/working/output/test_images' # test images path\n        png_path = \"./test_images\"\n        # Image path\n        image_png_path =  os.path.join(png_path, patient_id.astype(str), image_id.astype(str)+'.png')\n\n        # convert image to RGB\n        image = Image.open(image_png_path).convert('RGB')\n        \n        # Check if image is RGB \n        #print('image shape = ', np.array(image).shape)\n        \n        image = image.resize((1024,912))\n        \n        # Apply transformers on images\n        if self.transform:\n            image = self.transform(image).to(torch.float32)\n        \n        # Convert to tensors\n        #image = torch.tensor(image, dtype=torch.long)\n        \n        \n        \n        #{ 'image' : torch.tensor(image, dtype=torch.long),\n         #        'prediction_id' : prediction_id\n          #         }\n        \n        return image, prediction_id","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:04.092914Z","iopub.execute_input":"2023-08-14T07:45:04.093303Z","iopub.status.idle":"2023-08-14T07:45:04.10287Z","shell.execute_reply.started":"2023-08-14T07:45:04.093259Z","shell.execute_reply":"2023-08-14T07:45:04.101672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"class CNN(nn.Module):\n    def __init__(self):\n        super(CNN, self).__init__()\n        #self.network = models.resnet18(pretrained=True)\n        #n_features = self.network.fc.out_features\n        \n        self.network = timm.create_model('resnet18', pretrained=False, in_chans=3)\n        n_features = self.network.fc.out_features\n        \n        # add additional layer that maps 2048 extracted features from resnet to 1 feature \n        #determining the class\n        self.classifier_layer = nn.Sequential(\n            nn.Linear(n_features , 256),\n            nn.Dropout(0.), # 0.3 in the training part, There is no dropout in the inference part\n            #Dropout with p=0 is equivalent to the identity operation\n            nn.Linear(256 , 1)\n        )\n    \n    def forward(self, xb):        \n        xb = self.network(xb)\n        xb = self.classifier_layer(xb)\n        return torch.sigmoid(xb) #xb","metadata":{"execution":{"iopub.status.busy":"2023-07-17T08:39:50.612428Z","iopub.execute_input":"2023-07-17T08:39:50.614801Z","iopub.status.idle":"2023-07-17T08:39:50.631588Z","shell.execute_reply.started":"2023-07-17T08:39:50.614752Z","shell.execute_reply":"2023-07-17T08:39:50.630816Z"}}},{"cell_type":"code","source":"class BreastCancerModel(nn.Module):\n    def __init__(self, Config):\n        super().__init__()\n        self.efficientnet = timm.create_model('efficientnet_b4', pretrained=False,\n                                             in_chans=1)\n        \n        in_features = self.efficientnet.classifier.in_features\n        self.efficientnet.classifier = nn.Linear(in_features, Config.NUM_CLASSES)   \n        \n    def forward(self, image):\n        output = self.efficientnet(image)\n        \n        return output\n","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:04.104511Z","iopub.execute_input":"2023-08-14T07:45:04.104831Z","iopub.status.idle":"2023-08-14T07:45:04.11606Z","shell.execute_reply.started":"2023-08-14T07:45:04.104802Z","shell.execute_reply":"2023-08-14T07:45:04.115388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Efficientnetv2_s\ndef 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.0 / p)\n\n\nclass GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6, p_trainable=False):\n        super(GeM, self).__init__()\n        if p_trainable:\n            self.p = Parameter(torch.ones(1) * p)\n        else:\n            self.p = p\n        self.eps = eps\n\n    def forward(self, x):\n        ret = gem(x, p=self.p, eps=self.eps)\n        return ret\n\n    def __repr__(self):\n        return (\n            self.__class__.__name__\n            + \"(\"\n            + \"p=\"\n            + \"{:.4f}\".format(self.p.data.tolist()[0])\n            + \", \"\n            + \"eps=\"\n            + str(self.eps)\n            + \")\"\n        )\n\nclass Efficientnetv2_s(nn.Module):\n    def __init__(self, p=3, p_trainable=False, eps=1e-6):\n        super(Efficientnetv2_s, self).__init__()\n        \n        # tf_efficientnetv2_s\n        self.efficientnetv2_s = timm.create_model('tf_efficientnetv2_s', pretrained=False, in_chans=3)\n        model = self.efficientnetv2_s\n        clsf = model.default_cfg['classifier']\n        n_features = model._modules[clsf].in_features\n        model._modules[clsf] = nn.Identity()\n        self.fc = nn.Linear(n_features, 1) # cancer\n        self.pool = nn.Sequential(\n            GeM(p=p, eps=eps, p_trainable=p_trainable),\n            nn.Flatten())\n    \n    # if tf_efficientnetv2_s\n    def forward(self, x):\n        x = self.efficientnetv2_s(x) \n        #x = self.efficientnetv2_s.forward_features(x)\n        #x = self.pool(x)\n        logits = self.fc(x)\n        return logits   ","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:04.117241Z","iopub.execute_input":"2023-08-14T07:45:04.117957Z","iopub.status.idle":"2023-08-14T07:45:04.131519Z","shell.execute_reply.started":"2023-08-14T07:45:04.117926Z","shell.execute_reply":"2023-08-14T07:45:04.130357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Models(nn.Module):\n    def __init__(self):\n        super(Models, self).__init__()\n        #self.network = models.resnet18(pretrained=True)\n        #n_features = self.network.fc.out_features\n        \n        # Resnet\n        self.resnet = timm.create_model('resnet18', pretrained=False, in_chans=3)\n        n_features_resnet = self.resnet.fc.out_features\n        \n        self.classifier_layer_resnet = nn.Sequential(\n            nn.Linear(n_features_resnet , 256),\n            nn.Dropout(0.8), # 0.3\n            nn.Linear(256 , 1) #NUM_CLASSES = 1\n        )\n        \n        # Efficientnet\n        #self.efficientnet = timm.create_model('tf_efficientnetv2_s', pretrained=True, in_chans=3)\n        self.efficientnet = timm.create_model('efficientnet_b4', pretrained=False, in_chans=3)\n        in_features_efficientnet = self.efficientnet.classifier.in_features\n        \n        self.classifier_layer_efficientnet = nn.Sequential(\n            nn.Linear(in_features_efficientnet , 256),\n            nn.Dropout(0.5),\n            nn.Linear(256 , 1)\n        )\n        \n        # tf_efficientnetv2_s\n        self.model = timm.create_model('tf_efficientnetv2_s', pretrained=False, in_chans=3)\n        model = self.model\n        clsf = model.default_cfg['classifier']\n        n_features = model._modules[clsf].in_features\n        model._modules[clsf] = nn.Identity()\n        self.fc = nn.Linear(n_features, 1) # cancer\n        #self.pool = nn.Sequential(\n        #    GeM(p=p, eps=eps, p_trainable=p_trainable),\n        #    nn.Flatten())\n    \n    # if tf_efficientnetv2_s\n    def forward(self, x):\n        x = self.model(x)\n        #x = self.model.forward_features(x)\n        #x = self.pool(x)\n        logits = self.fc(x)\n        return logits   \n        ","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:04.132992Z","iopub.execute_input":"2023-08-14T07:45:04.1339Z","iopub.status.idle":"2023-08-14T07:45:04.147Z","shell.execute_reply.started":"2023-08-14T07:45:04.133875Z","shell.execute_reply":"2023-08-14T07:45:04.145945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n# Preprocess test images (convert to png format and cut off empty space)\n\ntest_dcm_images_path = '/kaggle/input/rsna-breast-cancer-detection/test_images'\npatient = '10008'\n\npatient_input_path = test_dcm_images_path + '/' + patient\n\n# Convert test images to png\n#output_path =  '/kaggle/working/output/rsna_pngs/test_images'\noutput_path =  '/kaggle/working/output/test_images'\n\n# Create directory if it does not exists\nif not os.path.isdir(output_path+'/'+patient):\n    os.makedirs(output_path+'/'+patient)\n\nfor image in os.listdir(patient_input_path):\n    image_input_path = patient_input_path + '/'+ image\n    dicom_image = pydicom.dcmread(image_input_path)\n    image_array = dicom_image.pixel_array\n    scaled_img = (np.maximum(image_array,0) / image_array.max()) * 255.0\n    if dicom_image.PhotometricInterpretation == \"MONOCHROME1\":\n        scaled_img = 1 - scaled_img\n    img = scaled_img.astype(np.uint8)\n    resized_image = cv2.resize(img, (1024, 912))\n    #cv2.imwrite(output_path + '/' + patient + '/' + image.replace('dcm', 'png'),resized_image)\n    \n    # 2. Crop\n    X = resized_image\n    # Some images have narrow exterior \"frames\" that complicate selection of the main data. Cutting off the frame\n    X = X[5:-5, 5:-5]\n    \n    \n    # regions of non-empty pixels\n    output= cv2.connectedComponentsWithStats((X > 0.05).astype(np.uint8)[:, :], 8, cv2.CV_32S)\n\n    # stats.shape == (N, 5), where N is the number of regions, 5 dimensions correspond to:\n    # left, top, width, height, area_size\n    stats = output[2]\n    \n    # finding max area which always corresponds to the breast data. \n    idx = stats[1:, 4].argmax() + 1\n    x1, y1, w, h = stats[idx][:4]\n    x2 = x1 + w\n    y2 = y1 + h\n    \n    # cutting out the breast data\n    X_fit = X[y1: y2, x1: x2]\n    \n    cv2.imwrite(output_path + '/' + patient + '/' + image.replace('dcm', 'png'),X_fit)\n    \n\n    # Plot png image\n    #img = mpimg.imread(output_path + '/' + patient + '/' + image.replace('dcm', 'png'))\n    #imgplot = plt.imshow(img)\n    #plt.show()\n\n    \n","metadata":{"execution":{"iopub.status.busy":"2023-05-30T08:04:06.408068Z","iopub.execute_input":"2023-05-30T08:04:06.409205Z","iopub.status.idle":"2023-05-30T08:04:08.679008Z","shell.execute_reply.started":"2023-05-30T08:04:06.409158Z","shell.execute_reply":"2023-05-30T08:04:08.677863Z"}}},{"cell_type":"code","source":"class CFG:\n    seed = 42\n    resize_dim = 1024\n    aspect_ratio = True\n    img_size = (1024, 912)\n    #batch_size = 16\n    \n    # Model\n    #model_name = \"efficientnet_b4\"\n    num_classes = 1\n    n_channels = 3\n    \n    test_img_path = \"./test_images\"\n\n    \nos.environ['CUDA_VISIBLE_DEVICES'] = \"0,1\"\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:04.150521Z","iopub.execute_input":"2023-08-14T07:45:04.150839Z","iopub.status.idle":"2023-08-14T07:45:04.160245Z","shell.execute_reply.started":"2023-08-14T07:45:04.150798Z","shell.execute_reply":"2023-08-14T07:45:04.159353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor\nimport re\nimport pydicom\nimport glob\nfrom PIL import Image\n\ndef fit_image(fname, size=1024):\n    # 1. Read, resize\n    patient = fname.split('/')[-2]\n    image = fname.split('/')[-1][:-4]\n    dicom = pydicom.dcmread(fname)\n    img = dicom.pixel_array\n    img = (img - img.min()) / (img.max() - img.min())\n    if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        img = 1 - img\n    #img = cv2.resize(img, (512, 512))\n    img = cv2.resize(img, (1024, 912))\n\n    \n    # 2. Crop\n    X = img\n    # Some images have narrow exterior \"frames\" that complicate selection of the main data. Cutting off the frame\n    X = X[5:-5, 5:-5]\n    \n    \n    # regions of non-empty pixels\n    output= cv2.connectedComponentsWithStats((X > 0.05).astype(np.uint8)[:, :], 8, cv2.CV_32S)\n\n    # stats.shape == (N, 5), where N is the number of regions, 5 dimensions correspond to:\n    # left, top, width, height, area_size\n    stats = output[2]\n    \n    # finding max area which always corresponds to the breast data. \n    idx = stats[1:, 4].argmax() + 1\n    x1, y1, w, h = stats[idx][:4]\n    x2 = x1 + w\n    y2 = y1 + h\n    \n    # cutting out the breast data\n    X_fit = X[y1: y2, x1: x2]\n    \n    patient_id, im_id = os.path.basename(os.path.dirname(fname)), os.path.basename(fname)[:-4]\n    os.makedirs(f'{CFG.test_img_path}/{patient_id}', exist_ok=True)\n    cv2.imwrite(f'{CFG.test_img_path}/{patient_id}/{im_id}.png', (X_fit[:, :] * 255).astype(np.uint8))\n\n    \n\ndef fit_all_images(all_images):\n    with ThreadPoolExecutor(2) as p:\n        for i in tqdm(p.map(fit_image, all_images), total=len(all_images)):\n            pass\n\nall_images = glob.glob('/kaggle/input/rsna-breast-cancer-detection/test_images/*/*') \n# all_images = glob.glob('/kaggle/input/rsna-breast-cancer-detection/train_images/10006/*')\nfit_all_images(all_images)\n","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:04.161876Z","iopub.execute_input":"2023-08-14T07:45:04.162266Z","iopub.status.idle":"2023-08-14T07:45:06.568185Z","shell.execute_reply.started":"2023-08-14T07:45:04.162236Z","shell.execute_reply":"2023-08-14T07:45:06.56719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!find test_images | head","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:45:06.569708Z","iopub.execute_input":"2023-08-14T07:45:06.570733Z","iopub.status.idle":"2023-08-14T07:45:07.567443Z","shell.execute_reply.started":"2023-08-14T07:45:06.570698Z","shell.execute_reply":"2023-08-14T07:45:07.566211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dfx = pd.read_csv('/kaggle/input/rsna-breast-cancer-detection/test.csv')\n#device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n\n#model = BreastCancerModel(Config=Config)\nmodel = Efficientnetv2_s() # from RSNA_my_version_with_train_test_split\n#model = Models() # from Fork of work of 7th place_try some parts of code\n\nmodel.to(device)\n\n# Load the checkpoint\nPATH = '/kaggle/input/tf-efficientnetv2-s/model.pt'\n#PATH = '/kaggle/input/efficient-model/models/efficientv5_seed_10.pth'\n\ncheckpoint = torch.load(PATH)\nmodel.load_state_dict(checkpoint['model_state_dict'])\n#model.load_state_dict(checkpoint['model'])\n\n#threshold = checkpoint['threshold']\nthreshold = 0.5\n\n#model.load_state_dict(torch.load(Config.MODEL_PATH))\n\nmodel.eval()\n\ntransform= transforms.Compose([\n    # input for augmentator is always PIL image\n    # transforms.ToPILImage(),\n    #transforms.RandomHorizontalFlip(0.5),\n    #transforms.RandomVerticalFlip(0.5),\n    #transforms.RandomPerspective(),\n    #transforms.RandomRotation((0, 90)),\n    #transforms.RandomAutocontrast(),\n    #transforms.RandomAffine(degrees=(0, 180), scale=(0.8, 1.2)),\n    #transforms.ElasticTransform(),\n    transforms.ToTensor(), # return it as a tensor and transforms it to [0, 1]\n    transforms.Normalize(mean = [0.1338, 0.1338, 0.1338],\n                         std = [0.2068, 0.2068, 0.2068])    \n])\n\ndataset = Dataset(dfx, transform=transform)\ndata_loader = torch.utils.data.DataLoader(dataset, batch_size= Config.BATCH_SIZE,\n                                             num_workers=0)\n\nwith torch.no_grad():\n    predictions = []\n    \n    \n    for batch_idx, (images, prediction_id) in enumerate(data_loader):\n        images = images.to(device, dtype=torch.float) \n        logits = model(images).squeeze()\n        prob_preds = logits.sigmoid() \n        predictions.append(prob_preds.cpu())\n        \n        #print('predictions before stack =', predictions)\n        \n    predictions = torch.stack(predictions, dim=0).numpy()   \n    #print('predictions after stack =', predictions)\n\npredictions = predictions.reshape(-1) # convert nd array to 1d array\n#print('prediction type = ', type(predictions))\n#print('predictions shape = ', predictions.shape)\n#print('length of predictions = ', len(predictions))\n\n\n\ndfx['cancer'] = predictions\n\nsample = dfx.groupby('prediction_id')[['cancer']].max()#.reset_index()\n\n#sample['cancer'] = (sample.cancer > threshold.detach().numpy()).astype(int)\nsample['cancer'] = (sample.cancer > 0.5).astype(int)\n\n# Save sample DataFrame as csv\nsample.to_csv('submission.csv', index=True)\n!head submission.csv\n#sample.head()","metadata":{"execution":{"iopub.status.busy":"2023-08-14T07:47:50.522783Z","iopub.execute_input":"2023-08-14T07:47:50.523181Z","iopub.status.idle":"2023-08-14T07:47:52.958079Z","shell.execute_reply.started":"2023-08-14T07:47:50.52315Z","shell.execute_reply":"2023-08-14T07:47:52.95685Z"},"trusted":true},"execution_count":null,"outputs":[]}]}