{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## IMPORTS","metadata":{}},{"cell_type":"code","source":"# Arbitrary Pyramid of Imports\nimport os\nimport PIL\nimport cv2\nimport time\nimport pydicom\nimport tarfile\nimport subprocess\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nimport nibabel as nib\nfrom PIL import Image\nimport multiprocessing\nimport matplotlib.pyplot as plt\nfrom scipy import ndimage as ndi","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-30T13:40:47.645415Z","iopub.execute_input":"2021-08-30T13:40:47.645869Z","iopub.status.idle":"2021-08-30T13:40:48.587661Z","shell.execute_reply.started":"2021-08-30T13:40:47.645766Z","shell.execute_reply":"2021-08-30T13:40:48.586654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## DATAFRAMES","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv\")\ntrain_brats_ids = [f\"{x:>05}\" for x in sorted(train_df.BraTS21ID.to_list())]\n\nss_df = pd.read_csv(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification/sample_submission.csv\")\ntest_brats_ids = [f\"{x:>05}\" for x in sorted(ss_df.BraTS21ID.to_list())]\n\nprint(\"... FIRST TEN TRAIN BRATSIDS ...\\n\")\nfor x in train_brats_ids[:10]: print(\"\\t-->\", x)\n    \nprint(\"\\n\\n... FIRST TEN TEST BRATSIDS ...\\n\")\nfor x in train_brats_ids[:10]: print(\"\\t-->\", x)","metadata":{"execution":{"iopub.status.busy":"2021-08-30T13:40:52.201840Z","iopub.execute_input":"2021-08-30T13:40:52.202216Z","iopub.status.idle":"2021-08-30T13:40:52.239786Z","shell.execute_reply.started":"2021-08-30T13:40:52.202185Z","shell.execute_reply":"2021-08-30T13:40:52.238529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## FUNCTION TO INSTALL CAPTK","metadata":{}},{"cell_type":"code","source":"def install_captk(package_input_dir=\"/kaggle/input/captk-181-installerbin\", working_dir=\"/kaggle/working\"):\n    \"\"\" Function to Install the CaPTk Package\n    \n    Most of this code comes from the following excellent notebook\n        --> https://www.kaggle.com/mpsampat/running-brats-pre-processing-pipeline\n    \n    Args:\n        package_input_dir (str, optional): Directory containing the package bin file\n        working_dir (str, optional): Working directory within the particular file system\n    \n    Returns:\n        None; Installs the CaPTk package (prints at various stages)\n        \n    \"\"\"\n    # Install the `bc` package (requirement for CapTK)\n    #     --> https://helpmanual.io/packages/apt/bc/\n    print(\"\\n\\n... INSTALLING BC PACKAGE ...\\n\\n\")\n    os.system('apt install bc')\n    \n    print(\"\\n\\n... MOVING THE BIN PACKAGE TO WORKING DIRECTORY AND MODIFYING PERMISSIONS ...\\n\\n\")\n    !cp {os.path.join(package_input_dir, \"CaPTk_1.8.1_Installer.bin\")} {working_dir}\n    !chmod +x {os.path.join(working_dir, \"CaPTk_1.8.1_Installer.bin\")}\n    \n    print(\"\\n\\n... INSTALLING CAPTK ...\\n\\n\")\n    !echo -e Y | {os.path.join(working_dir, \"CaPTk_1.8.1_Installer.bin\")}\n\n    # The subprocess module provides a function named call. \n    #       - This function allows you to call another program\n    #         wait for the command to complete \n    #         and then return the return code\n    # This step is necessary because after the installer successfully finishes \n    # we will not be able to run CaPTk due to FUSE issues.\n    # Therefore, we use the following command to extract the contents of the AppImage onto the hard drive\n    print(\"\\n\\n... EXTRACT CONTENTS OF APPIMAGE ONTO HARD DRIVE ...\\n\\n\")\n    subprocess.call([os.path.join(working_dir, \"CaPTk/1.8.1/captk\"), \"--appimage-extract\"])\n    \n    # Add relevant directories to the respective paths\n    print(\"\\n\\n... ADD RELEVANT PATHS TO SYSTEM PATHS ...\\n\\n\")\n    os.environ['PATH'] = os.path.join(working_dir, \"squashfs-root/usr/lib:\") + os.environ['PATH'] \n    os.environ['LD_LIBRARY_PATH'] = os.path.join(working_dir, \"squashfs-root/usr/lib:\") + os.environ['LD_LIBRARY_PATH'] \n    \n    print(\"\\n\\n... SEE CAPTK COMMAND HELP [-h] ...\\n\\n\")\n    !{os.path.join(working_dir, \"squashfs-root/usr/bin/BraTSPipeline\")} -h\n    \ninstall_captk()","metadata":{"execution":{"iopub.status.busy":"2021-08-30T13:40:56.379589Z","iopub.execute_input":"2021-08-30T13:40:56.379950Z","iopub.status.idle":"2021-08-30T13:42:23.048073Z","shell.execute_reply.started":"2021-08-30T13:40:56.379919Z","shell.execute_reply":"2021-08-30T13:42:23.046455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## FUNCTION TO RUN CAPTK","metadata":{}},{"cell_type":"code","source":"def run_captk(brats_id, \n              cmd_dir=\"/kaggle/working/squashfs-root/usr/bin/BraTSPipeline\", \n              input_dir=\"/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification\",\n              output_dir=\"/kaggle/working\",\n              ds_split=\"train\",\n              modalities=[\"T1wCE\", \"T1w\", \"T2w\", \"FLAIR\"],\n              flags={'-s':'0', '-b':'0', '-i':'0', '-d':'0'}):\n    \"\"\" Function to trigger the BraTS CaPTk Preprocessing Pipeline\n    \n    Args:\n        brats_id (str): The particular BraTSID to run the pipeline on\n        cmd_dir (str, optional): The location of the CaPTk execuatable we wish to run\n        input_dir (str, optional): Path to the input directory containing [train|test] dicom files\n        output_dir (str, optional): Path to the desired output directory\n        ds_split (str, optional): Whether the BraTSID is found within the train or test split\n        modalities (list of strs, optional): The way the modalities are spelled/capitalized\n        flags (dict, optional): Mapping to control the optional arguments \n            for the BraTS Preprocessing Pipeline\n    \n    Returns:\n        None; Saves the generated files to the specified output directory\n    \n    \n    \"\"\"\n    # Start Timing\n    t1 = time.time()\n    print(f\"\\n... STARTING TO PREPROCESS BRATSID={brats_id} ...\\n\")\n    \n    # Make sure brats_id is the correct format\n    if len(brats_id)!=5 or type(brats_id)!=str:\n        brats_id = f\"{brats_id:>05}\"\n    \n    # Setup paths\n    modality_base_dir = os.path.join(input_dir, ds_split, brats_id)\n    output_base_dir = os.path.join(output_dir, ds_split, brats_id)\n    modality_file_map = {m:os.path.join(modality_base_dir, m,\n                                        sorted(os.listdir(os.path.join(modality_base_dir, m)), \n                                               key=lambda x: int(x.rsplit(\"-\", 1)[1].split(\".\", 1)[0]))[0])\n                         for m in modalities}\n\n    # Make output directory if it doesn't already exist\n    if not os.path.isdir(output_base_dir): os.makedirs(output_base_dir, exist_ok=True)\n\n    # Ensure the dicom image actually exists to use for reference\n    for m, f_path in modality_file_map.items(): \n        if not os.path.exists(f_path):\n            print(f\"\\n... {f_path} does not exist for {m} modality ...\\n\")\n            \n    subprocess.call([\n        cmd_dir,                            # Path to the CaPTk executable file\n        '-t1c', modality_file_map[\"T1wCE\"], # Input structural T1-weighted post-contrast image \n        '-t1', modality_file_map[\"T1w\"],    # Input structural T1-weighted pre-contrast image\n        '-t2', modality_file_map[\"T2w\"],    # Input structural T2-weighted contrast image \n        '-fl', modality_file_map[\"FLAIR\"],  # Input structural FLAIR contrast image\n        '-o', output_base_dir,              # Output directory for final output\n        '-s', flags['-s'], # [DEFAULT=0]    # Flag whether to skull strip or not (0=NO, 1=YES)          \n        '-b', flags['-b'], # [DEFAULT=0]    # Flag whether to segment brain tumors or no (0=NO, 1=YES)\n        '-i', flags['-i'], # [DEFAULT=0]    # Flag whether to save intermediate files (0=NO, 1=YES)\n        '-d', flags['-d'], # [DEFAULT=0]    # Flag whether to print debugging information (0=NO, 1=YES)\n    ])\n    print(f\"\\n... IT TOOK {time.time()-t1:.3f} SECONDS TO COMPLETE BRATSID={brats_id}...\\n\")","metadata":{"execution":{"iopub.status.busy":"2021-08-30T13:42:23.052347Z","iopub.execute_input":"2021-08-30T13:42:23.052760Z","iopub.status.idle":"2021-08-30T13:42:23.069404Z","shell.execute_reply.started":"2021-08-30T13:42:23.052712Z","shell.execute_reply":"2021-08-30T13:42:23.068211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## FUNCTION TO RUN CAPTK ON SUBSAMPLE OF DATA","metadata":{}},{"cell_type":"code","source":"t1 = time.time()\n\nprint(\"\\n\\n\\n... STARTING TRAIN IMAGES ...\\n\\n\\n\")\n# test to see if multiprocessing can benefit us here...\nfor b_id in train_brats_ids[:5]:\n    KWARGS = dict(brats_id=b_id, ds_split=\"train\", flags={'-s':'0', '-b':'0', '-i':'0', '-d':'0'})\n    p = multiprocessing.Process(target=run_captk, kwargs=KWARGS)\n    p.start()\n    p.join()\nprint(\"\\n\\n\\n... FINISHING TRAIN IMAGES ...\\n\\n\\n\")\n\nprint(\"\\n\\n\\n... STARTING TEST IMAGES ...\\n\\n\\n\")\nfor brats_id in test_brats_ids[:5]:\n    run_captk(brats_id, ds_split=\"test\", flags={'-s':'0', '-b':'0', '-i':'0', '-d':'0'})\nprint(\"\\n\\n\\n... FINISHING TEST IMAGES ...\\n\\n\\n\")\n\nprint(f\"\\n\\n\\n\\n\\nTIME TO FINISH 50 PATIENTS IS :   {time.time()-t1:.4f} ...\\n\\n\\n\\n\\n\")","metadata":{"execution":{"iopub.status.busy":"2021-08-30T13:45:44.383408Z","iopub.execute_input":"2021-08-30T13:45:44.383793Z","iopub.status.idle":"2021-08-30T14:00:10.071544Z","shell.execute_reply.started":"2021-08-30T13:45:44.383754Z","shell.execute_reply":"2021-08-30T14:00:10.069116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Clean Up So We Can Use the Output For Dataset Creation\n!rm -rf /kaggle/working/squashfs-root\n!rm -rf /kaggle/working/CaPTk\n!rm -rf /kaggle/working/CaPTk_1.8.1_Installer.bin","metadata":{},"execution_count":null,"outputs":[]}]}