{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":29653,"databundleVersionId":2420395,"sourceType":"competition"},{"sourceId":7897133,"sourceType":"datasetVersion","datasetId":4637413}],"dockerImageVersionId":30664,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# TFM: Clasificación de imágenes tumorales usando deep learning\n## Análisis exploratorio de datos (EDA)\nEn esta primera libreta realizaremos un análisis exploratorio de datos correspondiente a la primera fase de la metodología CRISP-DM, comprensión del negocio. En nuestro caso, el objetivo fundamental de este análisis es comprender cuál es el problema que se pretende abordar.\n\nPor lo tanto, es importante comenzar organizando las partes principales de este apartado con el objetivo de comprender plenamente el problema.\n\n#### Índice\n* [1. Archivos disponibles y su significado](#1)\n* [2. Inicialización de la libreta](#2)\n* [3. Visualización del conjunto de entrenamiento](#3)\n* [4. Planteamiento de preprocesamiento](#4)","metadata":{}},{"cell_type":"markdown","source":"# 1. Archivos disponibles y su significado <a id=\"1\"></a>\nEn primer lugar, echaremos un vistazo a los archivos disponibles con los que podremos trabajar, el objetivo es comprender qué datos tenemos y qué datos podemos utilizar para la predicción de tumores cerebrales.\n\nLa composición de los datos propuestos por la competición son los siguientes:\n* Una carpeta **train** que contiene los archivos de entrenamiento. Cada carpeta de nivel superior representa un sujeto distinto. Esto significa que dentro de la carpeta **train**, encontrarás múltiples carpetas, y cada una de ellas corresponde a un sujeto o caso específico que será utilizado para el entrenamiento del modelo.\n* Una carpeta **test** con la misma organización que la carpeta **train**.\n* Un archivo CSV llamado **train_labels.csv** que contiene el valor objetivo **MGMT_value** para cada sujeto en los datos de entrenamiento. Por ejemplo, la presencia de metilación del promotor MGMT. Este archivo es esencialmente una lista que asocia a cada sujeto (generalmente identificado por un código o ID) con un valor objetivo, que en este contexto, indica si hay o no metilación del promotor MGMT en el sujeto.\n* Un archivo CSV llamado **sample_submission.csv** que hace referencia a un ejemplo de cómo se tendrían que subir las predicciones a la competición.\n\nUna vez conocemos la organización de los diferentes archivos es importante destacar que dado que la competición está cerrada solo haremos uso de los archivos referentes al entrenamiento, con dicho conjunto prepararemos nuestro propio conjunto de validación y prueba.","metadata":{}},{"cell_type":"markdown","source":"# 2. Inicialización de la libreta <a id=\"2\"></a>\nEn segundo lugar, es importante garantizar la integridad de los datos a lo largo de todo el proyecto, por lo tanto, es clave empezar estableciendo una semilla que será utilizada a lo largo de todo el trabajo. El motivo de empezar estableciendo la semilla es con el objetivo de garantizar la reproducibilidad en todo momento, así cómo garantizar que la división en subconjuntos de entrenamiento, validación y prueba se realicen de la misma forma en todo momento.\n\nPor ende, empezaremos estableciendo como semilla para todo el proyecto la semilla 42.","metadata":{}},{"cell_type":"code","source":"seed = 42","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:12:53.155194Z","iopub.execute_input":"2024-03-20T15:12:53.155589Z","iopub.status.idle":"2024-03-20T15:12:53.191698Z","shell.execute_reply.started":"2024-03-20T15:12:53.155542Z","shell.execute_reply":"2024-03-20T15:12:53.190747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Una vez establecida la semilla pasaremos a realizar una carga del archivo csv que contiene las etiquetas para todos los pacientes y antes de visualizar dicho archivo realizaremos la división en los diferentes subconjuntos. Esto debe realizarse de la mencionada forma para garantizar la integridad de los datos y que no ocurra ninguna fuga de datos desde el conjunto de entrenamiento hacia los subconjuntos de validación y prueba.","metadata":{}},{"cell_type":"code","source":"import os\nimport pandas as pd\n\npath = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n\ndf = pd.read_csv(os.path.join(path, 'train_labels.csv'))","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:13:16.115801Z","iopub.execute_input":"2024-03-20T15:13:16.116753Z","iopub.status.idle":"2024-03-20T15:13:16.124811Z","shell.execute_reply.started":"2024-03-20T15:13:16.116703Z","shell.execute_reply":"2024-03-20T15:13:16.123709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Puesto que contamos con 585 pacientes a la hora de dividir el conjunto de datos entre entrenamiento, validación y prueba realizaremos una partición de 80%, 10% y 10% respectivamente.","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ndf_train, df_aux = train_test_split(df, test_size=0.3, stratify=df['MGMT_value'], random_state=seed)\n\ndf_val, df_test = train_test_split(df_aux, test_size=0.5, stratify=df_aux['MGMT_value'], random_state=seed)","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:13:16.494985Z","iopub.execute_input":"2024-03-20T15:13:16.496281Z","iopub.status.idle":"2024-03-20T15:13:16.507602Z","shell.execute_reply.started":"2024-03-20T15:13:16.496221Z","shell.execute_reply":"2024-03-20T15:13:16.506316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:13:16.672854Z","iopub.execute_input":"2024-03-20T15:13:16.673559Z","iopub.status.idle":"2024-03-20T15:13:16.686690Z","shell.execute_reply.started":"2024-03-20T15:13:16.673506Z","shell.execute_reply":"2024-03-20T15:13:16.685832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. Visualización del conjunto de entrenamiento <a id=\"3\"></a>\nDespués de haber realizado la división entre los distintos conjuntos pasaremos a realizar un análisis exploratorio de datos sobre el conjunto de entrenamiento. Empezaremos evaluando el número de casos por clase que hay en el conjunto de **train**.","metadata":{}},{"cell_type":"code","source":"import seaborn as sns\nimport matplotlib.pyplot as plt\n\ntotal_cases = df_train['MGMT_value'].count()\n\nplt.figure(figsize=(6, 6))\nax = sns.countplot(data=df_train, x='MGMT_value')\nplt.title('Número de casos por clase MGMT_value')\nplt.xlabel('Clase MGMT_value')\nplt.ylabel('Número de casos')\n\n# Agregar el número de casos y el porcentaje del total encima de cada barra\nfor p in ax.patches:\n    percentage = f'{100 * p.get_height() / total_cases:.1f}%'\n    ax.annotate(f\"{p.get_height()} ({percentage})\", (p.get_x() + p.get_width() / 2., p.get_height()),\n                ha='center', va='center', fontsize=10, color='black', xytext=(0, 5),\n                textcoords='offset points')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:13:16.995721Z","iopub.execute_input":"2024-03-20T15:13:16.996612Z","iopub.status.idle":"2024-03-20T15:13:17.515695Z","shell.execute_reply.started":"2024-03-20T15:13:16.996566Z","shell.execute_reply":"2024-03-20T15:13:17.514822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"En este caso, nos encontramos ante un conjunto de datos prácticamente balanceado con un 47,4% de casos negativos y un 52,6% de casos positivos.","metadata":{}},{"cell_type":"code","source":"df_train['BraTS21ID'] = df_train['BraTS21ID'].apply(lambda x: str(x).zfill(5))\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:13:17.519674Z","iopub.execute_input":"2024-03-20T15:13:17.520067Z","iopub.status.idle":"2024-03-20T15:13:17.534856Z","shell.execute_reply.started":"2024-03-20T15:13:17.520035Z","shell.execute_reply":"2024-03-20T15:13:17.533477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = os.path.join(path, 'train')\n\ndf_train['path_dir'] = df_train['BraTS21ID'].apply(lambda x: os.path.join(train_path, x))\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:13:17.537319Z","iopub.execute_input":"2024-03-20T15:13:17.538300Z","iopub.status.idle":"2024-03-20T15:13:17.560857Z","shell.execute_reply.started":"2024-03-20T15:13:17.538256Z","shell.execute_reply":"2024-03-20T15:13:17.559531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3.1. Número de imágenes por paciente","metadata":{}},{"cell_type":"code","source":"import glob\n\nimages = []\n\nfor index, row in df_train.iterrows():\n    images.append(len(glob.glob(row['path_dir'] + \"/*/*.dcm\")))\n    \ndf_train['Total'] = images\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:13:18.324186Z","iopub.execute_input":"2024-03-20T15:13:18.324580Z","iopub.status.idle":"2024-03-20T15:14:49.786987Z","shell.execute_reply.started":"2024-03-20T15:13:18.324550Z","shell.execute_reply":"2024-03-20T15:14:49.786159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_histogram(df_plot, x_name, hue_name=None):\n    if hue_name is None:\n        sns.histplot(data=df_plot, x=x_name)\n        plt.ylabel('Número de pacientes')\n        plt.xlabel(f'Número de archivos DICOM - {x_name}')\n        plt.title(f'Histograma con el número de archivos DICOM por paciente - {x_name}')\n    else:\n        sns.histplot(data=df_plot, x=x_name, hue=hue_name)\n        plt.ylabel('Número de pacientes')\n        plt.xlabel(f'Número de archivos DICOM - {x_name}')\n        plt.title(f'Histograma con el número de archivos DICOM por paciente - {x_name}')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:22.345215Z","iopub.execute_input":"2024-03-20T14:54:22.345580Z","iopub.status.idle":"2024-03-20T14:54:22.352875Z","shell.execute_reply.started":"2024-03-20T14:54:22.345550Z","shell.execute_reply":"2024-03-20T14:54:22.351947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import warnings\n\nwarnings.filterwarnings(\"ignore\", category=FutureWarning, module=\"seaborn\")","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:22.354408Z","iopub.execute_input":"2024-03-20T14:54:22.355061Z","iopub.status.idle":"2024-03-20T14:54:22.371701Z","shell.execute_reply.started":"2024-03-20T14:54:22.355028Z","shell.execute_reply":"2024-03-20T14:54:22.370738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_train, 'Total')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:22.374199Z","iopub.execute_input":"2024-03-20T14:54:22.374595Z","iopub.status.idle":"2024-03-20T14:54:22.745228Z","shell.execute_reply.started":"2024-03-20T14:54:22.374563Z","shell.execute_reply":"2024-03-20T14:54:22.743967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_train, 'Total', 'MGMT_value')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:22.746872Z","iopub.execute_input":"2024-03-20T14:54:22.747295Z","iopub.status.idle":"2024-03-20T14:54:23.181440Z","shell.execute_reply.started":"2024-03-20T14:54:22.747263Z","shell.execute_reply":"2024-03-20T14:54:23.180315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"patient_id = []\nmgmt_value = []\nflair = []\nt1w = []\nt1wce = []\nt2w = []\n\nfor index, row in df_train.iterrows():\n    patient_id.append(row['BraTS21ID'])\n    mgmt_value.append(row['MGMT_value'])\n    flair.append(len(glob.glob(row['path_dir'] + \"/FLAIR/*.dcm\")))\n    t1w.append(len(glob.glob(row['path_dir'] + \"/T1w/*.dcm\")))\n    t1wce.append(len(glob.glob(row['path_dir'] + \"/T1wCE/*.dcm\")))\n    t2w.append(len(glob.glob(row['path_dir'] + \"/T2w/*.dcm\")))\n    \ndf_imgs_count = pd.DataFrame(\n    {'BraTS21ID': patient_id,\n     'MGMT_value': mgmt_value,\n     'FLAIR': flair,\n     'T1w': t1w,\n     'T1wCE': t1wce,\n     'T2w': t2w\n    })\ndf_imgs_count.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:23.182568Z","iopub.execute_input":"2024-03-20T14:54:23.182893Z","iopub.status.idle":"2024-03-20T14:54:25.261001Z","shell.execute_reply.started":"2024-03-20T14:54:23.182869Z","shell.execute_reply":"2024-03-20T14:54:25.260138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_imgs_count, 'FLAIR')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:25.262477Z","iopub.execute_input":"2024-03-20T14:54:25.263112Z","iopub.status.idle":"2024-03-20T14:54:25.606331Z","shell.execute_reply.started":"2024-03-20T14:54:25.263075Z","shell.execute_reply":"2024-03-20T14:54:25.605202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_imgs_count, 'FLAIR', 'MGMT_value')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:25.607666Z","iopub.execute_input":"2024-03-20T14:54:25.608107Z","iopub.status.idle":"2024-03-20T14:54:26.024070Z","shell.execute_reply.started":"2024-03-20T14:54:25.608067Z","shell.execute_reply":"2024-03-20T14:54:26.022894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_imgs_count, 'T1w')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:26.025240Z","iopub.execute_input":"2024-03-20T14:54:26.025617Z","iopub.status.idle":"2024-03-20T14:54:26.379970Z","shell.execute_reply.started":"2024-03-20T14:54:26.025589Z","shell.execute_reply":"2024-03-20T14:54:26.378929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_imgs_count, 'T1w', 'MGMT_value')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:26.383536Z","iopub.execute_input":"2024-03-20T14:54:26.384180Z","iopub.status.idle":"2024-03-20T14:54:26.783948Z","shell.execute_reply.started":"2024-03-20T14:54:26.384144Z","shell.execute_reply":"2024-03-20T14:54:26.782974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_imgs_count, 'T1wCE')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:26.785342Z","iopub.execute_input":"2024-03-20T14:54:26.785757Z","iopub.status.idle":"2024-03-20T14:54:27.150376Z","shell.execute_reply.started":"2024-03-20T14:54:26.785724Z","shell.execute_reply":"2024-03-20T14:54:27.149173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_imgs_count, 'T1wCE', 'MGMT_value')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:27.151576Z","iopub.execute_input":"2024-03-20T14:54:27.151883Z","iopub.status.idle":"2024-03-20T14:54:27.612168Z","shell.execute_reply.started":"2024-03-20T14:54:27.151858Z","shell.execute_reply":"2024-03-20T14:54:27.610846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_imgs_count, 'T2w')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:27.613517Z","iopub.execute_input":"2024-03-20T14:54:27.613942Z","iopub.status.idle":"2024-03-20T14:54:27.925425Z","shell.execute_reply.started":"2024-03-20T14:54:27.613913Z","shell.execute_reply":"2024-03-20T14:54:27.924626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_histogram(df_imgs_count, 'T2w', 'MGMT_value')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:27.926726Z","iopub.execute_input":"2024-03-20T14:54:27.927713Z","iopub.status.idle":"2024-03-20T14:54:28.320349Z","shell.execute_reply.started":"2024-03-20T14:54:27.927680Z","shell.execute_reply":"2024-03-20T14:54:28.319171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3.2. Análisis de imágenes\nMostrar imágenes por ensayo, cuándo hay MGMT o no, y dependiendo de la vista, si es axial, sagital o la otra.","metadata":{}},{"cell_type":"code","source":"import pydicom","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:14:49.788496Z","iopub.execute_input":"2024-03-20T15:14:49.789427Z","iopub.status.idle":"2024-03-20T15:14:50.114191Z","shell.execute_reply.started":"2024-03-20T15:14:49.789395Z","shell.execute_reply":"2024-03-20T15:14:50.112965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom(path):\n    dicom = pydicom.read_file(path) \n    data = dicom.pixel_array\n    data = data - np.min(data)\n    if np.max(data) != 0:\n        data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    return data\n\ndef visualize_patient(patient_path, mgmt_value):\n    plt.figure(figsize=(16, 5))\n    for i, scan_type in enumerate(['FLAIR', 'T1w', 'T1wCE', 'T2w'],1):\n        n_slice = len(os.listdir(os.path.join(patient_path,scan_type)))\n        data = load_dicom(os.path.join(patient_path,scan_type,f'Image-{int(n_slice/2)}.dcm'))\n        plt.subplot(1, 4, i)\n        plt.imshow(data, cmap=\"gray\")\n        plt.title(f\"{scan_type}\", fontsize=16)\n        plt.axis(\"off\")\n\n    plt.suptitle(f\"MGMT_value: {mgmt_value}\", fontsize=16)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:28.636680Z","iopub.execute_input":"2024-03-20T14:54:28.637010Z","iopub.status.idle":"2024-03-20T14:54:28.646100Z","shell.execute_reply.started":"2024-03-20T14:54:28.636984Z","shell.execute_reply":"2024-03-20T14:54:28.644778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\nimport numpy as np\n\ntry:\n    for i in random.sample(range(df_train.shape[0]), 6):\n        patient_path = df_train.iloc[i][\"path_dir\"] \n        mgmt_value = df_train.iloc[i][\"MGMT_value\"]\n        visualize_patient(patient_path, mgmt_value)\nexcept Exception as e:\n    print(\"Exception:\", e)","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:54:28.647643Z","iopub.execute_input":"2024-03-20T14:54:28.648169Z","iopub.status.idle":"2024-03-20T14:54:31.634590Z","shell.execute_reply.started":"2024-03-20T14:54:28.648106Z","shell.execute_reply":"2024-03-20T14:54:31.633396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3.3. Análisis de los metadatos de DICOM","metadata":{}},{"cell_type":"code","source":"example_dicom = pydicom.dcmread(os.path.join(df_train['path_dir'][100], 'T1w', 'Image-10.dcm'))\nprint(example_dicom)","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:21:11.318450Z","iopub.execute_input":"2024-03-20T15:21:11.318855Z","iopub.status.idle":"2024-03-20T15:21:11.350434Z","shell.execute_reply.started":"2024-03-20T15:21:11.318824Z","shell.execute_reply":"2024-03-20T15:21:11.349385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metadata_names = [\n    'AccessionNumber',\n    'AcquisitionMatrix',\n    'BitsAllocated',\n    'BitsStored',\n    'Columns',\n    'ConversionType',\n    'DiffusionBValue',\n    'DiffusionGradientOrientation',\n    'EchoNumbers',\n    'EchoTime',\n    'EchoTrainLength',\n    'FlipAngle',\n    'HighBit',\n    'HighRRValue',\n    'ImageDimensions',\n    'ImageFormat',\n    'ImageGeometryType',\n    'ImageLocation',\n    'ImageOrientation',\n    'ImageOrientationPatient',\n    'ImagePosition',\n    'ImagePositionPatient',\n    'ImageType',\n    'ImagedNucleus',\n    'ImagingFrequency',\n    'InPlanePhaseEncodingDirection',\n    'InStackPositionNumber',\n    'InstanceNumber',\n    'MRAcquisitionType',\n    'MagneticFieldStrength',\n    'Modality',\n    'NumberOfAverages',\n    'NumberOfPhaseEncodingSteps',\n    'PatientID',\n    'PatientName',\n    'PatientPosition',\n    'PercentPhaseFieldOfView',\n    'PercentSampling',\n    'PhotometricInterpretation',\n    'PixelBandwidth',\n    'PixelPaddingValue',\n    'PixelRepresentation',\n    'PixelSpacing',\n    'PlanarConfiguration',\n    'PositionReferenceIndicator',\n    'PresentationLUTShape',\n    'ReconstructionDiameter',\n    'RescaleIntercept',\n    'RescaleSlope',\n    'RescaleType',\n    'Rows',\n    'SAR',\n    'SOPClassUID',\n    'SOPInstanceUID',\n    'SamplesPerPixel',\n    'SeriesDescription',\n    'SeriesInstanceUID',\n    'SeriesNumber',\n    'SliceLocation',\n    'SliceThickness',\n    'SpacingBetweenSlices',\n    'SpatialResolution',\n    'SpecificCharacterSet',\n    'StudyInstanceUID',\n    'TemporalResolution',\n    'TransferSyntaxUID',\n    'TriggerWindow',\n    'WindowCenter',\n    'WindowWidth']","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:24:06.732702Z","iopub.execute_input":"2024-03-20T15:24:06.733112Z","iopub.status.idle":"2024-03-20T15:24:06.740765Z","shell.execute_reply.started":"2024-03-20T15:24:06.733081Z","shell.execute_reply":"2024-03-20T15:24:06.739879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://www.kaggle.com/code/rickandjoe/extract-metadata-from-dicom","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import os\n# import pydicom\n# import pandas as pd\n\n# from tqdm import tqdm\n# from multiprocessing import Pool\n# args={}\n# args['input'] = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n# args['output'] = './'\n# args['dataset'] = 'train'\n# args['n_jobs'] = 20\n# args['debug'] = 0\n\n\n# final = []\n\n\n# def get_meta_info(dicom):\n#     row = {f: dicom.get(f) for f in metadata_names}\n#     return {**row}\n\n\n# def get_dicom_files(input_dir, ds='train'):\n#     dicoms = []\n\n#     for subdir, dirs, files in os.walk(f\"{input_dir}/{ds}\"):\n#         for filename in files:\n#             filepath = subdir + os.sep + filename\n\n#             if filepath.endswith(\".dcm\"):\n#                 dicoms.append(filepath)\n\n#     return dicoms\n\n\n# def process_dicom(dicom_src, _x):\n#     dicom = pydicom.dcmread(dicom_src)\n#     file_data = dicom_src.split(\"/\")\n#     file_src = \"/\".join(file_data[-4:])\n\n#     tmp = {\"BraTS21ID\": file_data[-3], \"dataset\": file_data[-4], \"type\": file_data[-2], \"dicom_src\": f\"./{file_src}\"}\n#     tmp.update(get_meta_info(dicom))\n\n#     return tmp\n\n\n# def update(res):\n#     if res is not None:\n#         final.append(res)\n\n#     pbar.update()\n\n\n# def error(e):\n#     print(e)\n\n\n# if __name__ == \"__main__\":\n#     dicom_files = get_dicom_files(args[\"input\"], args[\"dataset\"])\n\n#     if args[\"debug\"]:\n#         dicom_files = dicom_files[:1000]\n\n#     pool = Pool(processes=args[\"n_jobs\"])\n#     pbar = tqdm(total=len(dicom_files))\n\n#     for dicom_file in dicom_files:\n#         pool.apply_async(\n#             process_dicom,\n#             args=(dicom_file, ''),\n#             callback=update,\n#             error_callback=error,\n#         )\n\n#     pool.close()\n#     pool.join()\n#     pbar.close()\n\n#     final = pd.DataFrame(final)\n#     final.to_csv(f\"{args['output']}/dicom_meta_{args['dataset']}.csv\", index=False)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:24:49.885218Z","iopub.execute_input":"2024-03-20T15:24:49.885562Z","iopub.status.idle":"2024-03-20T15:37:03.497330Z","shell.execute_reply.started":"2024-03-20T15:24:49.885537Z","shell.execute_reply":"2024-03-20T15:37:03.495297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metadata_df = pd.read_csv('/kaggle/input/metadata-extracted/dicom_meta_train.csv')\nmetadata_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:24:05.709541Z","iopub.execute_input":"2024-03-20T16:24:05.710000Z","iopub.status.idle":"2024-03-20T16:24:12.263077Z","shell.execute_reply.started":"2024-03-20T16:24:05.709970Z","shell.execute_reply":"2024-03-20T16:24:12.262108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metadata_df.info()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:24:12.265419Z","iopub.execute_input":"2024-03-20T16:24:12.266174Z","iopub.status.idle":"2024-03-20T16:24:12.756698Z","shell.execute_reply.started":"2024-03-20T16:24:12.266131Z","shell.execute_reply":"2024-03-20T16:24:12.755375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"umbral_faltantes = 85\nporcentaje_faltantes = metadata_df.isnull().mean() * 100\ncolumnas_incompletas = porcentaje_faltantes[porcentaje_faltantes > umbral_faltantes].index.tolist()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:24:12.758323Z","iopub.execute_input":"2024-03-20T16:24:12.758760Z","iopub.status.idle":"2024-03-20T16:24:13.350584Z","shell.execute_reply.started":"2024-03-20T16:24:12.758727Z","shell.execute_reply":"2024-03-20T16:24:13.346787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metadata_df.drop(columnas_incompletas,\n                    axis=1, \n                    inplace=True\n                )","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:24:13.357554Z","iopub.execute_input":"2024-03-20T16:24:13.358508Z","iopub.status.idle":"2024-03-20T16:24:13.675606Z","shell.execute_reply.started":"2024-03-20T16:24:13.358352Z","shell.execute_reply":"2024-03-20T16:24:13.671470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metadata_df.info()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:24:13.681132Z","iopub.execute_input":"2024-03-20T16:24:13.683977Z","iopub.status.idle":"2024-03-20T16:24:14.387944Z","shell.execute_reply.started":"2024-03-20T16:24:13.683805Z","shell.execute_reply":"2024-03-20T16:24:14.385239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def graficar_frecuencia_valores_unicos(df, columna):\n    plt.figure(figsize=(10, 6))\n    \n    sns.countplot(x=columna, data=df, order = df[columna].value_counts().index)\n    \n    plt.xticks(rotation=45, ha=\"right\")\n    plt.title(f'Frecuencia de valores únicos en la columna \"{columna}\"')\n    plt.ylabel('Frecuencia')\n    plt.xlabel(f'Valores únicos de {columna}')\n\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:13:17.337297Z","iopub.execute_input":"2024-03-20T16:13:17.337791Z","iopub.status.idle":"2024-03-20T16:13:17.346356Z","shell.execute_reply.started":"2024-03-20T16:13:17.337735Z","shell.execute_reply":"2024-03-20T16:13:17.344668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'type')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:14:39.453300Z","iopub.execute_input":"2024-03-20T16:14:39.453686Z","iopub.status.idle":"2024-03-20T16:14:39.930435Z","shell.execute_reply.started":"2024-03-20T16:14:39.453660Z","shell.execute_reply":"2024-03-20T16:14:39.929215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'Modality')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:15:59.090130Z","iopub.execute_input":"2024-03-20T16:15:59.090546Z","iopub.status.idle":"2024-03-20T16:15:59.548820Z","shell.execute_reply.started":"2024-03-20T16:15:59.090517Z","shell.execute_reply":"2024-03-20T16:15:59.547641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'PhotometricInterpretation')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:16:41.340363Z","iopub.execute_input":"2024-03-20T16:16:41.340786Z","iopub.status.idle":"2024-03-20T16:16:41.817043Z","shell.execute_reply.started":"2024-03-20T16:16:41.340757Z","shell.execute_reply":"2024-03-20T16:16:41.815754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'PixelSpacing')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:17:56.575951Z","iopub.execute_input":"2024-03-20T16:17:56.577364Z","iopub.status.idle":"2024-03-20T16:17:57.786560Z","shell.execute_reply.started":"2024-03-20T16:17:56.577317Z","shell.execute_reply":"2024-03-20T16:17:57.785210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'RescaleIntercept')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:20:19.912947Z","iopub.execute_input":"2024-03-20T16:20:19.913394Z","iopub.status.idle":"2024-03-20T16:20:20.177709Z","shell.execute_reply.started":"2024-03-20T16:20:19.913362Z","shell.execute_reply":"2024-03-20T16:20:20.176403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'RescaleSlope')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:20:20.945300Z","iopub.execute_input":"2024-03-20T16:20:20.945693Z","iopub.status.idle":"2024-03-20T16:20:21.210248Z","shell.execute_reply.started":"2024-03-20T16:20:20.945663Z","shell.execute_reply":"2024-03-20T16:20:21.209045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'RescaleType')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:18:03.641464Z","iopub.execute_input":"2024-03-20T16:18:03.641886Z","iopub.status.idle":"2024-03-20T16:18:04.114076Z","shell.execute_reply.started":"2024-03-20T16:18:03.641854Z","shell.execute_reply":"2024-03-20T16:18:04.112720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'Columns')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:18:06.925124Z","iopub.execute_input":"2024-03-20T16:18:06.926383Z","iopub.status.idle":"2024-03-20T16:18:07.517734Z","shell.execute_reply.started":"2024-03-20T16:18:06.926327Z","shell.execute_reply":"2024-03-20T16:18:07.516499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'Rows')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:18:10.668022Z","iopub.execute_input":"2024-03-20T16:18:10.668490Z","iopub.status.idle":"2024-03-20T16:18:11.093517Z","shell.execute_reply.started":"2024-03-20T16:18:10.668457Z","shell.execute_reply":"2024-03-20T16:18:11.092377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'SliceThickness')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:18:49.369109Z","iopub.execute_input":"2024-03-20T16:18:49.369520Z","iopub.status.idle":"2024-03-20T16:18:49.868649Z","shell.execute_reply.started":"2024-03-20T16:18:49.369491Z","shell.execute_reply":"2024-03-20T16:18:49.867301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'SamplesPerPixel')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:19:48.226372Z","iopub.execute_input":"2024-03-20T16:19:48.226880Z","iopub.status.idle":"2024-03-20T16:19:48.552749Z","shell.execute_reply.started":"2024-03-20T16:19:48.226845Z","shell.execute_reply":"2024-03-20T16:19:48.551516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'MagneticFieldStrength')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:24:43.476915Z","iopub.execute_input":"2024-03-20T16:24:43.477359Z","iopub.status.idle":"2024-03-20T16:24:43.778689Z","shell.execute_reply.started":"2024-03-20T16:24:43.477324Z","shell.execute_reply":"2024-03-20T16:24:43.777317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'MRAcquisitionType')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:25:58.830107Z","iopub.execute_input":"2024-03-20T16:25:58.830507Z","iopub.status.idle":"2024-03-20T16:25:59.296237Z","shell.execute_reply.started":"2024-03-20T16:25:58.830477Z","shell.execute_reply":"2024-03-20T16:25:59.295084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import ast\n\ndef get_image_plane(data):\n    \n    x1,y1,_,x2,y2,_ = [round(j) for j in ast.literal_eval(data.ImageOrientationPatient)]\n    cords = [x1,y1,x2,y2]\n\n    if cords == [1,0,0,0]:\n        return 'coronal'\n    if cords == [1,0,0,1]:\n        return 'axial'\n    if cords == [0,1,0,0]:\n        return 'sagittal'\n    \nmetadata_df['Orientation'] = metadata_df.apply(get_image_plane, axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:28:55.231134Z","iopub.execute_input":"2024-03-20T16:28:55.231548Z","iopub.status.idle":"2024-03-20T16:29:11.118943Z","shell.execute_reply.started":"2024-03-20T16:28:55.231513Z","shell.execute_reply":"2024-03-20T16:29:11.117702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graficar_frecuencia_valores_unicos(metadata_df, 'Orientation')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:29:11.584273Z","iopub.execute_input":"2024-03-20T16:29:11.584651Z","iopub.status.idle":"2024-03-20T16:29:12.061765Z","shell.execute_reply.started":"2024-03-20T16:29:11.584623Z","shell.execute_reply":"2024-03-20T16:29:12.060401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.histplot(data=metadata_df, x=\"SeriesDescription\", hue=\"Orientation\", \n             multiple=\"dodge\", shrink=.8)","metadata":{"execution":{"iopub.status.busy":"2024-03-20T16:29:54.409000Z","iopub.execute_input":"2024-03-20T16:29:54.409489Z","iopub.status.idle":"2024-03-20T16:29:55.519853Z","shell.execute_reply.started":"2024-03-20T16:29:54.409457Z","shell.execute_reply":"2024-03-20T16:29:55.518623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3.4. Análisis a nivel de píxel","metadata":{}},{"cell_type":"code","source":"# train_path += '/'\n# f = []\n# for (dirpath, dirnames, filenames) in os.walk(train_path):\n#     f.extend(os.path.join(dirpath, x) for x in filenames)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-19T18:29:25.647013Z","iopub.execute_input":"2024-03-19T18:29:25.648102Z","iopub.status.idle":"2024-03-19T18:29:29.152422Z","shell.execute_reply.started":"2024-03-19T18:29:25.648052Z","shell.execute_reply":"2024-03-19T18:29:29.151057Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_file_paths_df = pd.DataFrame({'file_paths': f})\n# train_file_paths_df['directory'] = train_path\n# train_file_paths_df['dataset'] = train_file_paths_df['file_paths'].str.split(\"/\", n = 7, expand = True)[3]\n# train_file_paths_df['patient_id'] = train_file_paths_df['file_paths'].str.split(\"/\", n = 7, expand = True)[4]\n# train_file_paths_df['scan_type'] = train_file_paths_df['file_paths'].str.split(\"/\", n = 7, expand = True)[5]\n# train_file_paths_df['file'] = train_file_paths_df['file_paths'].str.split(\"/\", n = 7, expand = True)[6]\n# display(train_file_paths_df.head(2))\n# train_file_paths_df.shape[0]","metadata":{"execution":{"iopub.status.busy":"2024-03-19T18:32:25.602576Z","iopub.execute_input":"2024-03-19T18:32:25.603096Z","iopub.status.idle":"2024-03-19T18:32:37.729056Z","shell.execute_reply.started":"2024-03-19T18:32:25.603060Z","shell.execute_reply":"2024-03-19T18:32:37.727454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"00109 (FLAIR images are blank) 00123 (T1w images are blank) 00709 (FLAIR images are blank)","metadata":{}},{"cell_type":"code","source":"# train_df = train_file_paths_df.copy()\n\n# train_df = train_df[(train_df.patient_id != \"00109\") & \n#                     (train_df.patient_id != \"00123\") &\n#                     (train_df.patient_id != \"00709\")]","metadata":{"execution":{"iopub.status.busy":"2024-03-19T18:33:03.149242Z","iopub.execute_input":"2024-03-19T18:33:03.149706Z","iopub.status.idle":"2024-03-19T18:33:03.830509Z","shell.execute_reply.started":"2024-03-19T18:33:03.149674Z","shell.execute_reply":"2024-03-19T18:33:03.829404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def image_stats(path):\n    dicom = pydicom.read_file(path)\n    data = apply_voi_lut(dicom.pixel_array, dicom)\n    \n    # Transform Data as Necessary     \n    if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    \n    data = data - np.min(data)\n    if np.max(data) != 0:\n        data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    \n    # Compute and Return Image Stats: min, max, mean, std, 25th-, 50th-, and 75th percentile\n    return np.min(data), \\\n            np.max(data), \\\n            np.mean(data), \\\n            np.std(data), \\\n            np.percentile(data, 25), \\\n            np.percentile(data, 50), \\\n            np.percentile(data, 75)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T18:32:37.731731Z","iopub.execute_input":"2024-03-19T18:32:37.732820Z","iopub.status.idle":"2024-03-19T18:32:37.743986Z","shell.execute_reply.started":"2024-03-19T18:32:37.732765Z","shell.execute_reply":"2024-03-19T18:32:37.742334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pydicom.pixel_data_handlers.util import apply_voi_lut","metadata":{"execution":{"iopub.status.busy":"2024-03-19T18:32:37.745823Z","iopub.execute_input":"2024-03-19T18:32:37.746383Z","iopub.status.idle":"2024-03-19T18:32:37.759695Z","shell.execute_reply.started":"2024-03-19T18:32:37.746335Z","shell.execute_reply":"2024-03-19T18:32:37.758141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pixel_data = train_df.copy()\n# pixel_data[\"stats\"] = pixel_data[\"file_paths\"].apply(lambda x: image_stats(x))\n# pixel_data[[\"min_px\", \"max_px\", \"mean_px\", \"std_px\", \"q1\", \"q2\", \"q3\"]] = pd.DataFrame(pixel_data[\"stats\"].tolist(), index=pixel_data.index)\n# pixel_data = pixel_data.drop(['stats'], axis=1)\n# pixel_data.to_csv('pixel_data_train.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T18:34:22.015410Z","iopub.execute_input":"2024-03-19T18:34:22.016562Z","iopub.status.idle":"2024-03-19T19:13:33.511342Z","shell.execute_reply.started":"2024-03-19T18:34:22.016476Z","shell.execute_reply":"2024-03-19T19:13:33.507167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pixel_data_df = pd.read_csv('/kaggle/input/metadata-extracted/pixel_data_train.csv')\npixel_data_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:43:34.500560Z","iopub.execute_input":"2024-03-20T15:43:34.500963Z","iopub.status.idle":"2024-03-20T15:43:36.371040Z","shell.execute_reply.started":"2024-03-20T15:43:34.500933Z","shell.execute_reply":"2024-03-20T15:43:36.368642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pixel_data_scan_type = sns.FacetGrid(pixel_data_df, col=\"scan_type\", col_wrap=2)\npixel_data_scan_type.map(sns.histplot, 'mean_px', bins=50)\npixel_data_scan_type.set(yscale=\"log\")","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:48:59.341481Z","iopub.execute_input":"2024-03-20T15:48:59.342521Z","iopub.status.idle":"2024-03-20T15:49:02.978682Z","shell.execute_reply.started":"2024-03-20T15:48:59.342470Z","shell.execute_reply":"2024-03-20T15:49:02.977774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.read_csv(os.path.join(path, 'train_labels.csv'))\npixel_data_df = pixel_data_df.merge(labels, left_on='patient_id', right_on='BraTS21ID')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:54:17.851681Z","iopub.execute_input":"2024-03-20T15:54:17.852121Z","iopub.status.idle":"2024-03-20T15:54:18.316895Z","shell.execute_reply.started":"2024-03-20T15:54:17.852086Z","shell.execute_reply":"2024-03-20T15:54:18.315122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pixel_data_scan_type = sns.FacetGrid(pixel_data_df, col=\"scan_type\", hue='MGMT_value', col_wrap=2)\npixel_data_scan_type.map(sns.histplot, 'mean_px', bins=50, alpha=0.5)\npixel_data_scan_type.set(yscale=\"log\")\npixel_data_scan_type.add_legend()","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:55:01.532513Z","iopub.execute_input":"2024-03-20T15:55:01.532984Z","iopub.status.idle":"2024-03-20T15:55:06.628464Z","shell.execute_reply.started":"2024-03-20T15:55:01.532947Z","shell.execute_reply":"2024-03-20T15:55:06.627193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Número de imágenes por paciente\nHistogramas, media, mediana, según el tipo de ensayos, número de imágenes vs MGMT_value, número de imágenes por ensayo vs MGMT_value...\n#### Análisis de las imágenes\nMostrar representación visual general de cuándo hay presencia de MGMT o no. Diferencias de los 4 ensayos, a qué hacen referencia cada uno y su visualización.\n#### Análisis de los metadatos de dicom\n¿Qué metadatos hay? ¿Qué podemos aprovechar de ahí?\n#### Análisis a nivel de pixel\nComparar píxeles.","metadata":{}},{"cell_type":"markdown","source":"# 4. Planteamiento de preprocesamiento <a id=\"4\"></a>","metadata":{}}]}