{"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":71549,"databundleVersionId":8561470,"sourceType":"competition"},{"sourceId":9071670,"sourceType":"datasetVersion","datasetId":5471909}],"dockerImageVersionId":30746,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Creating files and Folders for debugging submission code\n\n## What we have ?\n- test_imags folder provided by organizers has single study_id with 3-series\n\n## What problems I faced and what I have explored till now?\n\n- Current submission setup provides no way to debug if submission code runs successfully but scoring fails with *'Submission Scoring Error'* or *'Notebook Threw Exception'*\n- I wanted to validate my submission code which loops through study_ids in test_images folder which is not possible with test_images folder with single study_id instance.\n- I had asked the organizers to have at least 2 folders in test_images for loop code validation [here](https://www.kaggle.com/competitions/rsna-2024-lumbar-spine-degenerative-classification/discussion/516357#2917606\n) but organizers haven't responded since 19-days so I decided to do something about it myself.\n- [here](https://www.kaggle.com/competitions/rsna-2024-lumbar-spine-degenerative-classification/discussion/519612#2918053)\n[Sergey Saharovskiy](https://www.kaggle.com/sergiosaharovskiy) suggested to run the inference pipeline on train folder which is good idea, but it would take long time to run and debug on whole train folder which will again eat away GPU resurces which are limited per week.\n- I also wanted to test my submission code against edge cases like missing folders or more than 3-folders etc which is not readily possible with current test_images folder.\n\n## Solution\n- I created a dubug folder with dummy_test_images folder which includes 7-study_ids with variations like 2,3,4-series per study_id which will validate your code against fairly robust settings.\n- I have also supplemented it with dummy_test_description.csv and dummy_sample_submission.csv files which will help in creating submission.csv file.\n\n## PS:\n- I have included all files from originial competition dataset to debug dataset\n- Both train_images and test_images folders have 7-study_ids for quick and dirty prototyping for train and inference script\n- You can now use this dataset as drop in replacement for original competition dataset.\n- Happy coding !!!","metadata":{}},{"cell_type":"markdown","source":"## Import necessary Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport glob\nimport shutil\nimport numpy as np\nimport pandas as pd\nfrom tqdm.notebook import tqdm","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:37:56.995782Z","iopub.execute_input":"2024-10-02T05:37:56.996184Z","iopub.status.idle":"2024-10-02T05:37:58.140880Z","shell.execute_reply.started":"2024-10-02T05:37:56.996152Z","shell.execute_reply":"2024-10-02T05:37:58.139765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"DEBUG= False\nif DEBUG==True:\n    base_dir = '/kaggle/input/rsna-lsdc-2024-submission-debug-dataset'\nelse:\n    base_dir = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification'","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:38:23.256210Z","iopub.execute_input":"2024-10-02T05:38:23.256955Z","iopub.status.idle":"2024-10-02T05:38:23.261229Z","shell.execute_reply.started":"2024-10-02T05:38:23.256923Z","shell.execute_reply":"2024-10-02T05:38:23.260239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_images/'\nglob_pattern = os.path.join(base_dir, '*',\"*\",\"*\") \nglob_pattern","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:38:25.515488Z","iopub.execute_input":"2024-10-02T05:38:25.515842Z","iopub.status.idle":"2024-10-02T05:38:25.522269Z","shell.execute_reply.started":"2024-10-02T05:38:25.515797Z","shell.execute_reply":"2024-10-02T05:38:25.521348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def copy_folder(base_dir,destination_dir,num_files,train = True):\n    glob_pattern = os.path.join(base_dir, '*',\"*\",\"*\") \n    files_to_copy = glob.glob(glob_pattern, recursive=True)\n    if train==True:\n        files_to_copy = files_to_copy[:num_files]\n    else:\n        files_to_copy = files_to_copy[-num_files:]\n    os.makedirs(destination_dir, exist_ok=True)\n    # Copy each file to the destination directory, preserving the folder structure\n    for file_path in tqdm(files_to_copy):\n        # Get the relative path from the base directory\n        relative_path = os.path.relpath(file_path, base_dir)\n        # Create the full destination path\n        dest_path = os.path.join(destination_dir, relative_path)\n        # Create the destination directory if it doesn't exist\n        os.makedirs(os.path.dirname(dest_path), exist_ok=True)\n        # Copy the file\n        shutil.copy(file_path, dest_path)\n    study_ids = [int(i.split(\"/\")[-1]) for i in glob.glob(destination_dir+\"/*\")]\n\n    return study_ids","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:38:26.416616Z","iopub.execute_input":"2024-10-02T05:38:26.417015Z","iopub.status.idle":"2024-10-02T05:38:26.425409Z","shell.execute_reply.started":"2024-10-02T05:38:26.416981Z","shell.execute_reply":"2024-10-02T05:38:26.424151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_images/'\ndestination_dir = '/kaggle/working/debug/train_images'\ntrain_study_ids = copy_folder(base_dir,destination_dir,num_files=500,train = True)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:38:27.235395Z","iopub.execute_input":"2024-10-02T05:38:27.235763Z","iopub.status.idle":"2024-10-02T05:39:08.235228Z","shell.execute_reply.started":"2024-10-02T05:38:27.235732Z","shell.execute_reply":"2024-10-02T05:39:08.234184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_images/'\ndestination_dir = '/kaggle/working/debug/test_images'\ntest_study_ids = copy_folder(base_dir,destination_dir,num_files=500,train = True)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:39:08.236995Z","iopub.execute_input":"2024-10-02T05:39:08.237325Z","iopub.status.idle":"2024-10-02T05:39:13.502010Z","shell.execute_reply.started":"2024-10-02T05:39:08.237297Z","shell.execute_reply":"2024-10-02T05:39:13.501025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_study_ids),len(test_study_ids)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:39:13.503184Z","iopub.execute_input":"2024-10-02T05:39:13.503494Z","iopub.status.idle":"2024-10-02T05:39:13.510214Z","shell.execute_reply.started":"2024-10-02T05:39:13.503466Z","shell.execute_reply":"2024-10-02T05:39:13.509271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def copy_csv(input_filepath,dest_file_path,study_ids):\n    file = pd.read_csv(input_filepath)\n    dummy_file = file[file['study_id'].isin(study_ids)].copy()\n    dummy_file.to_csv(f'debug/{dest_file_path.split(\"/\")[-1]}',index=False)\n#     display(dummy_file)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:41:48.784234Z","iopub.execute_input":"2024-10-02T05:41:48.785033Z","iopub.status.idle":"2024-10-02T05:41:48.790416Z","shell.execute_reply.started":"2024-10-02T05:41:48.784995Z","shell.execute_reply":"2024-10-02T05:41:48.789328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_pattern = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/*'\ncsv_files = [i for i in glob.glob(base_pattern) if i.endswith(\".csv\")][1:]\ncsv_files","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:41:49.598347Z","iopub.execute_input":"2024-10-02T05:41:49.599061Z","iopub.status.idle":"2024-10-02T05:41:49.607647Z","shell.execute_reply.started":"2024-10-02T05:41:49.599018Z","shell.execute_reply":"2024-10-02T05:41:49.606555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_filepath = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train.csv'\ndest_file_path = 'train.csv'\nstudy_ids = train_study_ids\ncopy_csv(input_filepath,dest_file_path,study_ids)\n\ninput_filepath = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train.csv'\ndest_file_path = 'test.csv'\nstudy_ids = test_study_ids\ncopy_csv(input_filepath,dest_file_path,study_ids)\n\n\n\n\ninput_filepath = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_label_coordinates.csv'\ndest_file_path = 'train_label_coordinates.csv'\nstudy_ids = train_study_ids\ncopy_csv(input_filepath,dest_file_path,study_ids)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:41:50.384963Z","iopub.execute_input":"2024-10-02T05:41:50.385860Z","iopub.status.idle":"2024-10-02T05:41:50.559169Z","shell.execute_reply.started":"2024-10-02T05:41:50.385803Z","shell.execute_reply":"2024-10-02T05:41:50.558143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def copy_series_description_csv(input_filepath,dest_file_path,study_ids,series_folder):\n    file = pd.read_csv(input_filepath)\n    dummy_file = file[file['study_id'].isin(study_ids)].copy()\n    \n    glob_pattern = os.path.join(series_folder, '*',\"*\",\"*\") \n    series_folders = glob.glob(glob_pattern, recursive=True)\n\n    series_in_folder =  list(set([int(i.split(\"/\")[-2]) for i in series_folders]))\n#     print(series_in_folder)\n    cond1 = file['study_id'].isin(study_ids)\n    cond2 = file['series_id'].isin(series_in_folder)\n    dummy_file = file[cond1&cond2].copy()\n    dummy_file.to_csv(f'debug/{dest_file_path.split(\"/\")[-1]}',index=False)\n#     display(dummy_file)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:47:03.708051Z","iopub.execute_input":"2024-10-02T05:47:03.708433Z","iopub.status.idle":"2024-10-02T05:47:03.715976Z","shell.execute_reply.started":"2024-10-02T05:47:03.708402Z","shell.execute_reply":"2024-10-02T05:47:03.714744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_filepath = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv'\ndest_file_path = 'train_series_descriptions.csv'\nstudy_ids = train_study_ids\nseries_folder = \"/kaggle/working/debug/train_images\"\ncopy_series_description_csv(input_filepath,dest_file_path,study_ids,series_folder)\n\ninput_filepath = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv'\ndest_file_path = 'test_series_descriptions.csv'\nstudy_ids = test_study_ids\nseries_folder = \"/kaggle/working/debug/test_images\"\ncopy_series_description_csv(input_filepath,dest_file_path,study_ids,series_folder)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:47:03.985416Z","iopub.execute_input":"2024-10-02T05:47:03.985875Z","iopub.status.idle":"2024-10-02T05:47:04.015921Z","shell.execute_reply.started":"2024-10-02T05:47:03.985834Z","shell.execute_reply":"2024-10-02T05:47:04.014837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission_path = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/sample_submission.csv'\nsample_submission =  pd.read_csv(sample_submission_path)\nall_row_ids = [[\"_\".join([str(study_id),*(i[1:])]) for i in sample_submission[\"row_id\"].str.split(\"_\")] for study_id in study_ids]\nrow_id = sorted(np.array(all_row_ids).flatten().tolist())\ndummy_sample_submission = pd.DataFrame({'row_id':row_id,\"normal_mild\":0.33,'moderate':0.33,'severe':0.33})\ndummy_sample_submission.to_csv(\"debug/sample_submission.csv\",index=False)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T05:47:04.219193Z","iopub.execute_input":"2024-10-02T05:47:04.219542Z","iopub.status.idle":"2024-10-02T05:47:04.232694Z","shell.execute_reply.started":"2024-10-02T05:47:04.219517Z","shell.execute_reply":"2024-10-02T05:47:04.231566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}