{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","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":71549,"databundleVersionId":8561470,"sourceType":"competition"}],"dockerImageVersionId":30715,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# train.csv\n## Description\n\nThe `train.csv` file contains labels for a dataset of MRI scans of the lumbar spine. Each row represents an individual study and includes diagnostic information for multiple spinal levels and conditions. The columns in the file are as follows:\n\n- **study_id**: A unique identifier for each study.\n- **spinal_canal_stenosis_l1_l2**: Diagnosis for spinal canal stenosis at the L1/L2 level, with possible values being 'Normal/Mild', 'Moderate', or 'Severe'.\n- **spinal_canal_stenosis_l2_l3**: Diagnosis for spinal canal stenosis at the L2/L3 level.\n- **spinal_canal_stenosis_l3_l4**: Diagnosis for spinal canal stenosis at the L3/L4 level.\n- **spinal_canal_stenosis_l4_l5**: Diagnosis for spinal canal stenosis at the L4/L5 level.\n- **spinal_canal_stenosis_l5_s1**: Diagnosis for spinal canal stenosis at the L5/S1 level.\n- **left_neural_foraminal_narrowing_l1_l2**: Diagnosis for left neural foraminal narrowing at the L1/L2 level.\n- **left_neural_foraminal_narrowing_l2_l3**: Diagnosis for left neural foraminal narrowing at the L2/L3 level.\n- **left_neural_foraminal_narrowing_l3_l4**: Diagnosis for left neural foraminal narrowing at the L3/L4 level.\n- **left_neural_foraminal_narrowing_l4_l5**: Diagnosis for left neural foraminal narrowing at the L4/L5 level.\n- **left_neural_foraminal_narrowing_l5_s1**: Diagnosis for left neural foraminal narrowing at the L5/S1 level.\n- **right_neural_foraminal_narrowing_l1_l2**: Diagnosis for right neural foraminal narrowing at the L1/L2 level.\n- **right_neural_foraminal_narrowing_l2_l3**: Diagnosis for right neural foraminal narrowing at the L2/L3 level.\n- **right_neural_foraminal_narrowing_l3_l4**: Diagnosis for right neural foraminal narrowing at the L3/L4 level.\n- **right_neural_foraminal_narrowing_l4_l5**: Diagnosis for right neural foraminal narrowing at the L4/L5 level.\n- **right_neural_foraminal_narrowing_l5_s1**: Diagnosis for right neural foraminal narrowing at the L5/S1 level.\n- **left_subarticular_stenosis_l1_l2**: Diagnosis for left subarticular stenosis at the L1/L2 level.\n- **left_subarticular_stenosis_l2_l3**: Diagnosis for left subarticular stenosis at the L2/L3 level.\n- **left_subarticular_stenosis_l3_l4**: Diagnosis for left subarticular stenosis at the L3/L4 level.\n- **left_subarticular_stenosis_l4_l5**: Diagnosis for left subarticular stenosis at the L4/L5 level.\n- **left_subarticular_stenosis_l5_s1**: Diagnosis for left subarticular stenosis at the L5/S1 level.\n- **right_subarticular_stenosis_l1_l2**: Diagnosis for right subarticular stenosis at the L1/L2 level.\n- **right_subarticular_stenosis_l2_l3**: Diagnosis for right subarticular stenosis at the L2/L3 level.\n- **right_subarticular_stenosis_l3_l4**: Diagnosis for right subarticular stenosis at the L3/L4 level.\n- **right_subarticular_stenosis_l4_l5**: Diagnosis for right subarticular stenosis at the L4/L5 level.\n- **right_subarticular_stenosis_l5_s1**: Diagnosis for right subarticular stenosis at the L5/S1 level.\n\nEach diagnostic column contains one of three possible values:\n\n- **Normal/Mild**: Normal or mild condition.\n- **Moderate**: Moderate condition.\n- **Severe**: Severe condition.\n","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nfrom matplotlib import pyplot as plt\nimport seaborn as sns\nimport os\nimport imageio\nfrom IPython import display \nfrom math import ceil\nimport os\nimport imageio\nimport pydicom\n","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:53.750618Z","start_time":"2024-05-31T06:27:53.641639Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:11.806271Z","iopub.execute_input":"2024-05-31T07:48:11.807359Z","iopub.status.idle":"2024-05-31T07:48:11.815493Z","shell.execute_reply.started":"2024-05-31T07:48:11.807292Z","shell.execute_reply":"2024-05-31T07:48:11.813941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_path = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_images'\n\nstudy_id = 4003253\nseries_ids = [\n    {\"series_id\": 2448190387, \"description\": \"Axial T2\"},\n    {\"series_id\": 1054713880, \"description\": \"Sagittal T1\"},\n    {\"series_id\": 702807833, \"description\": \"Sagittal T2\"}\n]\ndicom_file_paths = [\n    base_path+\"/4003253/702807833/8.dcm\",\n    base_path+\"/4003253/1054713880/8.dcm\",\n    base_path+\"/4003253/2448190387/20.dcm\"\n]\n\ntrain = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train.csv')\nlabels = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_label_coordinates.csv')\nseries = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv')\ntrain.head()","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:53.794457Z","start_time":"2024-05-31T06:27:53.751556Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:11.817964Z","iopub.execute_input":"2024-05-31T07:48:11.818960Z","iopub.status.idle":"2024-05-31T07:48:11.970013Z","shell.execute_reply.started":"2024-05-31T07:48:11.818920Z","shell.execute_reply":"2024-05-31T07:48:11.968802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.info()","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:53.801390Z","start_time":"2024-05-31T06:27:53.795389Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:11.971972Z","iopub.execute_input":"2024-05-31T07:48:11.972409Z","iopub.status.idle":"2024-05-31T07:48:11.995197Z","shell.execute_reply.started":"2024-05-31T07:48:11.972370Z","shell.execute_reply":"2024-05-31T07:48:11.993628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20, 10))\nsns.set(style=\"whitegrid\")\n\ngrouped_df = train.melt(var_name='Condition_Level', value_name='Category', id_vars=['study_id'])\ngrouped_df['Level'] = grouped_df['Condition_Level'].apply(lambda x: '_'.join(x.split('_')[-2:]))\ngrouped_df['Condition'] = grouped_df['Condition_Level'].apply(lambda x: '_'.join(x.split('_')[:-2]))\n\nsns.countplot(data=grouped_df, x='Level', hue='Category')\nplt.title('Comparing the frequency of all states for each level')\nplt.xlabel('Level')\nplt.ylabel('Count')\nplt.legend(title='Category')\nplt.xticks(rotation=45)\nplt.show()\n","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:54.003945Z","start_time":"2024-05-31T06:27:53.802025Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:11.999017Z","iopub.execute_input":"2024-05-31T07:48:11.999534Z","iopub.status.idle":"2024-05-31T07:48:12.723128Z","shell.execute_reply.started":"2024-05-31T07:48:11.999493Z","shell.execute_reply":"2024-05-31T07:48:12.721875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"conditions = set()\nlevels = set()\nresult = []\n\nfor column_name in train.columns[1:]:\n    counts = train[column_name].value_counts().reset_index()\n    counts.columns = ['Category', 'Count']\n    condition, level = '_'.join(column_name.split('_')[:-2]), '_'.join(column_name.split('_')[-2:])\n    counts['Condition'] = condition\n    counts['Level'] = level\n    conditions.add(condition)\n    levels.add(level)\n    result.append(counts)\n\nconditions = sorted(list(conditions))\nlevels = sorted(list(levels))\nfinal_result_df = pd.concat(result).reset_index(drop=True)\n\nplt.figure(figsize=(20, 15))\nsns.set(style=\"whitegrid\")\n\nfig, axes = plt.subplots(3, 2, figsize=(20, 20), constrained_layout=True)\naxes = axes.flatten()\n\nfor i, condition in enumerate(conditions):\n    condition_df = final_result_df[final_result_df['Condition'] == condition]\n    sns.barplot(x='Level', y='Count', hue='Category', data=condition_df, ax=axes[i])\n    axes[i].set_title(f'Count categories {condition.replace(\"_\", \" \").title()}')\n    axes[i].set_xlabel('Levels')\n    axes[i].set_ylabel('Count')\n    axes[i].legend(title='Category')\n    axes[i].tick_params(axis='x', rotation=45)\n    \nfor j in range(len(conditions), len(axes)):\n    fig.delaxes(axes[j])","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:55.152774Z","start_time":"2024-05-31T06:27:54.004638Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:12.724525Z","iopub.execute_input":"2024-05-31T07:48:12.724884Z","iopub.status.idle":"2024-05-31T07:48:16.435448Z","shell.execute_reply.started":"2024-05-31T07:48:12.724852Z","shell.execute_reply":"2024-05-31T07:48:16.434052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(15, 10))\nsns.set(style=\"whitegrid\")\n\npivot_table = final_result_df.pivot_table(values='Count', index='Condition', columns=['Level', 'Category'], aggfunc='sum', fill_value=0)\n\nplt.figure(figsize=(20, 10))\nsns.heatmap(pivot_table, annot=True, fmt='d', cmap='Blues')\nplt.title('Heatmap for comparing categories by levels and states')\nplt.xlabel('Levels and Categories')\nplt.ylabel('Conditions')\nplt.xticks(rotation=90)\nplt.show()\n","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:55.431983Z","start_time":"2024-05-31T06:27:55.155202Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:16.437115Z","iopub.execute_input":"2024-05-31T07:48:16.438034Z","iopub.status.idle":"2024-05-31T07:48:17.393816Z","shell.execute_reply.started":"2024-05-31T07:48:16.437994Z","shell.execute_reply":"2024-05-31T07:48:17.392842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Conclusion\n\n### Prevalence of Normal/Mild Conditions:\n\nNormal or mild conditions predominate at all levels of the spine, which may reflect a general trend towards less severe forms of degeneration in the overall patient population. This is especially observed at the L1/L2 and L2/L3 levels.\n\n### Severe Conditions:\n\nMore severe conditions (Moderate and Severe) are more frequently found at the L4/L5 and L5/S1 levels.\n\n### Types of Degeneration:\n\nAll types of degeneration show similar trends in the distribution of categories across the levels of the spine. Specifically, at the L4/L5 and L5/S1 levels, there are more cases in the Moderate and Severe categories.","metadata":{}},{"cell_type":"markdown","source":"# Point analyze\n","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10, 6))\n\nsns.scatterplot(x='x', y='y', hue='condition', data=labels, palette='viridis')\nplt.title('Scatter Plot of Points Colored by Condition')\nplt.xlabel('X Coordinate')\nplt.ylabel('Y Coordinate')\nplt.legend(title='Condition', bbox_to_anchor=(1.05, 1), loc='upper left')\nplt.grid(True)\nplt.show()","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:56.196487Z","start_time":"2024-05-31T06:27:55.432893Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:17.395061Z","iopub.execute_input":"2024-05-31T07:48:17.396080Z","iopub.status.idle":"2024-05-31T07:48:19.505689Z","shell.execute_reply.started":"2024-05-31T07:48:17.396043Z","shell.execute_reply":"2024-05-31T07:48:19.504669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10, 6))\n\nsns.scatterplot(x='x', y='y', hue='level', data=labels, palette='tab10')\nplt.title('Scatter Plot of Points Colored by Level')\nplt.xlabel('X Coordinate')\nplt.ylabel('Y Coordinate')\nplt.legend(title='Level', bbox_to_anchor=(1.05, 1), loc='upper left')\nplt.grid(True)\nplt.show()\n","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:56.852292Z","start_time":"2024-05-31T06:27:56.197149Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:19.507212Z","iopub.execute_input":"2024-05-31T07:48:19.508246Z","iopub.status.idle":"2024-05-31T07:48:21.452552Z","shell.execute_reply.started":"2024-05-31T07:48:19.508204Z","shell.execute_reply":"2024-05-31T07:48:21.451002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merged_data = pd.merge(labels, train, on='study_id', how='left')\nfinal_data = pd.merge(merged_data, series[['series_id', 'series_description']], on='series_id', how='left')\n#final_data.to_csv('final_merged_data.csv', index=False)","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:56.875194Z","start_time":"2024-05-31T06:27:56.853564Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:21.454247Z","iopub.execute_input":"2024-05-31T07:48:21.454611Z","iopub.status.idle":"2024-05-31T07:48:21.538409Z","shell.execute_reply.started":"2024-05-31T07:48:21.454580Z","shell.execute_reply":"2024-05-31T07:48:21.537197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Analysis of Point Plots by Spine Levels for Each Series","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15, 10))\n\nfor i, series in enumerate(final_data['series_description'].unique(), 1):\n    plt.subplot(2, 2, i)\n    subset = final_data[final_data['series_description'] == series]\n    sns.scatterplot(x='x', y='y', hue='level', data=subset, palette='tab10', s=10)\n    plt.title(f'Scatter Plot for {series} Colored by Spine Level')\n    plt.xlabel('X Coordinate')\n    plt.ylabel('Y Coordinate')\n    plt.legend(title='Spine Level', bbox_to_anchor=(1.05, 1), loc='upper left')\n    plt.grid(True)\n\nplt.tight_layout()\nplt.show()\n","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:27:57.804578Z","start_time":"2024-05-31T06:27:56.875892Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:21.542004Z","iopub.execute_input":"2024-05-31T07:48:21.542715Z","iopub.status.idle":"2024-05-31T07:48:24.396007Z","shell.execute_reply.started":"2024-05-31T07:48:21.542680Z","shell.execute_reply":"2024-05-31T07:48:24.395030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DCMs\n\n**Three types of MRI scans**:\n\n    - Sagittal T2/STIR\n    - Sagittal T1\n    - Axial T2","metadata":{}},{"cell_type":"code","source":"def visualize_series_images(base_path, study_id, series_id, title, num_cols=5):\n    series_path = os.path.join(base_path, str(study_id), str(series_id))\n    image_files = [os.path.join(series_path, f) for f in os.listdir(series_path) if f.endswith('.dcm')][:10]\n    num_images = len(image_files)\n    num_rows = ceil(num_images / num_cols)\n    \n    fig, axs = plt.subplots(num_rows, num_cols, figsize=(num_cols*3, num_rows*3))\n    axs = axs.flatten() if num_images > 1 else [axs]\n    \n    for ax, img_path in zip(axs, image_files):\n        dicom_content = pydicom.dcmread(img_path)\n        ax.imshow(dicom_content.pixel_array, cmap='gray')\n        ax.axis('off')\n    \n\n    for ax in axs[num_images:]:\n        ax.axis('off')\n    \n    plt.suptitle(title)\n    plt.tight_layout()\n    plt.subplots_adjust(top=0.95)\n    plt.show()\n\nfor series in series_ids:\n    visualize_series_images(base_path, study_id, series['series_id'], series['description'])","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:28:00.095908Z","start_time":"2024-05-31T06:27:58.077315Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:24.397773Z","iopub.execute_input":"2024-05-31T07:48:24.398126Z","iopub.status.idle":"2024-05-31T07:48:30.580971Z","shell.execute_reply.started":"2024-05-31T07:48:24.398092Z","shell.execute_reply":"2024-05-31T07:48:30.579676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize_multiple_dicoms_with_colormaps(dicom_file_paths):\n    cmaps = ['gray', 'bone', 'viridis', 'plasma', 'inferno', 'magma', 'cividis', 'hot', 'cool', 'twilight', 'twilight_shifted', 'jet']\n    n_rows = 3\n    n_cols = 5\n\n    for dicom_file_path in dicom_file_paths:\n        dicom_data = pydicom.dcmread(dicom_file_path)\n        pixel_array = dicom_data.pixel_array\n\n        fig, axes = plt.subplots(n_rows, n_cols, figsize=(20, 12))\n\n        for ax, cmap in zip(axes.flatten(), cmaps):\n            ax.imshow(pixel_array, cmap=cmap)\n            ax.set_title(cmap)\n            ax.axis('off')\n\n        for ax in axes.flatten()[len(cmaps):]:\n            fig.delaxes(ax)\n\n        plt.suptitle(f'DICOM Image with Different Colormaps\\n{dicom_file_path}')\n        plt.show()\n\n\nvisualize_multiple_dicoms_with_colormaps(dicom_file_paths)","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:28:02.770675Z","start_time":"2024-05-31T06:28:00.096563Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:30.582681Z","iopub.execute_input":"2024-05-31T07:48:30.583063Z","iopub.status.idle":"2024-05-31T07:48:39.066757Z","shell.execute_reply.started":"2024-05-31T07:48:30.583029Z","shell.execute_reply":"2024-05-31T07:48:39.064252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib.patches import Circle\n\n\ndef display_image_with_annotations(base_path, data):\n    for index, row in data[:10].iterrows():  #10 first images from dataset\n        study_id = row['study_id']\n        series_id = row['series_id']\n        instance_number = row['instance_number'] \n        condition = row['condition']\n        level = row['level']\n        x, y = row['x'], row['y']\n        description = row['series_description']\n        \n        image_path = os.path.join(base_path, str(study_id), str(series_id), f\"{instance_number}.dcm\")\n        if os.path.exists(image_path):\n            dicom_content = pydicom.dcmread(image_path)\n            fig, ax = plt.subplots(1, figsize=(7, 10))\n            ax.imshow(dicom_content.pixel_array, cmap='gray')\n            ax.add_patch(Circle((x, y), radius=10, color='red', fill=False))\n            plt.title(f\"{description}\\n{condition} at {level}\")\n            plt.axis('off')\n            plt.show()\n        else:\n            print(f\"File not found: {image_path}\")\n\ndisplay_image_with_annotations(base_path, final_data)","metadata":{"ExecuteTime":{"end_time":"2024-05-31T06:28:03.304026Z","start_time":"2024-05-31T06:28:02.771290Z"},"execution":{"iopub.status.busy":"2024-05-31T07:48:39.068627Z","iopub.execute_input":"2024-05-31T07:48:39.069068Z","iopub.status.idle":"2024-05-31T07:48:43.120516Z","shell.execute_reply.started":"2024-05-31T07:48:39.069032Z","shell.execute_reply":"2024-05-31T07:48:43.119103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# GIFS","metadata":{}},{"cell_type":"code","source":"def create_gif_from_series(study_id, series_id, description):\n    images = []\n    series_path = os.path.join(base_path, str(study_id), str(series_id))\n    \n    for file_name in sorted(os.listdir(series_path)):\n        if file_name.endswith('.dcm'):\n            file_path = os.path.join(series_path, file_name)\n            ds = pydicom.dcmread(file_path)\n            img_array = ds.pixel_array\n            \n            img_array = (img_array - img_array.min()) / (img_array.max() - img_array.min()) * 255\n            img_array = img_array.astype('uint8')\n            \n            images.append(img_array)\n    \n    gif_path = os.path.join(f\"{description}.gif\")\n    imageio.mimsave(gif_path, images, duration=0.1) \n\n\nfor series in series_ids:\n    create_gif_from_series(study_id, series['series_id'], series['description'])","metadata":{"execution":{"iopub.status.busy":"2024-05-31T07:48:43.122214Z","iopub.execute_input":"2024-05-31T07:48:43.123531Z","iopub.status.idle":"2024-05-31T07:48:44.775584Z","shell.execute_reply.started":"2024-05-31T07:48:43.123491Z","shell.execute_reply":"2024-05-31T07:48:44.774191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<img src='Axial T2.gif' width=500>","metadata":{"execution":{"iopub.status.busy":"2024-05-31T07:55:01.139644Z","iopub.execute_input":"2024-05-31T07:55:01.140051Z","iopub.status.idle":"2024-05-31T07:55:01.210919Z","shell.execute_reply.started":"2024-05-31T07:55:01.140021Z","shell.execute_reply":"2024-05-31T07:55:01.209920Z"}}},{"cell_type":"markdown","source":"<img src='Sagittal T1.gif' width=500>","metadata":{"execution":{"iopub.status.busy":"2024-05-31T07:48:44.857332Z","iopub.execute_input":"2024-05-31T07:48:44.857906Z","iopub.status.idle":"2024-05-31T07:48:44.891246Z","shell.execute_reply.started":"2024-05-31T07:48:44.857874Z","shell.execute_reply":"2024-05-31T07:48:44.889918Z"}}},{"cell_type":"markdown","source":"<img src='Sagittal T2.gif' width=500>","metadata":{"execution":{"iopub.status.busy":"2024-05-31T07:48:44.892985Z","iopub.execute_input":"2024-05-31T07:48:44.893376Z","iopub.status.idle":"2024-05-31T07:48:44.986136Z","shell.execute_reply.started":"2024-05-31T07:48:44.893345Z","shell.execute_reply":"2024-05-31T07:48:44.984364Z"}}},{"cell_type":"markdown","source":"# Show some helpful metadata","metadata":{}},{"cell_type":"code","source":"def extract_relevant_dicom_metadata(dicom_file_path):\n    dicom_data = pydicom.dcmread(dicom_file_path)\n    \n    metadata = {\n        'Series Description': dicom_data.SeriesDescription if 'SeriesDescription' in dicom_data else 'N/A',\n        'Slice Thickness': dicom_data.SliceThickness if 'SliceThickness' in dicom_data else 'N/A',\n        'Spacing Between Slices': dicom_data.SpacingBetweenSlices if 'SpacingBetweenSlices' in dicom_data else 'N/A',\n        'Instance Number': dicom_data.InstanceNumber if 'InstanceNumber' in dicom_data else 'N/A',\n        'Image Position (Patient)': dicom_data.ImagePositionPatient if 'ImagePositionPatient' in dicom_data else 'N/A',\n        'Image Orientation (Patient)': dicom_data.ImageOrientationPatient if 'ImageOrientationPatient' in dicom_data else 'N/A',\n        'Slice Location': dicom_data.SliceLocation if 'SliceLocation' in dicom_data else 'N/A',\n        'Rows': dicom_data.Rows,\n        'Columns': dicom_data.Columns,\n        'Pixel Spacing': dicom_data.PixelSpacing if 'PixelSpacing' in dicom_data else 'N/A',\n        'Bits Allocated': dicom_data.BitsAllocated,\n        'Bits Stored': dicom_data.BitsStored,\n        'High Bit': dicom_data.HighBit,\n        'Pixel Representation': dicom_data.PixelRepresentation,\n        'Window Center': dicom_data.WindowCenter if 'WindowCenter' in dicom_data else 'N/A',\n        'Window Width': dicom_data.WindowWidth if 'WindowWidth' in dicom_data else 'N/A'\n    }\n    \n    return metadata\n\ndef display_relevant_dicom_metadata(dicom_file_paths):\n    all_metadata = []\n    \n    for dicom_file_path in dicom_file_paths:\n        metadata = extract_relevant_dicom_metadata(dicom_file_path)\n        all_metadata.append(metadata)\n    \n    df = pd.DataFrame(all_metadata)\n    display.display(df)\n    \ndisplay_relevant_dicom_metadata(dicom_file_paths)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T07:50:48.991512Z","iopub.execute_input":"2024-05-31T07:50:48.991908Z","iopub.status.idle":"2024-05-31T07:50:49.033590Z","shell.execute_reply.started":"2024-05-31T07:50:48.991877Z","shell.execute_reply":"2024-05-31T07:50:49.032423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# This is my first public notebook. Please upvote if you liked it!","metadata":{}}]}