{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"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"},"vscode":{"interpreter":{"hash":"f7241b2af102f7e024509099765066b36197b195077f7bfac6e5bc041ba17c8c"}},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"},{"sourceId":6089786,"sourceType":"datasetVersion","datasetId":3487378},{"sourceId":6267500,"sourceType":"datasetVersion","datasetId":3581068},{"sourceId":9117460,"sourceType":"datasetVersion","datasetId":5503496},{"sourceId":9324078,"sourceType":"datasetVersion","datasetId":5521028},{"sourceId":9352418,"sourceType":"datasetVersion","datasetId":5520878},{"sourceId":9566244,"sourceType":"datasetVersion","datasetId":5429096},{"sourceId":9576784,"sourceType":"datasetVersion","datasetId":5698705},{"sourceId":9566536,"sourceType":"datasetVersion","datasetId":5520938},{"sourceId":9567162,"sourceType":"datasetVersion","datasetId":5831049},{"sourceId":135925962,"sourceType":"kernelVersion"},{"sourceId":143511308,"sourceType":"kernelVersion"},{"sourceId":189493593,"sourceType":"kernelVersion"},{"sourceId":189493642,"sourceType":"kernelVersion"},{"sourceId":194725442,"sourceType":"kernelVersion"},{"sourceId":194726480,"sourceType":"kernelVersion"},{"sourceId":194727039,"sourceType":"kernelVersion"},{"sourceId":197533265,"sourceType":"kernelVersion"},{"sourceId":198937057,"sourceType":"kernelVersion"},{"sourceId":199071734,"sourceType":"kernelVersion"},{"sourceId":199615140,"sourceType":"kernelVersion"},{"sourceId":199618422,"sourceType":"kernelVersion"},{"sourceId":199650896,"sourceType":"kernelVersion"},{"sourceId":199650928,"sourceType":"kernelVersion"},{"sourceId":199650942,"sourceType":"kernelVersion"},{"sourceId":199650954,"sourceType":"kernelVersion"},{"sourceId":199650999,"sourceType":"kernelVersion"},{"sourceId":199658918,"sourceType":"kernelVersion"}],"dockerImageVersionId":30747,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Dieter","metadata":{}},{"cell_type":"code","source":"%%python\n\n##### %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:42:17.348876Z\",\"iopub.execute_input\":\"2024-08-30T21:42:17.349931Z\",\"iopub.status.idle\":\"2024-08-30T21:42:55.160463Z\",\"shell.execute_reply.started\":\"2024-08-30T21:42:17.349886Z\",\"shell.execute_reply\":\"2024-08-30T21:42:55.159222Z\"}}\nimport subprocess\nsubprocess.run('pip install -r /kaggle/input/github-rsna24/requirements_ngc.txt --no-index --find-links=file:/kaggle/input/rsna24-pip-packages -qqq', shell=True)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:42:55.164228Z\",\"iopub.execute_input\":\"2024-08-30T21:42:55.164594Z\",\"iopub.status.idle\":\"2024-08-30T21:42:59.922362Z\",\"shell.execute_reply.started\":\"2024-08-30T21:42:55.164566Z\",\"shell.execute_reply\":\"2024-08-30T21:42:59.921208Z\"}}\nimport numpy as np\nimport pandas as pd\nimport scipy as sp\nimport os\nimport json\nimport sys\nimport importlib\nimport multiprocessing as mp\nimport gc\nfrom tqdm import tqdm\nimport glob\nimport torch\nfrom copy import copy\nfrom torch.utils.data import DataLoader\nimport sys\nimport pickle\nimport shutil\nimport pydicom\nimport cv2\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:42:59.923999Z\",\"iopub.execute_input\":\"2024-08-30T21:42:59.924483Z\",\"iopub.status.idle\":\"2024-08-30T21:43:00.042039Z\",\"shell.execute_reply.started\":\"2024-08-30T21:42:59.924453Z\",\"shell.execute_reply\":\"2024-08-30T21:43:00.040734Z\"}}\nCOMP_FOLDER = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/'\n\n# train_df = pd.read_csv(COMP_FOLDER + 'train.csv')\n# test_df = pd.read_csv(COMP_FOLDER + 'test.csv')\nsample_submission = pd.read_csv(COMP_FOLDER + 'sample_submission.csv')\ntest_series_descriptions = pd.read_csv(COMP_FOLDER + 'test_series_descriptions.csv')\n\nPUBLIC_RUN = test_series_descriptions.shape[0] == 3\n\nN_CORES = mp.cpu_count()\nMIXED_PRECISION = False\n\nRAM_CHECK = False\nOOF_CHECK = False\nDEBUG = False\nFOLD = 1\n\n# assert (RAM_CHECK + OOF_CHECK) <= 1\n\nDEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'\n\nif PUBLIC_RUN is False:\n    RAM_CHECK = False\n    OOF_CHECK = False\n    DEBUG = False\n\nif OOF_CHECK:\n    DATA_FOLDER = COMP_FOLDER + 'train_images/'\n    test_df = pd.read_csv('/kaggle/input/aws-bucket-rsna24/train_folded_v1.csv')\n    test_df = test_df[test_df['fold']==FOLD].copy()\nelif DEBUG:\n    DATA_FOLDER = COMP_FOLDER + 'train_images/'\n    test_df = pd.read_csv('/kaggle/input/aws-bucket-rsna24/train_folded_v1.csv')\n    test_df = test_df[test_df['fold']==FOLD].copy().head(3)\nelif RAM_CHECK:\n    DATA_FOLDER = COMP_FOLDER + 'train_images/'\n    test_df = pd.read_csv('/kaggle/input/aws-bucket-rsna24/train_folded_v1.csv').sample(500000, random_state=23, replace=True)\nelse:\n    #create dummy test file\n    LEVELS = ['l1_l2','l2_l3','l3_l4','l4_l5','l5_s1']\n    TARGET_COLS = [f'spinal_canal_stenosis_{l}' for l in LEVELS] \n    TARGET_COLS += [f'left_neural_foraminal_narrowing_{l}' for l in LEVELS] \n    TARGET_COLS += [f'right_neural_foraminal_narrowing_{l}' for l in LEVELS] \n    TARGET_COLS += [f'left_subarticular_stenosis_{l}' for l in LEVELS] \n    TARGET_COLS += [f'right_subarticular_stenosis_{l}' for l in LEVELS] \n    study_ids = test_series_descriptions['study_id'].unique()\n    test_df = pd.DataFrame({'study_id':study_ids})\n    test_df[TARGET_COLS] = 'Normal/Mild'\n    test_df['fold'] = 0\n    test_df =test_df.merge(test_series_descriptions, how='right', on='study_id')\n    \n    DATA_FOLDER = COMP_FOLDER + 'test_images/'\n    \ntest_df['series_id'] = test_df['series_id'].astype(int)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:00.045396Z\",\"iopub.execute_input\":\"2024-08-30T21:43:00.046275Z\",\"iopub.status.idle\":\"2024-08-30T21:43:00.064589Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:00.046231Z\",\"shell.execute_reply\":\"2024-08-30T21:43:00.063496Z\"}}\ndf_sag_t1 = test_df[test_df['series_description'] == 'Sagittal T1'].copy()\ndf_sag_t2 = test_df[test_df['series_description'] == 'Sagittal T2/STIR'].copy()\ndf_sag = pd.concat([df_sag_t1,df_sag_t2]).reset_index(drop=True).copy()\ndf_ax = test_df[test_df['series_description'] == 'Axial T2'].copy()\ndf_sag_t1.shape, df_sag_t2.shape, df_ax.shape, df_sag.shape\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:00.066169Z\",\"iopub.execute_input\":\"2024-08-30T21:43:00.067152Z\",\"iopub.status.idle\":\"2024-08-30T21:43:00.075195Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:00.067113Z\",\"shell.execute_reply\":\"2024-08-30T21:43:00.07424Z\"}}\nimport sys\nsys.path.append('/kaggle/input/github-rsna24/configs')\nsys.path.append('/kaggle/input/github-rsna24/data')\nsys.path.append('/kaggle/input/github-rsna24/models')\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:00.078355Z\",\"iopub.execute_input\":\"2024-08-30T21:43:00.078869Z\",\"iopub.status.idle\":\"2024-08-30T21:43:00.097635Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:00.078832Z\",\"shell.execute_reply\":\"2024-08-30T21:43:00.096292Z\"}}\ndef get_cfg(CFG):\n    cfg = importlib.import_module('default_config')\n    importlib.reload(cfg)\n    cfg = importlib.import_module(CFG)\n    importlib.reload(cfg)\n    cfg = copy(cfg.cfg)\n#     cfg.post_process_pipeline = importlib.import_module(cfg.post_process_pipeline).post_process_pipeline\n\n    cfg.data_dir = COMP_FOLDER\n    cfg.data_folder = DATA_FOLDER\n    cfg.mixed_precision = MIXED_PRECISION\n    cfg.pretrained = False\n    cfg.pretrained_weights = False\n#     cfg.batch_size = 2\n    cfg.offline_inference = True\n\n#     print(CFG, cfg.model, cfg.dataset, cfg.backbone, cfg.tokenizer, cfg.pretrained_weights, cfg.post_process_pipeline)\n    \n    return cfg\n\ndef get_dl(cfg):\n    ds = importlib.import_module(cfg.dataset)\n    importlib.reload(ds)\n\n    CustomDataset = ds.CustomDataset\n    batch_to_device = ds.batch_to_device\n\n    test_ds = CustomDataset(test_df, cfg, cfg.val_aug, mode=\"test\")\n    test_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=True)\n\n    return test_dl, batch_to_device\n\ndef get_state_dict(sd_fp):\n    sd = torch.load(sd_fp, map_location=\"cpu\")\n    if \"model\" in sd.keys():\n        sd = sd[\"model\"]\n    sd = {k.replace(\"module.\", \"\"):v for k,v in sd.items()}\n    return sd\n\ndef get_nets(cfg,state_dicts):\n    model = importlib.import_module(cfg.model)\n    importlib.reload(model)\n    Net = model.Net\n    nets = []\n    for i,state_dict in enumerate(state_dicts):\n        net = Net(cfg).eval().to(DEVICE)\n        print(\"loading dict\")\n        sd = get_state_dict(state_dict)\n\n        net.load_state_dict(sd, strict=True)\n        net.is_test = True\n        nets += [net]\n        del sd\n        gc.collect()\n    return nets\n\n# %% [markdown]\n# ## Sagittal level prediction\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:00.099343Z\",\"iopub.execute_input\":\"2024-08-30T21:43:00.100286Z\",\"iopub.status.idle\":\"2024-08-30T21:43:22.258415Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:00.100248Z\",\"shell.execute_reply\":\"2024-08-30T21:43:22.255808Z\"}}\nname = 'cfg_ch_stg1_sagt1t2_2b'\ncfg = get_cfg(name)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:22.259722Z\",\"iopub.execute_input\":\"2024-08-30T21:43:22.26018Z\",\"iopub.status.idle\":\"2024-08-30T21:43:22.4016Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:22.260151Z\",\"shell.execute_reply\":\"2024-08-30T21:43:22.400573Z\"}}\nitems = df_sag[['study_id','series_id']].values\ntest_df2 = []\nfor study_id, series_id in tqdm(items):\n    dicom_ids = sorted([int(fn.split('/')[-1].replace('.dcm','')) for fn in glob.glob(f'{DATA_FOLDER}{study_id}/{series_id}/*.dcm')])\n    d = pd.DataFrame({'instance_number':dicom_ids})\n    d['study_id'] = study_id\n    d['series_id'] = series_id\n    test_df2 += [d]\ntest_df2 = pd.concat(test_df2)\ntest_df2[cfg.classes] = 0.\ntest_df2 = test_df2.merge(df_sag[['series_id','fold']],on='series_id',how='left')\ntest_df2\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:22.403119Z\",\"iopub.execute_input\":\"2024-08-30T21:43:22.403567Z\",\"iopub.status.idle\":\"2024-08-30T21:43:23.40151Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:22.40353Z\",\"shell.execute_reply\":\"2024-08-30T21:43:23.400475Z\"}}\nstate_dict_fps = sorted(glob.glob(f'/kaggle/input/weights-rsna24-cfg-ch-stg1-sagt1t2-2b/*/*check*', recursive = True))\n\nif OOF_CHECK:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold{FOLD}/' in fp]\n\n# test_dl, batch_to_device = get_dl(cfg)\nds = importlib.import_module(cfg.dataset)\nimportlib.reload(ds)\n\nCustomDataset = ds.CustomDataset\nbatch_to_device = ds.batch_to_device\n\ntest_ds = CustomDataset(test_df2, cfg, cfg.val_aug, mode=\"test\")\ntest_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=True)\nprint('\\n'.join(state_dict_fps))\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:23.40535Z\",\"iopub.execute_input\":\"2024-08-30T21:43:23.40566Z\",\"iopub.status.idle\":\"2024-08-30T21:43:34.574259Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:23.405635Z\",\"shell.execute_reply\":\"2024-08-30T21:43:34.573091Z\"}}\nnets = get_nets(cfg,state_dict_fps)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:34.576098Z\",\"iopub.execute_input\":\"2024-08-30T21:43:34.576523Z\",\"iopub.status.idle\":\"2024-08-30T21:43:39.120457Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:34.576484Z\",\"shell.execute_reply\":\"2024-08-30T21:43:39.119257Z\"}}\npreds = []\nwith torch.inference_mode():\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch,DEVICE)\n        outs = [net(batch) for net in nets]\n        preds += [torch.stack([out['logits'] for out in outs], dim=0).mean(0).cpu()]\npreds = torch.cat(preds, dim=0).float()\nprint('preds', preds.shape, ', test_df',test_df.shape)\n\ndel nets\ngc.collect()\ntorch.cuda.empty_cache()\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:43:39.122122Z\",\"iopub.execute_input\":\"2024-08-30T21:43:39.122446Z\",\"iopub.status.idle\":\"2024-08-30T21:43:39.139017Z\",\"shell.execute_reply.started\":\"2024-08-30T21:43:39.12242Z\",\"shell.execute_reply\":\"2024-08-30T21:43:39.137886Z\"}}\nkps_sag = test_df2.copy()\nkps_sag[cfg.classes] = preds.reshape(preds.shape[0],5,2).permute(0,2,1).reshape(preds.shape[0], 10).numpy()\nkps_sag[cfg.classes].mean()\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:12.405331Z\",\"iopub.execute_input\":\"2024-08-30T21:46:12.405849Z\",\"iopub.status.idle\":\"2024-08-30T21:46:12.432709Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:12.40581Z\",\"shell.execute_reply\":\"2024-08-30T21:46:12.431519Z\"}}\n#preprocess crops\n\nSAG_CROPS_FOLDER = 'crops_roi_sag/'\n# IMG_SIZE = 512\n# CROP_SIZE = 144\nCROP_SIZE_PCT = 144 / 512\nLEVELS = ['l1_l2','l2_l3','l3_l4','l4_l5','l5_s1']\nos.makedirs(SAG_CROPS_FOLDER, exist_ok=True)\n\nkps_gr = kps_sag.groupby('series_id')\n\nimport pydicom\n\n\ndef read_dcm_ret_arr(src_path):\n    image = pydicom.dcmread(src_path).pixel_array\n    image = convert_to_8bit(image)\n#     image = cv2.resize(image, (IMG_SIZE, IMG_SIZE), interpolation=cv2.INTER_CUBIC)\n#     assert img.shape == (IMG_SIZE[0], IMG_SIZE[1])\n    return image\n\ndef convert_to_8bit(x):\n    lower, upper = np.percentile(x, (1, 99))\n    x = np.clip(x, lower, upper)\n    x = x - np.min(x)\n    x = x / np.max(x) \n    return (x * 255).astype(\"uint8\")\n\n\ndef load_dicom_stack(dicom_folder, plane, reverse_sort=False):\n    dicom_files = glob.glob(os.path.join(dicom_folder, \"*.dcm\"))\n    dicoms = [pydicom.dcmread(f) for f in dicom_files]\n    \n    instance_ids = np.array([int(fn.split('/')[-1].replace('.dcm','')) for fn in dicom_files])\n#     series_ids = np.array([int(fn.split('/')[-2]) for fn in dicom_files])[idx]\n    \n    plane = {\"sagittal\": 0, \"coronal\": 1, \"axial\": 2}[plane.lower()]\n    positions = np.asarray([float(d.ImagePositionPatient[plane]) for d in dicoms])\n    # if reverse_sort=False, then increasing array index will be from RIGHT->LEFT and CAUDAL->CRANIAL\n    # thus we do reverse_sort=True for axial so increasing array index is craniocaudal\n    idx = np.argsort(-positions if reverse_sort else positions)\n    ipp = np.asarray([d.ImagePositionPatient for d in dicoms]).astype(\"float\")[idx]\n    array = np.stack([d.pixel_array.astype(\"float32\") for d in dicoms])\n    array = array[idx]\n    \n    instance_ids = instance_ids[idx]\n    \n    return {\"array\": convert_to_8bit(array), \"positions\": ipp, \"pixel_spacing\": np.asarray(dicoms[0].PixelSpacing).astype(\"float\"),'instance_ids':instance_ids}\n\ndef do_one(series_id):\n    sub_df = kps_gr.get_group(series_id)\n    study_id = sub_df['study_id'].values[0]\n    \n    dicom_stack = load_dicom_stack(f'{DATA_FOLDER}{study_id}/{series_id}/', plane='sagittal')\n    \n    instance_numbers = dicom_stack['instance_ids']\n    imgs = dicom_stack['array']\n    \n    sub_df = sub_df.set_index('instance_number').loc[instance_numbers]\n    H, W = imgs.shape[1:]\n    CROP_SIZE_X = int(W * CROP_SIZE_PCT)\n    CROP_SIZE_Y = int(H * CROP_SIZE_PCT)\n    img_ids = []\n    for i in range(5):\n        d = sub_df[[f'D{i+1}_x',f'D{i+1}_y']].values * np.array([W,H])[None]\n        \n        xmin = (d[:,0] - CROP_SIZE_X // 2).clip(0,W-CROP_SIZE_X)\n        xmax = xmin + CROP_SIZE_X\n        ymin = (d[:,1] - CROP_SIZE_Y // 2).clip(0,H-CROP_SIZE_Y)\n        ymax = ymin + CROP_SIZE_Y\n\n        bbs = np.stack([xmin,xmax,ymin,ymax],axis=-1).astype(int)\n        bb = np.median(bbs,axis=0).astype(int)\n        crop = imgs[:,bb[2]:bb[3],bb[0]:bb[1]].transpose(1,2,0).copy()\n        img_id = f'{series_id}_{LEVELS[i]}'\n        np.save(f'{SAG_CROPS_FOLDER}{img_id}.npy',crop.copy())\n\n\n        img_ids += [img_id]\n    return img_ids\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:12.546719Z\",\"iopub.execute_input\":\"2024-08-30T21:46:12.54714Z\",\"iopub.status.idle\":\"2024-08-30T21:46:12.554972Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:12.547108Z\",\"shell.execute_reply\":\"2024-08-30T21:46:12.553793Z\"}}\nseries_ids = kps_sag['series_id'].unique()\nseries_ids\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:12.71012Z\",\"iopub.execute_input\":\"2024-08-30T21:46:12.711188Z\",\"iopub.status.idle\":\"2024-08-30T21:46:14.359151Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:12.711142Z\",\"shell.execute_reply\":\"2024-08-30T21:46:14.357903Z\"}}\nwith mp.Pool(N_CORES) as p:\n    res = list(tqdm(p.imap(do_one,series_ids),total=len(series_ids)))\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:17.471625Z\",\"iopub.execute_input\":\"2024-08-30T21:46:17.472613Z\",\"iopub.status.idle\":\"2024-08-30T21:46:17.496871Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:17.472574Z\",\"shell.execute_reply\":\"2024-08-30T21:46:17.495773Z\"}}\ntest_df_sag_lvl = pd.DataFrame([x for sublist in res for x in sublist],columns=['image_id'])\ntest_df_sag_lvl['level'] = test_df_sag_lvl['image_id'].apply(lambda x: '_'.join(x.split('_')[1:]))\ntest_df_sag_lvl['series_id'] = test_df_sag_lvl['image_id'].apply(lambda x: x.split('_')[0])\n#dummy labels \ntest_df_sag_lvl['left_neural_foraminal_narrowing'] = 'Normal/Mild'\ntest_df_sag_lvl['right_neural_foraminal_narrowing'] = 'Normal/Mild'\ntest_df_sag_lvl['spinal_canal_stenosis'] = 'Normal/Mild'\ntest_df_sag_lvl.head()\n\n# %% [markdown]\n# ## Axial xy prediction\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:18.455678Z\",\"iopub.execute_input\":\"2024-08-30T21:46:18.456066Z\",\"iopub.status.idle\":\"2024-08-30T21:46:18.480899Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:18.456034Z\",\"shell.execute_reply\":\"2024-08-30T21:46:18.479994Z\"}}\nname = 'cfg_ch_15e_ax_v1'\ncfg = get_cfg(name)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:21.091544Z\",\"iopub.execute_input\":\"2024-08-30T21:46:21.092274Z\",\"iopub.status.idle\":\"2024-08-30T21:46:21.16319Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:21.092235Z\",\"shell.execute_reply\":\"2024-08-30T21:46:21.162193Z\"}}\nitems = df_ax[['study_id','series_id']].values\ntest_df2 = []\nfor study_id, series_id in tqdm(items):\n    dicom_ids = sorted([int(fn.split('/')[-1].replace('.dcm','')) for fn in glob.glob(f'{DATA_FOLDER}{study_id}/{series_id}/*.dcm')])\n    d = pd.DataFrame({'instance_number':dicom_ids})\n    d['study_id'] = study_id\n    d['series_id'] = series_id\n    test_df2 += [d]\ntest_df2 = pd.concat(test_df2)\ntest_df2[cfg.classes] = 0.\ntest_df2 = test_df2.merge(df_ax[['series_id','fold']],on='series_id',how='left')\ntest_df2\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:21.559329Z\",\"iopub.execute_input\":\"2024-08-30T21:46:21.559749Z\",\"iopub.status.idle\":\"2024-08-30T21:46:21.588783Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:21.559719Z\",\"shell.execute_reply\":\"2024-08-30T21:46:21.587785Z\"}}\nstate_dict_fps = sorted(glob.glob(f'/kaggle/input/weights-rsna24-cfg-ch-15e-ax-v1/*/*check*', recursive = True))\n\nif OOF_CHECK:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold{FOLD}/' in fp]\n\n# test_dl, batch_to_device = get_dl(cfg)\nds = importlib.import_module(cfg.dataset)\nimportlib.reload(ds)\n\nCustomDataset = ds.CustomDataset\nbatch_to_device = ds.batch_to_device\n\ntest_ds = CustomDataset(test_df2, cfg, cfg.val_aug, mode=\"test\")\ntest_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=True)\nprint('\\n'.join(state_dict_fps))\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:23.893953Z\",\"iopub.execute_input\":\"2024-08-30T21:46:23.894371Z\",\"iopub.status.idle\":\"2024-08-30T21:46:32.055676Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:23.894341Z\",\"shell.execute_reply\":\"2024-08-30T21:46:32.054818Z\"}}\nnets = get_nets(cfg,state_dict_fps)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:32.057514Z\",\"iopub.execute_input\":\"2024-08-30T21:46:32.057847Z\",\"iopub.status.idle\":\"2024-08-30T21:46:34.489544Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:32.05782Z\",\"shell.execute_reply\":\"2024-08-30T21:46:34.488275Z\"}}\npreds = []\nwith torch.inference_mode():\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch,DEVICE)\n        outs = [net(batch) for net in nets]\n        preds += [torch.stack([out['logits'] for out in outs], dim=0).mean(0).cpu()]\npreds = torch.cat(preds, dim=0).float()\nprint('preds', preds.shape, ', test_df',test_df.shape)\n\ndel nets\ngc.collect()\ntorch.cuda.empty_cache()\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:34.491309Z\",\"iopub.execute_input\":\"2024-08-30T21:46:34.491747Z\",\"iopub.status.idle\":\"2024-08-30T21:46:34.505341Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:34.491708Z\",\"shell.execute_reply\":\"2024-08-30T21:46:34.50417Z\"}}\nkps_ax = test_df2.copy()\nkps_ax[cfg.classes] = preds.numpy()\nkps_ax[cfg.classes].mean()\n\n# %% [markdown]\n# ## AXIAL level prediction\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:35.846725Z\",\"iopub.execute_input\":\"2024-08-30T21:46:35.847416Z\",\"iopub.status.idle\":\"2024-08-30T21:46:35.851677Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:35.84738Z\",\"shell.execute_reply\":\"2024-08-30T21:46:35.850656Z\"}}\n# derived from sagital xy\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:36.154455Z\",\"iopub.execute_input\":\"2024-08-30T21:46:36.155115Z\",\"iopub.status.idle\":\"2024-08-30T21:46:36.160352Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:36.155078Z\",\"shell.execute_reply\":\"2024-08-30T21:46:36.158976Z\"}}\nTARGETS = [f'D{i}_x' for i in range(1,6)] + [f'D{i}_y' for i in range(1,6)]\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:36.683211Z\",\"iopub.execute_input\":\"2024-08-30T21:46:36.683587Z\",\"iopub.status.idle\":\"2024-08-30T21:46:36.70734Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:36.683559Z\",\"shell.execute_reply\":\"2024-08-30T21:46:36.70618Z\"}}\ndef project_to_3d(x,y,z, df):\n\td = df.iloc[z]\n\tH, W = d.H, d.W\n\tsx, sy, sz = [float(v) for v in d.ImagePositionPatient]\n\to0, o1, o2, o3, o4, o5, = [float(v) for v in d.ImageOrientationPatient]\n\tdelx, dely = d.PixelSpacing\n\n\txx = o0 * delx * x + o3 * dely * y + sx\n\tyy = o1 * delx * x + o4 * dely * y + sy\n\tzz = o2 * delx * x + o5 * dely * y + sz\n\treturn xx,yy,zz\n\ndef project_to_3d_v2(x,y, d):\n\tsx, sy, sz = [float(v) for v in d.ImagePositionPatient]\n\to0, o1, o2, o3, o4, o5, = [float(v) for v in d.ImageOrientationPatient]\n\tdelx, dely = d.PixelSpacing\n\n\txx = o0 * delx * x + o3 * dely * y + sx\n\tyy = o1 * delx * x + o4 * dely * y + sy\n\tzz = o2 * delx * x + o5 * dely * y + sz\n\treturn xx,yy,zz\n\ndef view_to_world(sagittal_t2_point, z, sagittal_t2_df, image_size):\n\n\tH = sagittal_t2_df.iloc[0].H\n\tW = sagittal_t2_df.iloc[0].W\n\tscale_x = W / image_size\n\tscale_y = H / image_size\n\n\txxyyzz = []\n\tfor l in range(1, 6):\n\t\tx,y = sagittal_t2_point[l-1]\n\t\txx,yy,zz = project_to_3d(x*scale_x, y*scale_y, z, sagittal_t2_df)\n\t\txxyyzz.append((xx, yy, zz))\n\n\txxyyzz = np.array(xxyyzz)\n\treturn xxyyzz\n\ndef point_to_level(world_point, axial_t2_df):\n\n\t# we get closest axial slices (z) to the CSC world points\n\n\txxyyzz = world_point\n\torientation = np.array(axial_t2_df.ImageOrientationPatient.values.tolist())\n\tposition = np.array(axial_t2_df.ImagePositionPatient.values.tolist())\n\tox = orientation[:, :3]\n\toy = orientation[:, 3:]\n\toz = np.cross(ox, oy)\n\tt = xxyyzz.reshape(-1, 1, 3) - position.reshape(1, -1, 3)\n\tdis = (oz.reshape(1, -1, 3) * t).sum(-1)  # np.dot(point-s,oz)\n\tfdis = np.fabs(dis)\n\tclosest_z = fdis.argmin(-1)\n\tclosest_fdis = fdis.min(-1)\n\tclosest_df = axial_t2_df.iloc[closest_z]\n\n\tif 1:\n\t\t#<todo> hard/soft assigment, multi/single assigment\n\t\t# no assignment based on distance\n\n\t\t# allow point found in multi group\n\t\tnum_group   = len(axial_t2_df['group'].unique())\n\t\tpoint_group = axial_t2_df.group.values[fdis.argsort(-1)[:, :3]].tolist()\n\t\tpoint_group = [list(set(g)) for g in point_group]\n\t\tgroup_point = [[] for g in range(num_group)]\n\t\tfor l in range(5):\n\t\t\tfor k in point_group[l]:\n\t\t\t\tgroup_point[k].append(l)\n\t\t\t\t# print(k)\n\t\t\t\t# print(group_point[k])\n\t\t\t\t# print(group_point)\n\t\tgroup_point = [sorted(list(set(g))) for g in group_point]\n\n\tD = len(axial_t2_df)\n\tassigned_level=np.full(D,fill_value=0, dtype=int)\n\tfor group in range(num_group):\n\t\tpoint_in_this_group = np.array(group_point[group])  # np.where(closest_df['group'] == group)[0]\n\t\tslice_in_this_group = np.where(axial_t2_df['group'] == group)[0]\n\t\tif len(point_in_this_group) == 0:\n\t\t\tcontinue # unassigned, level=0\n\n\t\tlevel = point_in_this_group[fdis[point_in_this_group][:, slice_in_this_group].argmin(0)] + 1\n\t\tassigned_level[slice_in_this_group] = level\n\n\t# sor =  (fdis.argmin(0)+1)[closest_z]\n\t# closest_z= [ fdis.argmin(0)+1]\n\treturn assigned_level, closest_z, dis #dis is soft assignment\n\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:37.471404Z\",\"iopub.execute_input\":\"2024-08-30T21:46:37.472352Z\",\"iopub.status.idle\":\"2024-08-30T21:46:37.500563Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:37.472305Z\",\"shell.execute_reply\":\"2024-08-30T21:46:37.499538Z\"}}\ndef convert_to_8bit(x):\n    lower, upper = np.percentile(x, (1, 99))\n    x = np.clip(x, lower, upper)\n    x = x - np.min(x)\n    x = x / np.max(x) \n    return (x * 255).astype(\"uint8\")\n\ndef load_dicom_stack(dicom_folder, plane, reverse_sort=False, return_array=True, return_orientations=False, return_spacing=True):\n    dicom_files = glob.glob(os.path.join(dicom_folder, \"*.dcm\"))\n    dicoms = [pydicom.dcmread(f) for f in dicom_files]\n    plane = {\"sagittal\": 0, \"coronal\": 1, \"axial\": 2}[plane.lower()]\n    positions = np.asarray([float(d.ImagePositionPatient[plane]) for d in dicoms])\n    # if reverse_sort=False, then increasing array index will be from RIGHT->LEFT and CAUDAL->CRANIAL\n    # thus we do reverse_sort=True for axial so increasing array index is craniocaudal\n    idx = np.argsort(-positions if reverse_sort else positions)\n    ipp = np.asarray([d.ImagePositionPatient for d in dicoms]).astype(\"float\")[idx]\n    \n    \n    \n    out = {\"positions\": ipp}\n    if return_spacing:\n        assert len(np.unique([d.PixelSpacing for d in dicoms])) == 1\n        out[\"pixel_spacing\"] = np.asarray(dicoms[0].PixelSpacing).astype(\"float\")\n    if return_array:\n        array = [d.pixel_array.astype(\"float32\") for d in dicoms]\n        \n        #some axial have mixed res:\n        n_shapes = np.unique([a.shape for a in array],axis=0)\n        if len(n_shapes) > 1:\n            #resise to smallest shape\n            smallest_shape = n_shapes.prod(1).argmin()\n            array = [cv2.resize(a, n_shapes[smallest_shape], interpolation=cv2.INTER_CUBIC) for a in array]\n        array = np.stack(array)\n        \n        array = array[idx]\n        out['array'] = convert_to_8bit(array)\n    if return_orientations:\n        o = np.asarray([d.ImageOrientationPatient for d in dicoms]).astype(\"float\")[idx]\n        out['orientations'] = o\n    return out\n\ndef load_dicom_stacks(dicom_folders, plane, reverse_sort=False, return_array=True, return_orientations=False, return_spacing=True):\n    dicom_files = []\n    for dicom_folder in dicom_folders:\n        dicom_files += glob.glob(os.path.join(dicom_folder, \"*.dcm\"))\n    dicoms = [pydicom.dcmread(f) for f in dicom_files]\n    plane = {\"sagittal\": 0, \"coronal\": 1, \"axial\": 2}[plane.lower()]\n    positions = np.asarray([float(d.ImagePositionPatient[plane]) for d in dicoms])\n    # if reverse_sort=False, then increasing array index will be from RIGHT->LEFT and CAUDAL->CRANIAL\n    # thus we do reverse_sort=True for axial so increasing array index is craniocaudal\n    idx = np.argsort(-positions if reverse_sort else positions)\n    ipp = np.asarray([d.ImagePositionPatient for d in dicoms]).astype(\"float\")[idx]\n    \n    instance_ids = np.array([int(fn.split('/')[-1].replace('.dcm','')) for fn in dicom_files])[idx]\n    series_ids = np.array([int(fn.split('/')[-2]) for fn in dicom_files])[idx]\n    out = {\"positions\": ipp,'instance_ids':instance_ids,'series_ids':series_ids}\n    \n    if return_spacing:\n        assert len(np.unique([d.PixelSpacing for d in dicoms])) == 1\n        out[\"pixel_spacing\"] = np.asarray(dicoms[0].PixelSpacing).astype(\"float\")\n        \n    if return_array:\n        array = [d.pixel_array.astype(\"float32\") for d in dicoms]\n        \n        #some axial have mixed res:\n        n_shapes = np.unique([a.shape for a in array],axis=0)\n        if len(n_shapes) > 1:\n            #resise to smallest shape\n            smallest_shape = n_shapes.prod(1).argmin()\n            array = [cv2.resize(a, n_shapes[smallest_shape], interpolation=cv2.INTER_CUBIC) for a in array]\n        array = np.stack(array)\n        \n        array = array[idx]\n        out['array'] = convert_to_8bit(array)\n    if return_orientations:\n        o = np.asarray([d.ImageOrientationPatient for d in dicoms]).astype(\"float\")[idx]\n        out['orientations'] = o\n    return out\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:46.820509Z\",\"iopub.execute_input\":\"2024-08-30T21:46:46.820894Z\",\"iopub.status.idle\":\"2024-08-30T21:46:46.832235Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:46.820863Z\",\"shell.execute_reply\":\"2024-08-30T21:46:46.831099Z\"}}\n# convert all kps to 3d\n\ndef do_one(idx):\n    kp_row = kps_sag.iloc[idx]\n    series_id, study_id = int(kp_row['series_id']), int(kp_row['study_id'])\n    instance_number = int(kp_row['instance_number'])\n    d = pydicom.dcmread(f'{DATA_FOLDER}{study_id}/{series_id}/{instance_number}.dcm')\n    kps_3d = []\n    xy = []\n    for i in range(1,6):\n        x = kp_row[f'D{i}_x'] * d.Columns\n        y = kp_row[f'D{i}_y'] * d.Rows\n        xyz = project_to_3d_v2(x,y, d)\n        xy += [(x,y)]\n        kps_3d += [xyz]\n    kps_3d = np.array(kps_3d)\n    \n    return kps_3d.T.reshape(-1)\n\n# %% [code]\n\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:47.140334Z\",\"iopub.execute_input\":\"2024-08-30T21:46:47.141264Z\",\"iopub.status.idle\":\"2024-08-30T21:46:47.327044Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:47.141226Z\",\"shell.execute_reply\":\"2024-08-30T21:46:47.325644Z\"}}\nwith mp.Pool(N_CORES) as p:\n    res = list(tqdm(p.imap(do_one, range(len(kps_sag))),total=kps_sag.shape[0]))\nres = np.array(res)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:46:50.178193Z\",\"iopub.execute_input\":\"2024-08-30T21:46:50.179147Z\",\"iopub.status.idle\":\"2024-08-30T21:46:50.247177Z\",\"shell.execute_reply.started\":\"2024-08-30T21:46:50.179103Z\",\"shell.execute_reply\":\"2024-08-30T21:46:50.24612Z\"}}\nkps3d = kps_sag.drop([f'D{i}_x' for i in range(1,6)] + [f'D{i}_y' for i in range(1,6)], axis=1).copy()\n\nnew_cols = [f'D{i}_x' for i in range(1,6)] + [f'D{i}_y' for i in range(1,6)]+ [f'D{i}_z' for i in range(1,6)]\nxyz = pd.DataFrame(res, columns=new_cols)\nkps3d = pd.concat([kps3d,xyz],axis=1)\nkps3d\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:00.131578Z\",\"iopub.execute_input\":\"2024-08-30T21:47:00.132004Z\",\"iopub.status.idle\":\"2024-08-30T21:47:00.142838Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:00.131963Z\",\"shell.execute_reply\":\"2024-08-30T21:47:00.141828Z\"}}\ndef do_one(study_id):\n    ax_series = df_ax[df_ax['study_id']==study_id]['series_id'].values\n    dicom_folders = [f'{DATA_FOLDER}{study_id}/{s}/' for s in ax_series]\n    ax_dicoms = load_dicom_stacks(dicom_folders, 'axial', reverse_sort=True,return_array=False,return_orientations=True,return_spacing=False)\n\n    xxyyzz= kps3d[kps3d['study_id']==study_id].groupby('study_id')[new_cols].agg('median').values.reshape(3,5).T\n    orientation = ax_dicoms['orientations']\n    position = ax_dicoms['positions']\n    ox = orientation[:, :3]\n    oy = orientation[:, 3:]\n    oz = np.cross(ox, oy)\n\n    t = xxyyzz.reshape(-1, 1, 3) - position.reshape(1, -1, 3)\n    dis = (oz.reshape(1, -1, 3) * t).sum(-1)  # np.dot(point-s,oz)\n    fdis = np.fabs(dis)\n    closest_z = fdis.argmin(-1)\n    closest_fdis = fdis.min(-1)\n\n    labels = fdis.argmin(0)\n    image_ids = []\n    mask = fdis.min(0) < 30\n    \n    pred_df = pd.DataFrame({'series_id':ax_dicoms['series_ids'],'instance_id':ax_dicoms['instance_ids']})\n    pred_df[LEVELS] = fdis.T\n    return pred_df\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:02.512643Z\",\"iopub.execute_input\":\"2024-08-30T21:47:02.513474Z\",\"iopub.status.idle\":\"2024-08-30T21:47:02.518636Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:02.513438Z\",\"shell.execute_reply\":\"2024-08-30T21:47:02.517449Z\"}}\nstudy_ids = df_ax['study_id'].unique()\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:03.017913Z\",\"iopub.execute_input\":\"2024-08-30T21:47:03.018634Z\",\"iopub.status.idle\":\"2024-08-30T21:47:03.027362Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:03.018603Z\",\"shell.execute_reply\":\"2024-08-30T21:47:03.026347Z\"}}\nstudy_ids2 = np.intersect1d(study_ids,kps3d['study_id'].unique())\nlen(study_ids), len(study_ids2)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:03.947788Z\",\"iopub.execute_input\":\"2024-08-30T21:47:03.948978Z\",\"iopub.status.idle\":\"2024-08-30T21:47:04.186229Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:03.94891Z\",\"shell.execute_reply\":\"2024-08-30T21:47:04.184706Z\"}}\nwith mp.Pool(N_CORES) as p:\n    res = list(tqdm(p.imap(do_one, study_ids2), total=len(study_ids2)))\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:04.18903Z\",\"iopub.execute_input\":\"2024-08-30T21:47:04.189801Z\",\"iopub.status.idle\":\"2024-08-30T21:47:04.222548Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:04.189755Z\",\"shell.execute_reply\":\"2024-08-30T21:47:04.221296Z\"}}\nax_level_df = pd.concat(res).reset_index(drop=True)\nax_level_df\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:09.440473Z\",\"iopub.execute_input\":\"2024-08-30T21:47:09.440891Z\",\"iopub.status.idle\":\"2024-08-30T21:47:09.446355Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:09.440858Z\",\"shell.execute_reply\":\"2024-08-30T21:47:09.445376Z\"}}\nLEVELS = ['l1_l2','l2_l3','l3_l4','l4_l5','l5_s1']\nAX_CROPS_FOLDER = 'crops_roi_ax/'\nIMG_SIZE = 512\nCROP_SIZE = 112\nos.makedirs(AX_CROPS_FOLDER)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:09.702635Z\",\"iopub.execute_input\":\"2024-08-30T21:47:09.703064Z\",\"iopub.status.idle\":\"2024-08-30T21:47:09.707539Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:09.703031Z\",\"shell.execute_reply\":\"2024-08-30T21:47:09.706484Z\"}}\n# study_ids = df_ax['study_id'].unique()\n# study_id = study_ids[0]\n# study_id\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:11.845863Z\",\"iopub.execute_input\":\"2024-08-30T21:47:11.84667Z\",\"iopub.status.idle\":\"2024-08-30T21:47:11.861305Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:11.846632Z\",\"shell.execute_reply\":\"2024-08-30T21:47:11.860193Z\"}}\n#add study_ids\nax_level_df = ax_level_df.merge(test_df[['series_id','study_id']].drop_duplicates(), on='series_id', how='left')\nax_level_df = ax_level_df.rename(columns={'instance_id':'instance_number'})\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:12.117136Z\",\"iopub.execute_input\":\"2024-08-30T21:47:12.117804Z\",\"iopub.status.idle\":\"2024-08-30T21:47:12.126982Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:12.117772Z\",\"shell.execute_reply\":\"2024-08-30T21:47:12.125705Z\"}}\nkps_ax['id'] = kps_ax['series_id'].astype(str) + '_' + kps_ax['instance_number'].astype(str)\nkps_ax = kps_ax.set_index('id')\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:20.14109Z\",\"iopub.execute_input\":\"2024-08-30T21:47:20.142002Z\",\"iopub.status.idle\":\"2024-08-30T21:47:20.162041Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:20.141967Z\",\"shell.execute_reply\":\"2024-08-30T21:47:20.160867Z\"}}\ndef do_one(study_id):\n    ax_series = df_ax[df_ax['study_id']==study_id]['series_id'].values\n    dicom_folders = [f'{DATA_FOLDER}{study_id}/{s}/' for s in ax_series]\n    ax_dicoms = load_dicom_stacks(dicom_folders, 'axial', reverse_sort=True,return_array=True,return_orientations=True,return_spacing=False)\n\n    label_df = ax_level_df[ax_level_df['series_id'].isin(ax_series)].set_index(['series_id','instance_number'])\n    idx = [(a,b) for a,b in zip(ax_dicoms['series_ids'],ax_dicoms['instance_ids'])]\n    label_df = label_df.loc[idx]\n    \n    labels = label_df[LEVELS].values.argmin(1)\n    image_ids = []\n    mask = label_df[LEVELS].values.min(1) < 20 #85 % all slices\n    \n    for l in np.unique(labels):\n        \n        slice_ids = np.where((labels == l)& mask)[0]\n        if len(slice_ids) > 0:\n            image_id = f'{study_id}_{LEVELS[l]}'\n            img = ax_dicoms['array'][slice_ids]\n            img = cv2.resize(img.transpose(1,2,0), (IMG_SIZE, IMG_SIZE), interpolation=cv2.INTER_CUBIC)#.transpose(2,0,1)\n            if len(img.shape) == 2:\n                img = img[:,:,None]\n            img = img.transpose(2,0,1)\n\n            series_ids = ax_dicoms['series_ids'][slice_ids]\n            instance_ids = ax_dicoms['instance_ids'][slice_ids]\n            kp_ids = np.array([f'{s}_{i}' for s,i in zip(series_ids,instance_ids)])\n\n            xy_normed_l = kps_ax.loc[kp_ids][['x1','y1']].median().values\n            xyl = xy_normed_l * img.shape[1:][::-1]\n            xy_normed_r = kps_ax.loc[kp_ids][['x2','y2']].median().values\n            xyr = xy_normed_r * img.shape[1:][::-1]\n\n#             xmin3 = (min(xyr[0],xyl[0]) - 100)\n#             xmax3 = (max(xyr[0],xyl[0]) + 100).clip(0,IMG_SIZE)\n#             xmin3 = xmin3.clip(0,IMG_SIZE-(xmax3-xmin3))\n            \n#             ymin3 = (min(xyr[1],xyl[1])-112//2)\n#             ymax3 = (max(xyr[1],xyl[1])+112//2).clip(0,IMG_SIZE)\n#             ymin3 = ymin3.clip(0,IMG_SIZE-(ymax3-ymin3))\n\n            xmin3 = (0.5*xyr[0]+0.5*xyl[0] - 224 // 2).clip(0,IMG_SIZE-224)\n            xmax3 = (max(xyr[0],xyl[0]) + 100).clip(0,IMG_SIZE)\n            xmax3 = xmin3 + 224\n            xmin3 = xmin3.clip(0,IMG_SIZE-(xmax3-xmin3))\n            ymin3 = (0.5*xyr[1]+0.5*xyl[1] - 112 // 2).clip(0,IMG_SIZE-112)\n            ymax3 = ymin3 + 112\n\n            bbc = np.array([xmin3,xmax3,ymin3,ymax3]).astype(int)\n\n            imgc = img[:,bbc[2]:bbc[3],bbc[0]:bbc[1]]\n\n            np.save(f'{AX_CROPS_FOLDER}{image_id}.npy',imgc)\n            image_ids += [image_id]\n    return image_ids\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:20.739899Z\",\"iopub.execute_input\":\"2024-08-30T21:47:20.742157Z\",\"iopub.status.idle\":\"2024-08-30T21:47:20.750187Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:20.742121Z\",\"shell.execute_reply\":\"2024-08-30T21:47:20.749009Z\"}}\nstudy_ids2 = np.intersect1d(study_ids,ax_level_df['study_id'].unique())\nlen(study_ids), len(study_ids2)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:21.899795Z\",\"iopub.execute_input\":\"2024-08-30T21:47:21.901Z\",\"iopub.status.idle\":\"2024-08-30T21:47:22.682193Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:21.900929Z\",\"shell.execute_reply\":\"2024-08-30T21:47:22.680896Z\"}}\nwith mp.Pool(N_CORES) as p:\n    res = list(tqdm(p.imap(do_one, study_ids2), total=len(study_ids2)))\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:25.859886Z\",\"iopub.execute_input\":\"2024-08-30T21:47:25.860884Z\",\"iopub.status.idle\":\"2024-08-30T21:47:25.881225Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:25.860847Z\",\"shell.execute_reply\":\"2024-08-30T21:47:25.880132Z\"}}\ntest_df_ax_lvl = pd.DataFrame([x for sublist in res for x in sublist],columns=['image_id'])\ntest_df_ax_lvl['level'] = test_df_ax_lvl['image_id'].apply(lambda x: '_'.join(x.split('_')[1:]))\ntest_df_ax_lvl['study_id'] = test_df_ax_lvl['image_id'].apply(lambda x: x.split('_')[0])\n#dummy labels \ntest_df_ax_lvl['left_subarticular_stenosis'] = 'Normal/Mild'\ntest_df_ax_lvl['right_subarticular_stenosis'] = 'Normal/Mild'\ntest_df_ax_lvl.head()\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:28.566688Z\",\"iopub.execute_input\":\"2024-08-30T21:47:28.567634Z\",\"iopub.status.idle\":\"2024-08-30T21:47:28.573817Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:28.567598Z\",\"shell.execute_reply\":\"2024-08-30T21:47:28.572822Z\"}}\ntest_df_ax_lvl['series_id'] = -1\ntest_df_ax_lvl['series_description'] = 'Axial T2'\ntest_df_sag_lvl['series_id'] = test_df_sag_lvl['series_id'].astype(int)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:28.755181Z\",\"iopub.execute_input\":\"2024-08-30T21:47:28.755599Z\",\"iopub.status.idle\":\"2024-08-30T21:47:28.795059Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:28.755566Z\",\"shell.execute_reply\":\"2024-08-30T21:47:28.793878Z\"}}\n\n\ntest_df_sag_lvl = test_df_sag_lvl.merge(test_df[['series_id','study_id','series_description']].drop_duplicates(),how='left',on='series_id')\n\n\ntest_df_stg2 = pd.concat([test_df_sag_lvl,test_df_ax_lvl])\ntest_df_stg2['study_id'] = test_df_stg2['study_id'].astype(int)\ntest_df_stg2 = test_df_stg2.merge(test_df[['study_id','fold']].drop_duplicates(),how='left',on='study_id')\ntest_df_stg2\n\n# %% [code]\n\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:32.01201Z\",\"iopub.execute_input\":\"2024-08-30T21:47:32.012395Z\",\"iopub.status.idle\":\"2024-08-30T21:47:32.039383Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:32.012366Z\",\"shell.execute_reply\":\"2024-08-30T21:47:32.038564Z\"}}\nname = 'cfg_ch_35'\ncfg = get_cfg(name)\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:34.5244Z\",\"iopub.execute_input\":\"2024-08-30T21:47:34.524762Z\",\"iopub.status.idle\":\"2024-08-30T21:47:34.567307Z\",\"shell.execute_reply.started\":\"2024-08-30T21:47:34.524735Z\",\"shell.execute_reply\":\"2024-08-30T21:47:34.566326Z\"}}\n# name = 'cfg_ch_12d4'\n# cfg = get_cfg(name)\ncfg.data_folder = SAG_CROPS_FOLDER\ncfg.data_folder_s2 = SAG_CROPS_FOLDER\ncfg.data_folder_ax = AX_CROPS_FOLDER\n# cfg.train_df = '/mount/rsna24/data/train_stg2_st1st2ax_v7.csv'\n\n\n\nstate_dict_fps = sorted(glob.glob(f'/kaggle/input/weights-rsna24-cfg-ch-35/*/*check*', recursive = True))\n\nif OOF_CHECK:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold{FOLD}/' in fp]\n\n# test_dl, batch_to_device = get_dl(cfg)\nds = importlib.import_module(cfg.dataset)\nimportlib.reload(ds)\n\nCustomDataset = ds.CustomDataset\nbatch_to_device = ds.batch_to_device\n\ntest_ds = CustomDataset(test_df_stg2, cfg, cfg.val_aug, mode=\"test\")\ntest_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=True)\nprint('\\n'.join(state_dict_fps))\n\n# %% [code] {\"execution\":{\"iopub.status.busy\":\"2024-08-30T21:47:39.785165Z\",\"iopub.execute_input\":\"2024-08-30T21:47:39.785571Z\"}}\nnets = get_nets(cfg,state_dict_fps)\n\n# %% [code]\npreds = []\nwith torch.inference_mode():\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch,DEVICE)\n        outs = [net(batch) for net in nets]\n        preds += [torch.stack([out['logits'] for out in outs], dim=0).mean(0).cpu()]\npreds = torch.cat(preds, dim=0).float()\nprint('preds', preds.shape, ', test_df',test_df.shape)\n\ndel nets\ngc.collect()\ntorch.cuda.empty_cache()\n\n# %% [code]\n# preds = preds.softmax(-1)\npreds2 = preds.reshape(preds.shape[0],5,5,3).permute(0,2,1,3).reshape(preds.shape[0], 25, 3)\n\n# %% [code]\n\n\n# %% [code]\nTC2 = ['spinal_canal_stenosis',\n    'left_neural_foraminal_narrowing',\n 'right_neural_foraminal_narrowing',\n 'left_subarticular_stenosis',\n 'right_subarticular_stenosis']\n\n# %% [code]\n# levels = np.array(np.array(LEVELS)).repeat(len(cfg.target_columns))[:,None].repeat(test_dl.dataset.ids.shape[0],1).T.reshape(-1)\n# conditions = np.array(cfg.target_columns * test_dl.dataset.ids.shape[0] * 5)\n# pred_df = pd.DataFrame({'study_id':test_dl.dataset.ids[:,None].repeat(25,1).reshape(-1),'condition':conditions,'level':levels,})\n# pred_val_df= pd.DataFrame(preds2.reshape(-1,3),columns=[c.lower().replace('/','_') for c in cfg.classes])\n# pred_df = pd.concat([pred_df,pred_val_df],axis=1)\n# pred_df['row_id'] = pred_df['study_id'].astype(str) + '_' + pred_df['condition'].astype(str) + '_' + pred_df['level'].astype(str)\n# pred_df = pred_df.sort_values('row_id').reset_index(drop=True)\n# pred_df_cfg_35 = pred_df.copy()\n# pred_df_cfg_35\n\n# %% [code]\nlevels = np.array(np.array(LEVELS)).repeat(len(TC2))[:,None].repeat(test_dl.dataset.ids.shape[0],1).T.reshape(-1)\nconditions = np.array(TC2 * test_dl.dataset.ids.shape[0] * 5)\npred_df = pd.DataFrame({'study_id':test_dl.dataset.ids[:,None].repeat(25,1).reshape(-1),'condition':conditions,'level':levels,})\npred_val_df= pd.DataFrame(preds2.reshape(-1,3),columns=[c.lower().replace('/','_') for c in cfg.classes])\npred_df = pd.concat([pred_df,pred_val_df],axis=1)\npred_df['row_id'] = pred_df['study_id'].astype(str) + '_' + pred_df['condition'].astype(str) + '_' + pred_df['level'].astype(str)\npred_df = pred_df.sort_values('row_id').reset_index(drop=True)\npred_df_cfg_35 = pred_df.copy()\npred_df_cfg_35\n\n# %% [code]\nname = 'cfg_ch_1i9'\ncfg = get_cfg(name)\n\n\nstate_dict_fps = sorted(glob.glob(f'/kaggle/input/weights-rsna24-cfg-ch-1i9/*/*check*', recursive = True))\n\nif OOF_CHECK:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold{FOLD}/' in fp]\n\ntest_dl, batch_to_device = get_dl(cfg)\nprint('\\n'.join(state_dict_fps))\n\n# %% [code]\nnets = get_nets(cfg,state_dict_fps)\n\n\n# %% [code]\npreds = []\nwith torch.inference_mode():\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch,DEVICE)\n        outs = [net(batch) for net in nets]\n        preds += [torch.stack([out['logits'] for out in outs], dim=0).mean(0).cpu()]\npreds = torch.cat(preds, dim=0).float()\n\nprint('preds', preds.shape, ', test_df',test_df.shape)\n\nprint(cfg.target_columns)\n\ndel nets\ngc.collect()\ntorch.cuda.empty_cache()\n\n# %% [code]\ndata = []\nfor i, s in tqdm(enumerate(test_dl.dataset.study_ids)):\n    for j,c in enumerate(cfg.target_columns):\n        data += [(f'{s}_{c}',)+ tuple(preds[i,:,j].cpu().numpy())]  # .softmax(0)\npred_df = pd.DataFrame(data, columns= 'row_id\tnormal_mild\tmoderate\tsevere'.split())\npred_df\n\n# %% [code]\npred_df = pred_df.set_index('row_id')\npred_df_cfg_35 = pred_df_cfg_35.set_index('row_id')\n\n# %% [code]\npred_df.head(20)\n\n# %% [code]\npred_df.loc[pred_df_cfg_35.index,'normal_mild\tmoderate\tsevere'.split()] = pred_df_cfg_35['normal_mild\tmoderate\tsevere'.split()].values\n\n# %% [code]\npred_df.head(20)\n\n# %% [code]\npred_df = pred_df.reset_index()\n\n# %% [code]\nif RAM_CHECK + OOF_CHECK + DEBUG== 0:\n    #sort same as sample sub\n    pred_df = pred_df.set_index('row_id')\n    pred_df = pred_df.loc[sample_submission['row_id'].values].reset_index()\n    #optional fill bad preds with sample sub \n    pred_df\n\n# %% [code]\npred_df.to_csv('logits_dieter.csv',index=False)\n\n# %% [code]\nshutil.rmtree(SAG_CROPS_FOLDER)\nshutil.rmtree(AX_CROPS_FOLDER)\n\n# %% [code]\n","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:36:11.902613Z","iopub.execute_input":"2024-10-07T18:36:11.902914Z","iopub.status.idle":"2024-10-07T18:38:08.521437Z","shell.execute_reply.started":"2024-10-07T18:36:11.902887Z","shell.execute_reply":"2024-10-07T18:38:08.520624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Darragh","metadata":{}},{"cell_type":"code","source":"!pip install -r /kaggle/input/github-rsna24/requirements_ngc.txt --no-index --find-links=file:/kaggle/input/rsna24-pip-packages\n    \nimport sys\nsys.path.append('/kaggle/input/github-rsna24/configs')\nsys.path.append('/kaggle/input/github-rsna24/data')\nsys.path.append('/kaggle/input/github-rsna24/models')\nsys.path.append('/kaggle/input/github-rsna24/postprocess')\nsys.path.append('/kaggle/input/github-rsna24/metrics')\nsys.path.append('/kaggle/input/github-rsna24/')\n\n\nimport numpy as np\nimport pandas as pd\nimport scipy as sp\nimport os\nimport json\nimport sys\nimport importlib\nimport multiprocessing as mp\nimport pydicom\nimport gc\nfrom tqdm import tqdm\nimport glob\nimport torch\nfrom copy import copy\nfrom torch.utils.data import DataLoader\nfrom pathlib import Path\nimport cv2\nfrom multiprocessing import Pool, cpu_count\nfrom tqdm import tqdm\nimport warnings\nfrom PIL import Image\nimport collections\nfrom utils_dh import apply_windowing, process_file, project_to_3d, view_to_world, point_to_level2, score_from_train\nfrom metrics.metric_dh_02 import StudyLoss\n#from pp_dh_02b import post_process_pipeline\nfrom pp_dh_03 import post_process_pipeline\nwarnings.filterwarnings(\"ignore\")","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-10-07T18:38:08.523259Z","iopub.execute_input":"2024-10-07T18:38:08.523717Z","iopub.status.idle":"2024-10-07T18:38:24.395139Z","shell.execute_reply.started":"2024-10-07T18:38:08.523682Z","shell.execute_reply":"2024-10-07T18:38:24.394295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_cfg(CFG):\n    cfg = importlib.import_module('default_config')\n    importlib.reload(cfg)\n    cfg = importlib.import_module(CFG)\n    importlib.reload(cfg)\n    cfg = copy(cfg.cfg)\n#     cfg.post_process_pipeline = importlib.import_module(cfg.post_process_pipeline).post_process_pipeline\n\n    cfg.data_dir = COMP_FOLDER\n    cfg.data_folder = DATA_FOLDER\n    cfg.mixed_precision = MIXED_PRECISION\n    cfg.pretrained = False\n    cfg.pretrained_weights = False\n#     cfg.batch_size = 2\n    cfg.offline_inference = True\n\n#     print(CFG, cfg.model, cfg.dataset, cfg.backbone, cfg.tokenizer, cfg.pretrained_weights, cfg.post_process_pipeline)\n    \n    return cfg\n\ndef get_dl(cfg, mode = 'test'):\n    ds = importlib.import_module(cfg.dataset)\n    importlib.reload(ds)\n\n    CustomDataset = ds.CustomDataset\n    batch_to_device = ds.batch_to_device\n\n    test_ds = CustomDataset(test_df, cfg, cfg.val_aug, mode=mode)\n    test_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=True)\n\n    return test_dl, batch_to_device\n\ndef get_state_dict(sd_fp):\n    sd = torch.load(sd_fp, map_location=\"cpu\")\n    if \"model\" in sd.keys():\n        sd = sd[\"model\"]\n    sd = {k.replace(\"module.\", \"\"):v for k,v in sd.items()}\n    return sd\n\ndef get_nets(cfg,state_dicts):\n    model = importlib.import_module(cfg.model)\n    importlib.reload(model)\n    Net = model.Net\n    nets = []\n    for i,state_dict in enumerate(state_dicts):\n        net = Net(cfg).eval().to(DEVICE)\n        print(\"loading dict\")\n        sd = get_state_dict(state_dict)\n\n        net.load_state_dict(sd, strict=True)\n        net.is_test = True\n        nets += [net]\n        del sd\n        gc.collect()\n    return nets\n\n\ndef apply_windowing_v04(dcm, norm_val = 255):\n    pixel_data = dcm.pixel_array\n    pixel_data_windowed2 = pixel_data.copy()\n    min_int = np.quantile(pixel_data_windowed2, 0.005)\n    max_int = np.quantile(pixel_data_windowed2, 0.995)\n    pixel_data_windowed2[pixel_data < min_int] = min_int\n    pixel_data_windowed2[pixel_data > max_int] = max_int\n    pixel_data_windowed2 = (pixel_data_windowed2/(max_int/255)).round().astype(np.uint8)\n    Image.fromarray(pixel_data_windowed2)\n    return pixel_data_windowed2\n\n\ndef dicom2jpg(fnm, version=1):\n    fpath = Path(fnm)\n    dcm_dir = str(fpath.parent)\n    dcmfile = fnm\n    dcm = pydicom.dcmread(dcmfile)\n    \n    jpeg_dir = dcm_dir.replace(DATA_FOLDER, IMAGE_FOLDER)\n    Path(jpeg_dir).mkdir(parents=True, exist_ok=True)\n    img = apply_windowing(dcm)\n    jpeg_nm = f\"{jpeg_dir}/{fpath.stem}.jpeg\"\n    cv2.imwrite(jpeg_nm, img)\n    \n    jpeg_dir = dcm_dir.replace(DATA_FOLDER, IMAGE_FOLDER4)\n    Path(jpeg_dir).mkdir(parents=True, exist_ok=True)\n    img = apply_windowing_v04(dcm)\n    jpeg_nm = f\"{jpeg_dir}/{fpath.stem}.jpeg\"\n    cv2.imwrite(jpeg_nm, img)\n    ","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-10-07T18:38:24.396373Z","iopub.execute_input":"2024-10-07T18:38:24.396812Z","iopub.status.idle":"2024-10-07T18:38:24.414379Z","shell.execute_reply.started":"2024-10-07T18:38:24.396782Z","shell.execute_reply":"2024-10-07T18:38:24.413425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"COMP_FOLDER = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/'\n\n# train_df = pd.read_csv(COMP_FOLDER + 'train.csv')\n# test_df = pd.read_csv(COMP_FOLDER + 'test.csv')\nsample_submission = pd.read_csv(COMP_FOLDER + 'sample_submission.csv')\ntest_series_descriptions = pd.read_csv(COMP_FOLDER + 'test_series_descriptions.csv')\n\nPUBLIC_RUN = test_series_descriptions.shape[0] == 3\n\nN_CORES = mp.cpu_count()\nMIXED_PRECISION = False\n\nRAM_CHECK = False\nOOF_CHECK = False\nOOF_FOLD = 1\n\n# assert (RAM_CHECK + OOF_CHECK) <= 1\n\nDEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'\n\nif PUBLIC_RUN is False:\n    RAM_CHECK = False\n    OOF_CHECK = False\n    \n\nif OOF_CHECK:\n    N_STUDIES = 500\n    DATA_FOLDER = COMP_FOLDER + 'train_images/'\n    IMAGE_FOLDER = './train_images_v01/'\n    IMAGE_FOLDER4 = './train_images_v04/'\n    test_df = pd.read_csv('/kaggle/input/aws-bucket-rsna24/train_folded_v2.csv')\n    test_df = test_df[test_df['fold']==OOF_FOLD].copy()#.head(40)\n    test_df = test_df[test_df.study_id.isin(test_df.study_id.unique())]\n    test_series_descriptions = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv')\n    LEVELS = ['l1_l2','l2_l3','l3_l4','l4_l5','l5_s1']\n\n    \nelif RAM_CHECK:\n    DATA_FOLDER = COMP_FOLDER + 'train_images/'\n    IMAGE_FOLDER = './train_images_v01/'\n    IMAGE_FOLDER4 = './train_images_v04/'\n    test_df = pd.read_csv('/kaggle/input/aws-bucket-rsna24/train_folded_v2.csv')\n    N_STUDIES = 1000\n    test_df = test_df[test_df.study_id.isin(test_df.study_id.unique()[:N_STUDIES])]\n    test_series_descriptions = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv')\n    LEVELS = ['l1_l2','l2_l3','l3_l4','l4_l5','l5_s1']\nelse:\n    #create dummy test file\n    LEVELS = ['l1_l2','l2_l3','l3_l4','l4_l5','l5_s1']\n    TARGET_COLS = [f'spinal_canal_stenosis_{l}' for l in LEVELS] \n    TARGET_COLS += [f'left_neural_foraminal_narrowing_{l}' for l in LEVELS] \n    TARGET_COLS += [f'right_neural_foraminal_narrowing_{l}' for l in LEVELS] \n    TARGET_COLS += [f'left_subarticular_stenosis_{l}' for l in LEVELS] \n    TARGET_COLS += [f'right_subarticular_stenosis_{l}' for l in LEVELS] \n    study_ids = test_series_descriptions['study_id'].unique()\n    test_df = pd.DataFrame({'study_id':study_ids})\n    test_df[TARGET_COLS] = 'Normal/Mild'\n    test_df['fold'] = 0\n    test_df =test_df.merge(test_series_descriptions, how='right', on='study_id')\n    DATA_FOLDER = COMP_FOLDER + 'test_images/'\n    IMAGE_FOLDER = './test_images_v01/'\n    IMAGE_FOLDER4 = './test_images_v04/'\n    \n    \ntest_df.to_csv('test_df.csv', index = False)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:38:24.418082Z","iopub.execute_input":"2024-10-07T18:38:24.418349Z","iopub.status.idle":"2024-10-07T18:38:24.492718Z","shell.execute_reply.started":"2024-10-07T18:38:24.418327Z","shell.execute_reply":"2024-10-07T18:38:24.491841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fnmls = sorted(glob.glob(f\"{DATA_FOLDER}/*/*/*\"))\nstudy_check_list = set(test_df.study_id.tolist())\n\nfnmls = [f for f in fnmls if int(str(Path(f)).split('/')[-3]) in study_check_list]\n\n# Create a pool of processes\nwith Pool(cpu_count()) as p:\n    max_ = len(fnmls)\n    with tqdm(total=max_) as pbar:\n        for _ in p.imap_unordered(dicom2jpg, fnmls):\n            pbar.update()\n            \n            \nn_study = len(glob.glob(f\"{IMAGE_FOLDER}/*\"))\nprint(f\"Number of studies 1: {n_study}\")\nn_study = len(glob.glob(f\"{IMAGE_FOLDER4}/*\"))\nprint(f\"Number of studies 4: {n_study}\")\ngc.collect()\n\nwith Pool(cpu_count()) as p:\n    metals = list(tqdm(p.imap(process_file, fnmls), total=len(fnmls)))\n\nmetadf = pd.DataFrame(metals).sort_values('series_id instance_number'.split())\nmetadf['instance_number'] = metadf.instance_number.astype(int)\ndel  metals\ngc.collect()\nmetadf.to_pickle(\"meta_v1.pkl\")\nprint(metadf.dtypes)\nmetadf.head(10)\n\ncoorddf = metadf['series_id instance_number img_w\timg_h'.split()].drop_duplicates().reset_index(drop = True)\ncoorddfls = []\nfor t, c in enumerate([\"Right Subarticular Stenosis\", \"Left Subarticular Stenosis\"]):\n    coorddfls.append(coorddf.copy())\n    coorddfls[-1]['condition level'.split()] = c, 'l1_l2'\n    dims = coorddfls[-1]['img_w img_h'.split()].values\n    coorddfls[-1]['x y'.split()] = dims // 3 + (t * dims) // 10\ncoorddf = pd.concat(coorddfls)\ncoorddf.to_csv('dummy_coordinates.csv.gz')","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:38:24.493714Z","iopub.execute_input":"2024-10-07T18:38:24.493960Z","iopub.status.idle":"2024-10-07T18:38:26.422151Z","shell.execute_reply.started":"2024-10-07T18:38:24.493938Z","shell.execute_reply":"2024-10-07T18:38:26.420978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Axial location - cfg_dh_05b5_loc_test","metadata":{}},{"cell_type":"code","source":"name = 'cfg_dh_05b5_loc_test'\ncfg = get_cfg(name)\n#cfg.full_test_set = False\ncfg.coord_df = 'dummy_coordinates.csv.gz'\ncfg.image_folder = IMAGE_FOLDER\ncfg.dicom_folder = DATA_FOLDER\nstate_dict_fps = sorted(glob.glob(f'/kaggle/input/weights-rsna24-cfg-dh-05b5-loc/**/*check*', recursive = True))\nfull_test_set = False\nif OOF_CHECK:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold{OOF_FOLD}/' in fp]\nelse:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold-1/' in fp]\nstate_dict_fps\n\n# test_dl, batch_to_device = get_dl(cfg)\nds = importlib.import_module(cfg.dataset)\nimportlib.reload(ds)\n\nCustomDataset = ds.CustomDataset\nbatch_to_device = ds.batch_to_device\n\ntest_ds = CustomDataset(test_df, cfg, cfg.val_aug, mode=\"test\")\ntest_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=True)\nprint('\\n'.join(state_dict_fps))\n\nnets = get_nets(cfg,state_dict_fps)\n\n\noutd = collections.defaultdict(list)\nwith torch.inference_mode():\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch,DEVICE)\n        outs = [net(batch) for net in nets]\n        outd['preds'] += [torch.stack([out['logits'] for out in outs], dim=0).mean(0).cpu()]\n        outd['series_id'] += [batch['series_id'].cpu()]\n        outd['instance_number'] += [batch['instance_numbers'].cpu()]\nfor k in \"preds series_id instance_number\".split(): \n    outd[k] = torch.cat(outd[k], dim=0)\nlocdf = pd.DataFrame({k: outd[k].numpy() for k in \"series_id instance_number\".split()})\nlocdf[cfg.classes] = outd['preds'].numpy()\nlocdf.to_csv('cfg_dh_05b5_loc_test.csv.gz', index = False)\nlocdf.head(8)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:38:26.423808Z","iopub.execute_input":"2024-10-07T18:38:26.424466Z","iopub.status.idle":"2024-10-07T18:38:55.109674Z","shell.execute_reply.started":"2024-10-07T18:38:26.424428Z","shell.execute_reply":"2024-10-07T18:38:55.108463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Sagittal location - cfg_dh_14p2_locsag_test","metadata":{}},{"cell_type":"code","source":"# Dummy coorddf\ncoord_df  = {'instance_number': {0: 3, 1: 3, 2: 3, 3: 4, 4: 4},\n                 'series_id': {0: 10996, 1: 10996, 2: 10996, 3: 10996, 4: 10996},\n                 'level': {0: 'l3_l4', 1: 'l4_l5', 2: 'l5_s1', 3: 'l2_l3', 4: 'l3_l4'},\n                 'x': {0: 244, 1: 246, 2: 252, 3: 253, 4: 249},\n                 'y': {0: 247, 1: 288, 2: 319, 3: 207, 4: 250}}\ncoord_df = pd.DataFrame(coord_df)\ncoord_df.to_csv('dummy_coordf.csv.gz', index = False)\n\nname = 'cfg_dh_14p2_locsag_test'\ncfg = get_cfg(name)\n#cfg.full_test_set = False\ncfg.coord_df = 'dummy_coordf.csv.gz'\ncfg.image_folder = IMAGE_FOLDER\ncfg.dicom_folder = DATA_FOLDER\nstate_dict_fps = sorted(glob.glob(f'/kaggle/input/weights-rsna24-cfg-dh-14p2-locsag-2/**/*check*', recursive = True))\nfull_test_set = False\nif OOF_CHECK:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold{OOF_FOLD}/' in fp]\nelse:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold-1/' in fp]\n    \nstate_dict_fps\n\n# test_dl, batch_to_device = get_dl(cfg)\nds = importlib.import_module(cfg.dataset)\nimportlib.reload(ds)\n\nCustomDataset = ds.CustomDataset\nbatch_to_device = ds.batch_to_device\n\ntest_ds = CustomDataset(test_df, cfg, cfg.val_aug, mode=\"test\")\ntest_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=True)\nprint('\\n'.join(state_dict_fps))\n\nnets = get_nets(cfg,state_dict_fps)\n\n\noutd = collections.defaultdict(list)\nwith torch.inference_mode():\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch,DEVICE)\n        outs = [net(batch) for net in nets]\n        outd['logits'] += [torch.stack([out['logits'] for out in outs], dim=0).mean(0).cpu()]\n        outd['logits_mask'] += [torch.stack([out['logits_mask'] for out in outs]).mean(0).cpu().flatten()]\n        outd['series_id'] += [batch['series_id'].cpu()]\n        outd['instance_number'] += [batch['instance_numbers'].cpu()]\nfor k in \"series_id instance_number logits logits_mask\".split(): \n    outd[k] = torch.cat(outd[k], dim=0)\nlocdf = pd.DataFrame({k: outd[k].numpy() for k in \"series_id instance_number logits_mask\".split()})\nlocdf[cfg.classes] = outd['logits'].numpy()\nlocdf = locdf.groupby('series_id instance_number'.split())[['logits_mask'] + cfg.classes].mean().reset_index()\nlocdf = locdf.sort_values('series_id\tinstance_number'.split()).reset_index(drop = True)\nlocdf = pd.merge(locdf, test_df['study_id series_id'.split()].drop_duplicates(), on = 'series_id', how = 'inner')\n\nlocdf = pd.melt(locdf,\n          id_vars=['instance_number', 'logits_mask', 'series_id', 'study_id'],\n          value_vars=['x__l1_l2', 'y__l1_l2', 'x__l2_l3', 'y__l2_l3', 'x__l3_l4', 'y__l3_l4', 'x__l4_l5', 'y__l4_l5', 'x__l5_s1', 'y__l5_s1'],\n          var_name='level', value_name='coord')\nlocdf[['coord_type', 'level']] = locdf.level.str.split('__', expand=True)\nlocdf = locdf.query('logits_mask > 0.2')\nlocdf['coord'] = locdf['coord'].astype(np.float32)\nlocdf['logits_mask'] = locdf['logits_mask'].astype(np.float32)\nlocdf = locdf.pivot_table(index=['instance_number', 'series_id', 'study_id', 'level', 'logits_mask'],\n                          columns='coord_type',\n                          values='coord').reset_index()\nCOLS = ['series_id', 'level', 'instance_number']\nlocdf = pd.merge(locdf, \n                 metadf['series_id\tinstance_number img_h img_w'.split()].drop_duplicates(), \n                 on = 'instance_number  series_id'.split(), how = 'left')\nlocdf['x'] = (locdf['x'] * locdf['img_w']).round().astype(int)\nlocdf['y'] = (locdf['y'] * locdf['img_h']).round().astype(int)\nlocdf = locdf.sort_values(COLS).reset_index(drop = True)\nlocdf.to_csv(\"test__cfg_dh_14p2_locsag_test.csv.gz\", index = False)\n\nlocdf.head()","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:38:55.111626Z","iopub.execute_input":"2024-10-07T18:38:55.112281Z","iopub.status.idle":"2024-10-07T18:39:16.446942Z","shell.execute_reply.started":"2024-10-07T18:38:55.112239Z","shell.execute_reply":"2024-10-07T18:39:16.445887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"name = \"cfg_dh_14s10a_locsag\"\ncfg = get_cfg(name)\n#cfg.full_test_set = False\n\ncfg.loc_df   = 'test__cfg_dh_14p2_locsag_test.csv.gz'\ncfg.meta_df  = f'meta_v1.pkl'\n\ncfg.coord_df = 'dummy_coordf.csv.gz'\ncfg.image_folder = IMAGE_FOLDER\ncfg.dicom_folder = DATA_FOLDER\nstate_dict_fps = sorted(glob.glob(f'/kaggle/input/weights-rsna24-cfg-dh-14s10a-locsag/**/*check*', recursive = True))\nfull_test_set = False\nif OOF_CHECK:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold{OOF_FOLD}/' in fp]\nelse:\n    state_dict_fps = [fp for fp in state_dict_fps if f'fold-1/' in fp]\n    \nstate_dict_fps\n\n# test_dl, batch_to_device = get_dl(cfg)\nds = importlib.import_module(cfg.dataset)\nimportlib.reload(ds)\n\nCustomDataset = ds.CustomDataset\nbatch_to_device = ds.batch_to_device\n\ntest_ds = CustomDataset(test_df, cfg, cfg.val_aug, mode=\"test\")\ntest_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=True)\nprint('\\n'.join(state_dict_fps))\n\nnets = get_nets(cfg,state_dict_fps)\n\noutd = collections.defaultdict(list)\nwith torch.inference_mode():\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch,DEVICE)\n        outs = [net(batch) for net in nets]\n        outd['logits'] += [torch.stack([out['logits'] for out in outs], dim=0).mean(0).cpu()]\n        for k in 'series_id instance_number'.split():\n            outd[k] += [outs[0][k].cpu()]\nfor k in \"series_id instance_number logits\".split(): \n    outd[k] = torch.cat(outd[k], dim=0)\nslcdf = pd.DataFrame({k: outd[k].numpy() for k in \"series_id instance_number\".split()})\nslcdf[cfg.classes] = outd['logits'].numpy()\nslcdf = slcdf.groupby('series_id instance_number'.split())[cfg.classes].mean().reset_index()\nslcdf = slcdf.sort_values('series_id\tinstance_number'.split()).reset_index(drop = True)\nslcdf.to_csv('test__cfg_dh_14s10a_locsag.csv.gz', index = False)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:39:16.448635Z","iopub.execute_input":"2024-10-07T18:39:16.449095Z","iopub.status.idle":"2024-10-07T18:39:30.586475Z","shell.execute_reply.started":"2024-10-07T18:39:16.449055Z","shell.execute_reply":"2024-10-07T18:39:30.585461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Projection","metadata":{}},{"cell_type":"code","source":"locdf = pd.read_csv('/kaggle/working/test__cfg_dh_14p2_locsag_test.csv.gz')\nslcdf = pd.read_csv('/kaggle/working/test__cfg_dh_14s10a_locsag.csv.gz')\nmetadf = pd.read_pickle(\"/kaggle/working/meta_v1.pkl\")\n\nslcdf = slcdf[slcdf.filter(like = 'nfn').max(1)>0.1].reset_index(drop = True)\nslcdf['side'] = slcdf.filter(like = 'nfn').idxmax(1)\njcols = \"series_id  instance_number\".split()\nlocdf = pd.merge(locdf, slcdf[jcols + ['side']], on = jcols, how = 'inner')\nfcols = \"series_id  instance_number level side x y \".split()\nlocdf = locdf[fcols].sort_values(fcols[:3]).reset_index(drop = True)\n\npcols = \"PixelSpacing img_w  img_h ImageOrientationPatient ImagePositionPatient\".split()\nmetadf = pd.merge(metadf[pcols+jcols] , slcdf[jcols], on = jcols, how = 'inner')\nmetadf = metadf.set_index('series_id')\nmetadf.head()\n\nxxyyzzdf = []\nfor (series_id, instance_number, side), g in \\\n    locdf.groupby(\"series_id  instance_number side\".split()):\n    mdf = metadf.loc[series_id].query(\"instance_number == @instance_number\")\n    sagittal_t2_point, sagittal_t2_df, image_size = g, mdf, (512,512)\n    xxyyzz = view_to_world(sagittal_t2_point, 0, sagittal_t2_df, image_size)\n    for level, xyz in zip(g.level, xxyyzz ):\n        xxyyzzdf.append([series_id, instance_number, level, side, *xyz])\n\nxxyyzzdf = pd.DataFrame(xxyyzzdf, columns = \"series_id instance_number level side xx yy zz\".split())\nxxyyzzdf = xxyyzzdf.sort_values(\"series_id level instance_number\".split()).reset_index(drop = True)\nxxyyzzdf.head()\n\nmetadf  = pd.read_pickle('meta_v1.pkl')\\\n        .sort_values('series_id instance_number'.split())\nkcols = \"series_id instance_number ImageOrientationPatient ImagePositionPatient PixelSpacing\".split()\nmetadf  = metadf[kcols].set_index('series_id')\ntrnsdf = test_series_descriptions.copy()\nmapper = collections.defaultdict(list)\nfor study_id, grp in trnsdf.groupby('study_id'):\n    sagt1ls =  grp.query('series_description==\"Sagittal T1\"').series_id.tolist()\n    axt2ls =  grp.query('series_description==\"Axial T2\"').series_id.tolist()\n    for sagt1 in sagt1ls:\n        mapper[sagt1] += axt2ls\n        \n        \naxmapdf = []\nfor (series_id, instance_number), g in xxyyzzdf.groupby(\"series_id instance_number\".split()):\n    for axt2_series in mapper[series_id]:\n        axial_t2_df = metadf.loc[axt2_series]\n        world_point = g['xx yy zz'.split()].values\n        ax_instance_numbers, fdis = point_to_level2(world_point, axial_t2_df)\n        tmpdf = {'level': g.level.tolist(),\n         'mapped_ax_instance_number': ax_instance_numbers,\n         'source_series_id': series_id,\n         'series_id':axt2_series,\n         'distance': fdis}\n        axmapdf.append(pd.DataFrame(tmpdf))\n        \naxmapdf = pd.concat(axmapdf)\naxmapdf = axmapdf.sort_values('series_id level distance'.split()).reset_index(drop= True)\n\naxmapdf = axmapdf.groupby('series_id level source_series_id'.split())\\\n    .agg({'mapped_ax_instance_number':list, 'distance':list})\naxmapdf = axmapdf.reset_index()\n#axmapdf['distance'].apply(lambda x: x[0])\naxmapdf.to_pickle('test__dh_14p2___dh_14s10a____locsag_mapped_v02.pkl')\naxmapdf.head(8)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:39:30.588645Z","iopub.execute_input":"2024-10-07T18:39:30.589037Z","iopub.status.idle":"2024-10-07T18:39:30.857431Z","shell.execute_reply.started":"2024-10-07T18:39:30.588995Z","shell.execute_reply":"2024-10-07T18:39:30.856350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Crop models","metadata":{}},{"cell_type":"code","source":"def pred_config(cfg_name = 'cfg_dh_29a2', \n                weights_dir = '/kaggle/input/weights-rsna24-cfg-dh-29a2',\n                loc_df_nm = 'test__cfg_dh_14p2_locsag_test.csv.gz',\n                meta_df_nm = f'meta_v1.pkl',\n                locax_df_nm = f'cfg_dh_05b5_loc_test.csv.gz',\n                mapax_df_nm = f'test__dh_14p2___dh_14s10a____locsag_mapped_v02.pkl',\n                IMAGE_DIR = IMAGE_FOLDER,\n                ):\n    name = cfg_name\n    cfg = get_cfg(name)\n    cfg.train_df = 'test_df.csv'\n    cfg.loc_df   = loc_df_nm\n    cfg.meta_df  = meta_df_nm\n    cfg.locax_df = locax_df_nm\n    cfg.mapax_df = mapax_df_nm\n    cfg.batch_size = 8\n    cfg.batch_size_val=8\n    cfg.image_folder = IMAGE_DIR\n    state_dict_fps = sorted(glob.glob(f'{weights_dir}/fold-1/*check*', recursive = True))[:8]\n    if OOF_CHECK:\n        state_dict_fps = sorted(glob.glob(f'{weights_dir}/fold{OOF_FOLD}/*check*', recursive = True))\n        state_dict_fps = [fp for fp in state_dict_fps if f'fold{OOF_FOLD}/' in fp][-1:]\n    test_dl, batch_to_device = get_dl(cfg)\n    print('Loading')\n    print('\\n'.join(state_dict_fps))\n    nets = get_nets(cfg,state_dict_fps)\n    outd = collections.defaultdict(list)\n    with torch.inference_mode():\n        for batch in tqdm(test_dl):\n            batch = batch_to_device(batch,DEVICE)\n            outs = [net(batch) for net in nets]\n            for k in \"series_id study_id condition level target\".split():\n                outd[k] += [outs[0][k].cpu()]\n            outd['logits'] += [torch.stack([out['logits'] for out in outs], dim=0).mean(0).cpu()]\n    for k in \"series_id study_id condition level target logits\".split(): \n        outd[k] = torch.cat(outd[k], dim=0)\n    pp_out = post_process_pipeline(cfg,  outd, None)\n    pred_df = pd.DataFrame({k:v.numpy() for k,v in outd.items() if k in \"series_id study_id condition level\".split()})\n    preds = torch.softmax(outd['logits'].float(), -1).detach().cpu().numpy()\n    \n    outls = []\n    targets = [['left_neural_foraminal_narrowing', 'right_neural_foraminal_narrowing'], \n               ['spinal_canal_stenosis'], \n               ['left_subarticular_stenosis', 'right_subarticular_stenosis']]\n    for rp, r in zip(preds, pred_df.itertuples()):\n        tgts = targets[r.condition]\n        for tgt,rpp in zip(tgts, rp):\n            out = [f'{r.study_id}_{tgt}_{LEVELS[r.level]}'] + rpp.tolist()\n            out += [r.study_id, tgt, LEVELS[r.level]]\n            outls.append(out)\n    pred_df_1 = pd.DataFrame(outls, columns= 'row_id\tnormal_mild\tmoderate\tsevere study_id condition level'.split())\n    pred_df_1 = pred_df_1.groupby('row_id study_id condition level'.split())['normal_mild\tmoderate\tsevere'.split()].agg('mean').reset_index()\n    \n    return pred_df_1, pp_out","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:39:30.862231Z","iopub.execute_input":"2024-10-07T18:39:30.862601Z","iopub.status.idle":"2024-10-07T18:39:30.878453Z","shell.execute_reply.started":"2024-10-07T18:39:30.862573Z","shell.execute_reply":"2024-10-07T18:39:30.877516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### cfg_dh_29a2","metadata":{}},{"cell_type":"code","source":"pred_df_1, pp_out__cfg_dh_29a2 = pred_config(cfg_name = 'cfg_dh_29a2', \n                                weights_dir = '/kaggle/input/weights-rsna24-cfg-dh-29a2',\n                                loc_df_nm = 'test__cfg_dh_14p2_locsag_test.csv.gz',\n                                meta_df_nm = f'meta_v1.pkl',\n                                locax_df_nm = f'cfg_dh_05b5_loc_test.csv.gz',\n                                mapax_df_nm = f'test__dh_14p2___dh_14s10a____locsag_mapped_v02.pkl',\n                                IMAGE_DIR = IMAGE_FOLDER4,\n                                )\ntorch.save(pp_out__cfg_dh_29a2, f'pp_out__cfg_dh_29a2.pth')","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:39:30.879490Z","iopub.execute_input":"2024-10-07T18:39:30.879777Z","iopub.status.idle":"2024-10-07T18:40:00.218973Z","shell.execute_reply.started":"2024-10-07T18:39:30.879751Z","shell.execute_reply":"2024-10-07T18:40:00.217943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if OOF_CHECK:\n    study_loss = StudyLoss()\n    loss_scs, loss_nfn, loss_ss, any_loss = study_loss(\n        pp_out__cfg_dh_29a2['logits'],pp_out__cfg_dh_29a2['target']\n    )[:4]\n\n    print(f'scs : {loss_scs.item():0.4f}')\n    print(f'nfn : {loss_nfn.item():0.4f}')\n    print(f'ss : {loss_ss.item():0.4f}')\n    print(f'any_scs : {any_loss.item():0.4f}')\n    \n    file = '/kaggle/input/rsna-oofs/oof____cfg_dh_29a2.pth'\n    d = torch.load(file)\n    print()\n\n    studies = d['study_id']\n    kept = np.array([s in pp_out__cfg_dh_29a2['study_id'] for s in studies])    \n\n    loss_scs, loss_nfn, loss_ss, any_loss = study_loss(d['logits'][kept], d[\"target\"][kept])[:4]\n\n    print()\n    print(f'scs : {loss_scs.item():0.4f}')\n    print(f'nfn : {loss_nfn.item():0.4f}')\n    print(f'ss : {loss_ss.item():0.4f}')\n    print(f'any_scs : {any_loss.item():0.4f}')\n    print()\n    ","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:00.220794Z","iopub.execute_input":"2024-10-07T18:40:00.221583Z","iopub.status.idle":"2024-10-07T18:40:00.229450Z","shell.execute_reply.started":"2024-10-07T18:40:00.221535Z","shell.execute_reply":"2024-10-07T18:40:00.228404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### cfg_dh_29g","metadata":{}},{"cell_type":"code","source":"pred_df_0, pp_out__cfg_dh_29g = pred_config(cfg_name = 'cfg_dh_29g', \n                                weights_dir = '/kaggle/input/weights-rsna24-cfg-dh-29g',\n                                loc_df_nm = 'test__cfg_dh_14p2_locsag_test.csv.gz',\n                                meta_df_nm = f'meta_v1.pkl',\n                                locax_df_nm = f'cfg_dh_05b5_loc_test.csv.gz',\n                                mapax_df_nm = f'test__dh_14p2___dh_14s10a____locsag_mapped_v02.pkl',\n                                IMAGE_DIR = IMAGE_FOLDER4,\n                                )\ntorch.save(pp_out__cfg_dh_29g, f'pp_out__cfg_dh_29g.pth')","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:00.230614Z","iopub.execute_input":"2024-10-07T18:40:00.230884Z","iopub.status.idle":"2024-10-07T18:40:29.793883Z","shell.execute_reply.started":"2024-10-07T18:40:00.230860Z","shell.execute_reply":"2024-10-07T18:40:29.792601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if OOF_CHECK:\n    \n    study_loss = StudyLoss()\n    loss_scs, loss_nfn, loss_ss, any_loss = study_loss(\n        pp_out__cfg_dh_29g['logits'],pp_out__cfg_dh_29g['target']\n    )[:4]\n\n    print(f'scs : {loss_scs.item():0.4f}')\n    print(f'nfn : {loss_nfn.item():0.4f}')\n    print(f'ss : {loss_ss.item():0.4f}')\n    print(f'any_scs : {any_loss.item():0.4f}')\n    \n    file = '/kaggle/input/rsna-oofs/oof____cfg_dh_29g_seed1.pth'\n    d = torch.load(file)\n    print()\n    \n    studies = d['study_id']\n    kept = np.array([s in pp_out__cfg_dh_29g['study_id'] for s in studies])    \n    \n    loss_scs, loss_nfn, loss_ss, any_loss = study_loss(d['logits'][kept], d[\"target\"][kept])[:4]\n\n    print()\n    print(f'scs : {loss_scs.item():0.4f}')\n    print(f'nfn : {loss_nfn.item():0.4f}')\n    print(f'ss : {loss_ss.item():0.4f}')\n    print(f'any_scs : {any_loss.item():0.4f}')\n    print()\n    ","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:29.795447Z","iopub.execute_input":"2024-10-07T18:40:29.795765Z","iopub.status.idle":"2024-10-07T18:40:29.803889Z","shell.execute_reply.started":"2024-10-07T18:40:29.795733Z","shell.execute_reply":"2024-10-07T18:40:29.802859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### cfg_dh_12y8","metadata":{}},{"cell_type":"code","source":"pred_df_2, pp_out__cfg_dh_12y8 = pred_config(cfg_name = 'cfg_dh_12y8', \n                                weights_dir = '/kaggle/input/weights-rsna24-cfg-dh-12y8/',\n                                loc_df_nm = 'test__cfg_dh_14p2_locsag_test.csv.gz',\n                                meta_df_nm = f'meta_v1.pkl',\n                                locax_df_nm = None,\n                                mapax_df_nm = None,\n                                IMAGE_DIR = IMAGE_FOLDER,\n                                )\ntorch.save(pp_out__cfg_dh_12y8, f'pp_out__cfg_dh_12y8.pth')","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:29.805137Z","iopub.execute_input":"2024-10-07T18:40:29.805896Z","iopub.status.idle":"2024-10-07T18:40:49.528633Z","shell.execute_reply.started":"2024-10-07T18:40:29.805867Z","shell.execute_reply":"2024-10-07T18:40:49.527360Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if OOF_CHECK:\n    study_loss = StudyLoss()\n    loss_scs, loss_nfn, loss_ss, any_loss = study_loss(\n        pp_out__cfg_dh_12y8['logits'], pp_out__cfg_dh_12y8['target']\n    )[:4]\n\n    print(f'scs : {loss_scs.item():0.4f}')\n    print(f'nfn : {loss_nfn.item():0.4f}')\n    print(f'ss : {loss_ss.item():0.4f}')\n    print(f'any_scs : {any_loss.item():0.4f}')\n\n    file = f'/kaggle/input/rsna-oofs/oof____cfg_dh_12y8.pth'\n    d = torch.load(file)\n    print()\n    \n    studies = d['study_id']\n    kept = np.array([s in pp_out__cfg_dh_29g['study_id'] for s in studies])    \n    \n    loss_scs, loss_nfn, loss_ss, any_loss = study_loss(d['logits'][kept], d[\"target\"][kept])[:4]\n\n    print()\n    print(f'scs : {loss_scs.item():0.4f}')\n    print(f'nfn : {loss_nfn.item():0.4f}')\n    print(f'ss : {loss_ss.item():0.4f}')\n    print(f'any_scs : {any_loss.item():0.4f}')\n    print()\n    ","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:49.530214Z","iopub.execute_input":"2024-10-07T18:40:49.530581Z","iopub.status.idle":"2024-10-07T18:40:49.538838Z","shell.execute_reply.started":"2024-10-07T18:40:49.530547Z","shell.execute_reply":"2024-10-07T18:40:49.537756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Theo","metadata":{}},{"cell_type":"markdown","source":"### Imports","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport re\nimport sys\nimport cv2\nimport glob\nimport json\nimport torch\nimport shutil\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport torch.nn.functional as F\nimport matplotlib.pyplot as plt\n\nfrom tqdm.notebook import tqdm\nfrom scipy.special import softmax\nfrom collections import Counter\nfrom joblib import Parallel, delayed\n\nwarnings.simplefilter(\"ignore\", FutureWarning)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:49.539894Z","iopub.execute_input":"2024-10-07T18:40:49.540196Z","iopub.status.idle":"2024-10-07T18:40:49.551723Z","shell.execute_reply.started":"2024-10-07T18:40:49.540172Z","shell.execute_reply":"2024-10-07T18:40:49.550845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if os.path.exists(\"/kaggle/input/rsna-lumbar-spine-code/src\"):\n    !cp -r /kaggle/input/rsna-lumbar-spine-code/src ./\n    sys.path.append(\"src\")\n\nfrom util.torch import load_model_weights\nfrom util.plots import plot_mask, add_rect\nfrom util.metrics import rsna_loss\n\nfrom data.processing import process_and_save\nfrom data.transforms import get_transfos\nfrom data.dataset import CropDataset, CoordsDataset\nfrom data.preparation import prepare_data_crop\n\nfrom inference.seg import get_crops\nfrom inference.dataset import ImageInfDataset, FeatureInfDataset, SafeDataset\nfrom inference.lvl1 import predict, Config\nfrom inference.utils import sub_to_dict\n\nif os.path.exists(\"/kaggle/input/timm-smp\"):\n    sys.path.append(\n        \"/kaggle/input/timm-smp/pytorch-image-models-main/pytorch-image-models-main\"\n    )\n    sys.path.append(\n        \"/kaggle/input/timm-smp/segmentation_models.pytorch-master/segmentation_models.pytorch-master\"\n    )\nfrom model_zoo.models import define_model\nfrom model_zoo.models_lvl2 import define_model as define_model_2\n# from model_zoo.models_seg import define_model as define_model_seg\n# from model_zoo.models_seg import convert_3d\n\nfrom params import CLASSES_SEG, MODES, LEVELS_, SEVERITIES, LEVELS","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:49.553208Z","iopub.execute_input":"2024-10-07T18:40:49.553605Z","iopub.status.idle":"2024-10-07T18:40:50.852781Z","shell.execute_reply.started":"2024-10-07T18:40:49.553573Z","shell.execute_reply":"2024-10-07T18:40:50.851676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Params","metadata":{}},{"cell_type":"code","source":"EVAL = False\nDEBUG = False\n\n# ROOT_DATA_DIR = \"../input/\"\n# DEBUG_DATA_DIR = \"../output/dataset_debug/\"  # Todo\n# SAVE_FOLDER = \"../output/tmp/\"\n# shutil.rmtree(SAVE_FOLDER)\n\nROOT_DATA_DIR = \"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/\"\nDEBUG_DATA_DIR = \"/kaggle/input/rsna-2024-debug/\"\nSAVE_FOLDER = \"/tmp/\"\n\nos.makedirs(SAVE_FOLDER, exist_ok=True)\nos.makedirs(SAVE_FOLDER + \"npy/\", exist_ok=True)\nos.makedirs(SAVE_FOLDER + \"mid/\", exist_ok=True)\nos.makedirs(SAVE_FOLDER + \"csv/\", exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:50.854343Z","iopub.execute_input":"2024-10-07T18:40:50.854752Z","iopub.status.idle":"2024-10-07T18:40:50.863200Z","shell.execute_reply.started":"2024-10-07T18:40:50.854708Z","shell.execute_reply":"2024-10-07T18:40:50.862401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_PATH = ROOT_DATA_DIR + \"test_images/\"\nfolds_dict = {}\n\nif DEBUG:\n    df_meta = pd.read_csv(ROOT_DATA_DIR + \"train_series_descriptions.csv\")\nelse:\n    df_meta = pd.read_csv(ROOT_DATA_DIR + \"test_series_descriptions.csv\")\n\ndf_meta[\"weighting\"] = df_meta[\"series_description\"].apply(lambda x: x.split()[1][:2])\ndf_meta[\"orient\"] = df_meta[\"series_description\"].apply(lambda x: x.split()[0])\ndf_meta[\"study_series\"] = df_meta[\"study_id\"].astype(str) + \"_\" + df_meta[\"series_id\"].astype(str)\n\nif DEBUG:\n    if EVAL:\n        DATA_PATH = ROOT_DATA_DIR + \"train_images/\"\n        FOLDS_FILE = DEBUG_DATA_DIR + \"train_folded_v1.csv\"\n        folds = pd.read_csv(FOLDS_FILE)\n        df_meta = df_meta.merge(folds, how=\"left\")\n        df_meta = df_meta[df_meta['fold'] == 1].reset_index(drop=True)\n    else:\n        DATA_PATH = DEBUG_DATA_DIR + \"debug_images/\"\n        df_meta = df_meta.head(3)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:50.864335Z","iopub.execute_input":"2024-10-07T18:40:50.864659Z","iopub.status.idle":"2024-10-07T18:40:50.883574Z","shell.execute_reply.started":"2024-10-07T18:40:50.864635Z","shell.execute_reply":"2024-10-07T18:40:50.882828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 16\nBATCH_SIZE_2 = 512\nUSE_FP16 = True\n\nNUM_WORKERS = os.cpu_count()\n\nFOLD = 1 if DEBUG else \"fullfit_0\"\nPLOT = DEBUG and not EVAL","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:50.884815Z","iopub.execute_input":"2024-10-07T18:40:50.885648Z","iopub.status.idle":"2024-10-07T18:40:50.890757Z","shell.execute_reply.started":"2024-10-07T18:40:50.885619Z","shell.execute_reply":"2024-10-07T18:40:50.889946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EXP_FOLDERS = {}\n\nCOORDS_FOLDERS = {\n    \"sag\": (\"/kaggle/input/rsna-2024-weights-1/2024-08-29_0/\", FOLD),\n}\n\nCROP_EXP_FOLDERS = {\n    \"crop\": (\"/kaggle/input/rsna-2024-weights-2/2024-10-04_1/\", [FOLD], \"crops_0.1\"),\n    \"crop_2\": (\"/kaggle/input/rsna-2024-weights-2/2024-10-04_9/\", [FOLD], \"crops_0.1\"),\n    \"scs_crop_coords\": (\"/kaggle/input/rsna-2024-weights-2/2024-10-04_34/\", [FOLD], \"crops_0.1\"),  # 5f -0.005 scs\n    \"scs_crop_coords_2\": (\"/kaggle/input/rsna-2024-weights-2/2024-10-04_37/\", [FOLD], \"crops_0.1\"),  # 3f -0.005 scs\n}\n\nEXP_FOLDERS_2 = [\n#     \"/kaggle/input/rsna-2024-weights-2/2024-10-04_43/\",  # 0.3861\n#     \"/kaggle/input/rsna-2024-weights-2/2024-10-07_0/\",  # 0.382\n    \"/kaggle/input/rsna-2024-weights-2/2024-10-08_2/\",  # Shifted dist\n]\nFOLDS_2 = [0, 1, 2]  # [FOLD]\n\n# EXP_FOLDER_3D = \"../logs/2024-07-31/25/\"\n\nfor f in EXP_FOLDERS_2:\n    folders = Config(json.load(open(f + \"config.json\", \"r\"))).exp_folders\n    print(\"-> Level 2 model:\", f)\n    for k in folders:\n        print(k, folders[k], EXP_FOLDERS.get(k, CROP_EXP_FOLDERS.get(k, [\"?\"]))[0])\n    print()\n\n    \nfor k in EXP_FOLDERS:\n    assert os.path.exists(EXP_FOLDERS[k][0]), f\"Model not found: {k}\"\nfor k in CROP_EXP_FOLDERS:\n    assert os.path.exists(CROP_EXP_FOLDERS[k][0]), f\"Crop model not found: {k}\"\nfor k in COORDS_FOLDERS:\n    assert os.path.exists(COORDS_FOLDERS[k][0]), f\"Coords model not found: {k}\"","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:50.892097Z","iopub.execute_input":"2024-10-07T18:40:50.894758Z","iopub.status.idle":"2024-10-07T18:40:50.916374Z","shell.execute_reply.started":"2024-10-07T18:40:50.894733Z","shell.execute_reply":"2024-10-07T18:40:50.915544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_meta.head(5)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:50.917299Z","iopub.execute_input":"2024-10-07T18:40:50.917586Z","iopub.status.idle":"2024-10-07T18:40:50.928459Z","shell.execute_reply.started":"2024-10-07T18:40:50.917556Z","shell.execute_reply":"2024-10-07T18:40:50.927589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preparation","metadata":{}},{"cell_type":"code","source":"_ = Parallel(n_jobs=NUM_WORKERS)(\n    delayed(process_and_save)(\n        df_meta['study_id'][i],\n        df_meta['series_id'][i],\n        df_meta['orient'][i],\n        DATA_PATH,\n        save_folder=SAVE_FOLDER,\n        save_meta=False,\n        save_middle_frame=True,\n    ) for i in tqdm(range(len(df_meta)))\n)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:50.929657Z","iopub.execute_input":"2024-10-07T18:40:50.929968Z","iopub.status.idle":"2024-10-07T18:40:53.439243Z","shell.execute_reply.started":"2024-10-07T18:40:50.929939Z","shell.execute_reply":"2024-10-07T18:40:53.437890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# if DEBUG and not EVAL:\n#     from data.preparation import prepare_data_crop\n\n#     ref_folder = DEBUG_DATA_DIR + \"npy/\"\n#     # png_ref_folder = \"../input/coords/comp_data/\"\n\n#     for i in range(len(df_meta)):\n#         study_series = df_meta[\"study_series\"][i]\n#         npy_ref = np.load(ref_folder + f\"{study_series}.npy\")\n#         npy = np.load(SAVE_FOLDER + f\"npy/{study_series}.npy\")\n#         assert (npy == npy_ref).all()\n\n#         # if df_meta['orient'][i] == \"Axial\":\n#         #     continue\n\n#         # png_ref = cv2.imread(png_ref_folder + f\"{study_series}.png\")\n#         # png = cv2.imread(SAVE_FOLDER + f\"mid/{study_series}.png\")\n\n#         # # plt.subplot(1, 2, 1)\n#         # # plt.imshow(png, cmap=\"gray\")\n#         # # plt.subplot(1, 2, 2)\n#         # # plt.imshow(png_ref, cmap=\"gray\")\n#         # # plt.show()\n        \n#         # assert (png == png_ref).all()\n        ","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:53.441349Z","iopub.execute_input":"2024-10-07T18:40:53.443836Z","iopub.status.idle":"2024-10-07T18:40:53.449714Z","shell.execute_reply.started":"2024-10-07T18:40:53.443794Z","shell.execute_reply":"2024-10-07T18:40:53.448585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Sagittal Coords","metadata":{}},{"cell_type":"code","source":"df_sag = df_meta[df_meta[\"orient\"] == \"Sagittal\"].reset_index(drop=True)\ndf_sag = df_sag[df_sag.columns[:6]]\n\ndf_sag['img_path'] = SAVE_FOLDER + \"mid/\" + df_sag[\"study_series\"] + \".png\"\ndf_sag['target'] = [np.ones((5, 2)) for _ in range(len(df_sag))]\n\ndf_sag.head(3)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:53.451026Z","iopub.execute_input":"2024-10-07T18:40:53.451949Z","iopub.status.idle":"2024-10-07T18:40:53.482041Z","shell.execute_reply.started":"2024-10-07T18:40:53.451917Z","shell.execute_reply":"2024-10-07T18:40:53.480708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"config_sag = Config(json.load(open(COORDS_FOLDERS['sag'][0] + \"config.json\", \"r\")))\n\nmodel_sag = define_model(\n    config_sag.name,\n    drop_rate=config_sag.drop_rate,\n    drop_path_rate=config_sag.drop_path_rate,\n    pooling=config_sag.pooling,\n    num_classes=config_sag.num_classes,\n    num_classes_aux=config_sag.num_classes_aux,\n    n_channels=config_sag.n_channels,\n    reduce_stride=config_sag.reduce_stride,\n    pretrained=False,\n)\nmodel_sag = model_sag.cuda().eval()\n\nweights = COORDS_FOLDERS['sag'][0] + f\"{config_sag.name}_{COORDS_FOLDERS['sag'][1]}.pt\"\nmodel_sag = load_model_weights(model_sag, weights, verbose=1)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:53.483666Z","iopub.execute_input":"2024-10-07T18:40:53.483964Z","iopub.status.idle":"2024-10-07T18:40:57.380814Z","shell.execute_reply.started":"2024-10-07T18:40:53.483940Z","shell.execute_reply":"2024-10-07T18:40:57.379770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ntransfos = get_transfos(augment=False, resize=config_sag.resize, use_keypoints=True)\ndataset = CoordsDataset(df_sag, transforms=transfos)\ndataset = SafeDataset(dataset)\n\npreds_sag, _ = predict(model_sag, dataset, config_sag.loss_config, batch_size=32, use_fp16=True)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:57.387318Z","iopub.execute_input":"2024-10-07T18:40:57.387629Z","iopub.status.idle":"2024-10-07T18:40:58.031051Z","shell.execute_reply.started":"2024-10-07T18:40:57.387604Z","shell.execute_reply":"2024-10-07T18:40:58.029862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DELTAS = [0.1]  #, 0.15]\n\nfor delta in DELTAS:\n    os.makedirs(SAVE_FOLDER + f\"crops_{delta}\", exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:58.032479Z","iopub.execute_input":"2024-10-07T18:40:58.032888Z","iopub.status.idle":"2024-10-07T18:40:58.038447Z","shell.execute_reply.started":"2024-10-07T18:40:58.032845Z","shell.execute_reply":"2024-10-07T18:40:58.037502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for idx in tqdm(range(len(df_sag))):\n    study_series = df_sag[\"study_series\"][idx]\n    imgs_path = SAVE_FOLDER + \"npy/\" + study_series + \".npy\"\n\n    imgs = np.load(imgs_path)\n\n    preds = preds_sag[idx].reshape(-1, 2).copy()\n\n    for delta in DELTAS:  # , 0.15\n        crops = np.concatenate([preds, preds], -1)\n        crops[:, [0, 1]] -= delta\n        crops[:, [2, 3]] += delta\n        crops = crops.clip(0, 1)\n\n        crops[:, [0, 2]] *= imgs.shape[2]\n        crops[:, [1, 3]] *= imgs.shape[1]\n        crops = crops.astype(int)\n\n        img_crops = []\n        for i, (x0, y0, x1, y1) in enumerate(crops):\n\n            crop = imgs[:, y0: y1, x0: x1].copy()\n            # crop = np.zeros((3, 1, 1))\n            try:\n                assert crop.shape[2] >= 1 and crop.shape[1] >= 1\n            except AssertionError:\n                # print('!!')\n                # pass\n                crop = imgs.copy()\n\n            np.save(SAVE_FOLDER + f\"crops_{delta}/{study_series}_{LEVELS_[i]}.npy\", crop)\n            img_crops.append(crop[len(crop) // 2])\n\n        if PLOT:\n            preds[:, 0] *= imgs.shape[2]\n            preds[:, 1] *= imgs.shape[1]\n\n            plt.figure(figsize=(8, 8))\n            plt.imshow(imgs[len(imgs) // 2], cmap=\"gray\")\n            plt.scatter(preds[:, 0], preds[:, 1], marker=\"x\", label=\"center\")\n            plt.title(study_series)\n            plt.axis(False)\n            plt.legend()\n            plt.show()\n\n            plt.figure(figsize=(20, 4))\n            for i in range(5):\n                plt.subplot(1, 5, i + 1)\n                plt.imshow(img_crops[i], cmap=\"gray\")\n                plt.axis(False)\n                plt.title(LEVELS[i])\n            plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:58.039808Z","iopub.execute_input":"2024-10-07T18:40:58.040071Z","iopub.status.idle":"2024-10-07T18:40:58.110956Z","shell.execute_reply.started":"2024-10-07T18:40:58.040049Z","shell.execute_reply":"2024-10-07T18:40:58.109993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if DEBUG and not EVAL:\n    ref_folder = DEBUG_DATA_DIR + \"coords_crops_0.1_2/\"\n    df_ref = prepare_data_crop(ROOT_DATA_DIR, ref_folder).head(10)\n\n    df_ref['img_path_2'] = df_ref['img_path'].apply(\n        lambda x: re.sub(ref_folder, SAVE_FOLDER + f\"crops_0.1/\", x)\n    )\n\n    for i in range(len(df_ref)):\n        cref = np.load(df_ref['img_path'][i])\n        c = np.load(df_ref['img_path_2'][i])\n        assert (cref == c).all()\n        # plt.subplot(1, 2, 1)\n        # plt.imshow(c[len(c) // 2], cmap=\"gray\")\n        # plt.subplot(1, 2, 2)\n        # plt.imshow(cref[len(cref) // 2], cmap=\"gray\")\n        # plt.show()\n        # break","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:58.112412Z","iopub.execute_input":"2024-10-07T18:40:58.112860Z","iopub.status.idle":"2024-10-07T18:40:58.120694Z","shell.execute_reply.started":"2024-10-07T18:40:58.112826Z","shell.execute_reply":"2024-10-07T18:40:58.119854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Crop models","metadata":{}},{"cell_type":"code","source":"df = df_meta.copy()\n\ndf[\"target\"] = 0\ndf[\"coords\"] = 0\n\ndf[\"level\"] = [LEVELS for _ in range(len(df))]\ndf[\"level_\"] = [LEVELS_ for _ in range(len(df))]\ndf = df.explode([\"level\", \"level_\"]).reset_index(drop=True)\ndf[\"img_path_\"] = df[\"study_series\"] + \"_\" + df[\"level_\"] + \".npy\"","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:58.121722Z","iopub.execute_input":"2024-10-07T18:40:58.121973Z","iopub.status.idle":"2024-10-07T18:40:58.144030Z","shell.execute_reply.started":"2024-10-07T18:40:58.121951Z","shell.execute_reply":"2024-10-07T18:40:58.143073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"crop_fts = {}\nfor mode in tqdm(CROP_EXP_FOLDERS, total=len(CROP_EXP_FOLDERS)):\n    exp_folder, folds, crop_folder = CROP_EXP_FOLDERS[mode]\n    print(f\"- Model {mode} - {exp_folder}\")\n\n    config = Config(json.load(open(exp_folder + \"config.json\", \"r\")))\n\n    if mode in [\"crop\", \"crop_2\"]:\n        df_mode = df[df['orient'] == \"Sagittal\"].reset_index(drop=True)\n        df_mode[\"side\"] = \"Center\"\n    elif \"scs\" in mode:\n        df_mode = df[df['orient'] == \"Sagittal\"]\n        df_mode = df_mode[df_mode[\"weighting\"] == \"T2\"].reset_index(drop=True)\n        df_mode[\"side\"] = \"Center\"\n    elif \"nfn\" in mode:\n        df_mode = df[df['orient'] == \"Sagittal\"]\n        df_mode[\"side\"] = [\"Right\", \"Left\"]\n        df_mode = df_mode.explode(\"side\").reset_index(drop=True)\n        df_mode = df_mode.sort_values(\n            [\"study_id\", \"series_id\", \"side\", \"level\"],\n            ascending=[True, True, False, True],\n            ignore_index=True\n        )\n    elif \"ss\" in mode:\n        df_mode = df[df['orient'] == \"Axial\"]\n        df_mode[\"side\"] = [\"Right\", \"Left\"]\n        df_mode = df_mode.explode(\"side\").reset_index(drop=True)\n        df_mode = df_mode.sort_values(\n            [\"study_id\", \"series_id\", \"side\", \"level\"],\n            ascending=[True, True, False, True],\n            ignore_index=True\n        )\n\n    df_mode['img_path'] = SAVE_FOLDER + crop_folder + \"/\" + df_mode[\"img_path_\"]\n\n    transfos = get_transfos(augment=False, resize=config.resize, crop=config.crop)\n    dataset = CropDataset(\n        df_mode,\n        targets=\"target\",\n        transforms=transfos,\n        frames_chanel=config.frames_chanel,\n        n_frames=config.n_frames,\n        stride=config.stride,\n        train=False,\n        load_in_ram=False,\n    )\n    dataset = SafeDataset(dataset)\n\n    model = define_model(\n        config.name,\n        drop_rate=config.drop_rate,\n        drop_path_rate=config.drop_path_rate,\n        pooling=config.pooling,\n        head_3d=config.head_3d,\n        n_frames=config.n_frames,\n        num_classes=config.num_classes,\n        num_classes_aux=config.num_classes_aux,\n        n_channels=config.n_channels,\n        reduce_stride=config.reduce_stride,\n        pretrained=False,\n    )\n    model = model.cuda().eval()\n\n    if mode == \"crop_2\":\n        model.delta = 1\n\n    preds = []\n    for fold in folds:\n        weights = exp_folder + f\"{config.name}_{fold}.pt\"\n        model = load_model_weights(model, weights, verbose=1)\n\n        pred, _ = predict(\n            model,\n            dataset,\n            config.loss_config,\n            batch_size=BATCH_SIZE,\n            use_fp16=USE_FP16,\n            num_workers=NUM_WORKERS,\n        )\n        preds.append(pred)\n\n    preds = np.mean(preds, 0)\n\n    if PLOT:\n        df_ref = pd.read_csv(exp_folder + f\"df_val_{FOLD}.csv\").head(len(preds))\n        # order_ref = df_ref.sort_values([\"side\", \"level\"]).index.values\n        preds_ref = np.load(exp_folder + f\"pred_inf_{FOLD}.npy\")[: len(preds)]  # [order_ref]\n\n        # plt.figure(figsize=(8, 4))\n        # plt.subplot(1, 2, 1)\n        # plt.plot(preds)\n        # plt.subplot(1, 2, 2)\n        # plt.plot(preds_ref)\n        # plt.show()\n\n        delta = (np.abs(preds - preds_ref)).max()\n        print(preds.shape, preds_ref.shape)\n        print(f\"{mode} delta:\", delta)\n\n    idx = df_mode[[\"study_id\", \"series_id\", \"level\", \"side\"]].values.astype(str).tolist()\n    idx = [\"_\".join(i) for i in idx]\n    crop_fts[mode] = dict(zip(idx, preds))","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:40:58.145346Z","iopub.execute_input":"2024-10-07T18:40:58.146146Z","iopub.status.idle":"2024-10-07T18:41:12.319158Z","shell.execute_reply.started":"2024-10-07T18:40:58.146113Z","shell.execute_reply":"2024-10-07T18:41:12.317950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Level 2","metadata":{}},{"cell_type":"code","source":"csv_fts = {\n    \"ch\": sub_to_dict(\"logits_dieter.csv\"),\n    \"dh\": dict(zip(torch.load(f'pp_out__cfg_dh_12y8.pth')['study_id'].numpy(), torch.load(f'pp_out__cfg_dh_12y8.pth')['logits'].numpy())),\n    \"dh_2\": dict(zip(torch.load(f'pp_out__cfg_dh_29a2.pth')['study_id'].numpy(), torch.load(f'pp_out__cfg_dh_29a2.pth')['logits'].numpy())),\n    \"dh_3\": dict(zip(torch.load(f'pp_out__cfg_dh_29g.pth')['study_id'].numpy(), torch.load(f'pp_out__cfg_dh_29g.pth')['logits'].numpy())),\n}","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:41:12.320884Z","iopub.execute_input":"2024-10-07T18:41:12.321260Z","iopub.status.idle":"2024-10-07T18:41:12.340031Z","shell.execute_reply.started":"2024-10-07T18:41:12.321227Z","shell.execute_reply":"2024-10-07T18:41:12.339275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# csv_fts = {\n#     \"ch\": sub_to_dict(\"logits_dieter.csv\"),\n#     \"dh\": dict(zip(torch.load(f'/kaggle/input/rsna-oofs/oof____cfg_dh_12y8.pth')['study_id'].numpy(), torch.load(f'/kaggle/input/rsna-oofs/oof____cfg_dh_12y8.pth')['logits'].numpy())),\n#     \"dh_2\": dict(zip(torch.load(f'/kaggle/input/rsna-oofs/oof____cfg_dh_29a2.pth')['study_id'].numpy(), torch.load(f'/kaggle/input/rsna-oofs/oof____cfg_dh_29a2.pth')['logits'].numpy())),\n#     \"dh_3\": dict(zip(torch.load(f'/kaggle/input/rsna-oofs/oof____cfg_dh_29g_seed1.pth')['study_id'].numpy(), torch.load(f'/kaggle/input/rsna-oofs/oof____cfg_dh_29g_seed1.pth')['logits'].numpy())),\n# }","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:41:12.341241Z","iopub.execute_input":"2024-10-07T18:41:12.341667Z","iopub.status.idle":"2024-10-07T18:41:12.346076Z","shell.execute_reply.started":"2024-10-07T18:41:12.341640Z","shell.execute_reply":"2024-10-07T18:41:12.345085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\n\n\ndef define_model_2(\n    name=\"rnn_att\",\n    ft_dim=2048,\n    layer_dim=64,\n    dense_dim=256,\n    resize=15,\n    p=0.1,\n    num_classes=2,\n    num_classes_aux=0,\n    n_fts=0,\n):\n    \"\"\"\n    Define the level 2 model.\n\n    Args:\n        name (str): The name of the model to define. Default is \"rnn_att\".\n        ft_dim (int): Dimension of input features. Default is 2048.\n        layer_dim (int): Dimension of LSTM layers. Default is 64.\n        dense_dim (int): Dimension of the dense layer. Default is 256.\n        p (float): Dropout probability. Default is 0.1.\n        num_classes (int): Number of main classes. Default is 2.\n        num_classes_aux (int): Number of auxiliary classes. Default is 0.\n        n_fts (int): Number of features to use. Default is 0.\n\n    Returns:\n        nn.Module: The defined model.\n    \"\"\"\n    model_classes = {\n#         \"baseline\": BaselineModel,\n        \"simple\": SimpleModel,\n    }\n    model_class = model_classes[name]\n\n    return model_class(\n        ft_dim=ft_dim,\n        lstm_dim=layer_dim,\n        dense_dim=dense_dim,\n        resize=resize,\n        p=p,\n        num_classes=num_classes,\n        num_classes_aux=num_classes_aux,\n        n_fts=n_fts,\n    )\n\n\nclass SimpleModel(nn.Module):\n    def __init__(self, ft_dim=64, dense_dim=64, p=0.0, n_fts=0, **kwargs):\n        \"\"\"\n        Constructor.\n\n        Args:\n            ft_dim (int): The dimension of input features. Defaults to 64.\n            lstm_dim (int): The dimension of the LSTM layer. Defaults to 64.\n            n_lstm (int): The number of LSTM layers. Defaults to 1.\n            dense_dim (int): The dimension of the dense layer. Defaults to 64.\n            p (float): Dropout probability. Defaults to 0.1.\n            num_classes (int): The number of primary target classes. Defaults to 8.\n            num_classes_aux (int): The number of auxiliary target classes. Defaults to 0.\n            n_fts (int): The number of additional features. Defaults to 0.\n\n        \"\"\"\n        super().__init__()\n        self.n_fts = n_fts\n        self.num_classes = 3\n        self.num_classes_aux = 0\n\n        self.logits_scs = nn.Sequential(\n            nn.Linear(ft_dim[0], dense_dim),\n            nn.Dropout(p=p),\n            nn.LeakyReLU(0.05),\n            nn.Linear(dense_dim, 3),\n        )\n\n        self.logits_nfn = nn.Sequential(\n            nn.Linear(ft_dim[1], dense_dim),\n            nn.Dropout(p=p),\n            nn.LeakyReLU(0.05),\n            nn.Linear(dense_dim, 3),\n        )\n\n        self.logits_ss = nn.Sequential(\n            nn.Linear(ft_dim[2], dense_dim),\n            nn.Dropout(p=p),\n            nn.LeakyReLU(0.05),\n            nn.Linear(dense_dim, 3),\n        )\n\n    def forward(self, x, ft=None):\n        \"\"\"\n        Forward pass of the RNN with attention model.\n        \"\"\"\n        ref_k = list(x.keys())[0]\n        bs = x[ref_k].size(0)\n        logits = torch.zeros(bs, 25, 3).to(x[ref_k].device)\n\n        if \"crop_2\" in x.keys():\n            x[\"crop\"] = (x[\"crop\"] + x[\"crop_2\"]) / 2\n            del x[\"crop_2\"]\n\n        # if \"scs_crop_coords_2\" in x.keys() and \"scs_crop_coords\" in x.keys():\n        #     x[\"scs_crop_coords\"] = (x[\"scs_crop_coords\"] + x[\"scs_crop_coords_2\"]) / 2\n        #     del x[\"scs_crop_coords_2\"]\n\n        if \"dh_2\" in x.keys():\n            x['dh'][:, -10:] = x['dh_2'][:, -10:]\n            del x['dh_2']\n\n        if \"dh_3\" in x.keys():\n            x['dh'][:, :5] = (x['dh'][:, :5] + x['dh_3'][:, :5]) / 2\n            del x['dh_3']\n\n        if \"dh_4\" in x.keys():\n            x['dh'][:, 5:15] = (x['dh'][:, 5:15] + x['dh_4'][:, 5:15]) / 2\n            del x['dh_4']\n\n        fts = torch.cat(\n            [\n                x[k].view(bs, 25, -1)\n                for k in x.keys()\n                if not any([s in k for s in [\"scs\", \"nfn\", \"ss\", \"spinenet\"]])\n            ],\n            -1,\n        )\n\n        fts_scs = torch.cat(\n            [fts[:, :5]] +\n            [x[k].view(bs, -1, 3) for k in x.keys() if \"scs\" in k] +\n            ([x['spinenet']] if \"spinenet\" in x else []),\n            -1\n        )\n\n        fts_nfn = torch.cat(\n            [fts[:, 5:15]] +\n            [x[k].view(bs, -1, 3) for k in x.keys() if \"nfn\" in k] +\n            ([x['spinenet'].repeat(1, 2, 1)] if \"spinenet\" in x else []),\n            -1\n        )\n\n        fts_ss = torch.cat(\n            [fts[:, 15:]] +\n            [x[k].view(bs, -1, 3) for k in x.keys() if \"ss\" in k] +\n            ([x['spinenet'].repeat(1, 2, 1)] if \"spinenet\" in x else []),\n            -1\n        )\n\n        logits[:, :5] = self.logits_scs(fts_scs)\n        logits[:, 5:15] = self.logits_nfn(fts_nfn)\n        logits[:, 15:] = self.logits_ss(fts_ss)\n\n        # logits[:, 5: 15] = self.logits_nfn(x[\"nfn_crop_coords\"].view(bs, 10, 3))\n\n        return logits, torch.zeros(bs)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:41:12.347600Z","iopub.execute_input":"2024-10-07T18:41:12.347926Z","iopub.status.idle":"2024-10-07T18:41:12.372964Z","shell.execute_reply.started":"2024-10-07T18:41:12.347895Z","shell.execute_reply":"2024-10-07T18:41:12.372049Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_2 = df_meta[\n    [\"study_id\", \"series_id\", \"series_description\"]\n].groupby('study_id').agg(list).reset_index()\n\nall_preds = []\nfor exp_folder in EXP_FOLDERS_2:\n    config_2 = Config(json.load(open(exp_folder + \"config.json\", \"r\")))\n\n#     # LOCAL\n#     csv_fts = {}\n#     for k in config_2.exp_folders:\n#         if \"ch\" in k or \"dh\" in k:\n#             file = torch.load(config_2.exp_folders[k])\n#             csv_fts[k] = dict(zip(\n#                 file[\"study_id\"].tolist(),\n#                 file['logits'].float().cpu().numpy(),\n#             ))\n    dataset = FeatureInfDataset(\n        df_2,\n        config_2.exp_folders,\n        crop_fts,\n        csv_fts,\n        save_folder=SAVE_FOLDER,\n    )\n    dataset = SafeDataset(dataset)\n\n    model = define_model_2(\n        config_2.name,\n        ft_dim=config_2.ft_dim,\n        layer_dim=config_2.layer_dim,\n        dense_dim=config_2.dense_dim,\n        p=config_2.p,\n        n_fts=config_2.n_fts,\n        resize=config_2.resize,\n        num_classes=config_2.num_classes,\n        num_classes_aux=config_2.num_classes_aux,\n    )\n    model = model.eval().cuda()\n\n    for fold in FOLDS_2:\n        weights = exp_folder + f\"{config_2.name}_{fold}.pt\"\n        model = load_model_weights(model, weights, verbose=config_2.local_rank == 0)\n\n        preds, _ = predict(\n            model,\n            dataset,\n            {\"activation\": \"\"},\n            batch_size=BATCH_SIZE_2,\n            use_fp16=USE_FP16,\n            num_workers=NUM_WORKERS,\n        )\n\n#         preds[:, :5, 0] += DELTA_SCS[0]\n#         preds[:, :5, 1] += DELTA_SCS[1]\n#         preds[:, :5, 2] += DELTA_SCS[2]\n\n        preds = softmax(preds, axis=-1)\n\n#         print(preds[:, :5, 2].mean())\n#         print(preds[:, :5, 1].mean())\n\n        if DEBUG and not EVAL:\n            preds_ref = np.load(EXP_FOLDERS_2[0] + f\"pred_val_{fold}.npy\")[:1]\n            delta = np.abs(preds - preds_ref).max()\n            print(f\"Model {exp_folder} delta:\", delta)\n\n        all_preds.append(preds)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:41:12.374816Z","iopub.execute_input":"2024-10-07T18:41:12.375155Z","iopub.status.idle":"2024-10-07T18:41:12.629659Z","shell.execute_reply.started":"2024-10-07T18:41:12.375124Z","shell.execute_reply":"2024-10-07T18:41:12.628516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = np.mean(all_preds, 0).astype(np.float64)\nstudies = df_2[[\"study_id\"]].copy().astype(int)\n\nrows = []\nfor i in range(len(studies)):\n    for c, injury in enumerate(config_2.targets):\n        rows.append(\n            {\n                \"row_id\": f'{studies[\"study_id\"].values[i]}_{injury}',\n                \"normal_mild\": preds[i, c, 0],\n                \"moderate\": preds[i, c, 1],\n                \"severe\": preds[i, c, 2],\n            }\n        )\n\nsub = pd.DataFrame(rows)\nsub.to_csv(\"submission.csv\", index=False)\nsub.head(25)","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:41:12.631255Z","iopub.execute_input":"2024-10-07T18:41:12.631622Z","iopub.status.idle":"2024-10-07T18:41:12.657163Z","shell.execute_reply.started":"2024-10-07T18:41:12.631590Z","shell.execute_reply":"2024-10-07T18:41:12.656185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if EVAL:\n    y = pd.read_csv(ROOT_DATA_DIR + \"train.csv\")\n\n    for c in y.columns[1:]:\n        y[c] = y[c].map(dict(zip(SEVERITIES, [0, 1, 2]))).fillna(-1)\n    y = y.astype(int)\n\n    df_val = studies.copy().merge(y, how=\"left\")\n\n    avg_loss, losses = rsna_loss(df_val[config_2.targets].values, preds, verbose=1)\n\n    for k, v in losses.items():\n        print(f\"- {k}_loss\\t: {v:.3f}\")\n\n    print(f\"\\n -> CV Score : {avg_loss :.3f}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:41:12.658354Z","iopub.execute_input":"2024-10-07T18:41:12.658672Z","iopub.status.idle":"2024-10-07T18:41:12.665666Z","shell.execute_reply.started":"2024-10-07T18:41:12.658647Z","shell.execute_reply":"2024-10-07T18:41:12.664655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -r *.gz *.pkl *.pth","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:42:57.584815Z","iopub.execute_input":"2024-10-07T18:42:57.585566Z","iopub.status.idle":"2024-10-07T18:42:58.629006Z","shell.execute_reply.started":"2024-10-07T18:42:57.585522Z","shell.execute_reply":"2024-10-07T18:42:58.627851Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -r test*","metadata":{"execution":{"iopub.status.busy":"2024-10-07T18:42:59.037267Z","iopub.execute_input":"2024-10-07T18:42:59.038135Z","iopub.status.idle":"2024-10-07T18:43:00.070301Z","shell.execute_reply.started":"2024-10-07T18:42:59.038099Z","shell.execute_reply":"2024-10-07T18:43:00.069078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Done ! ","metadata":{}}]}