{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"from pip._internal import main as pipmain\nimport subprocess\n# !conda install -c conda-forge gdcm -y\nsubprocess.getoutput('cp ../input/gdcm-conda-install/gdcm.tar .')\nsubprocess.getoutput('tar -xvzf gdcm.tar')\nsubprocess.getoutput('conda install --offline ./gdcm/gdcm-2.8.9-py37h71b2a6d_0.tar.bz2')\npipmain(['install', '../input/pretrained-models/pretrained-models.pytorch-master'])\npipmain(['install', '../input/geffnet/gen-efficientnet-pytorch/gen-efficientnet-pytorch-master'])\nprint(\"done\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(action='once')\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pylab as plt\nimport datetime\nfrom IPython.core.interactiveshell import InteractiveShell\nInteractiveShell.ast_node_interactivity = \"all\"\nimport pickle\n%load_ext autoreload\n%autoreload 2\n%matplotlib inline\nfrom misclib import *\nfrom processdata import *\nfrom pytorchmodels import *\nimport torch\nimport torch.nn as nn\nimport torch.utils.data as D\nimport torch.nn.functional as F\nimport copy\nfrom torchvision import transforms\nimport PIL.Image\nfrom sklearn.metrics import roc_auc_score\nimport torchvision.transforms.functional as TF\nfrom types import MethodType\n#import sandesh\nimport pydicom\nimport os","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"params=json_to_parameters('../input/rsna2020-config/kaggle_config.json')\ndo_full=False\ndo_z=False\nnum_folds=5\nSEED=220\nparams=json_to_parameters('../input/rsna2020-config/kaggle_config.json')\ndo_full=False\ndo_z=False\nnum_folds=5\nSEED=220\nmodels=[{'inference_fold':0,\n        'model_type':'tf_efficientnet_b5_ns',\n        'base_version':1,\n        'output_size':11,\n        'pool':False,\n        'name_tamplate':'image_{}',\n        'transformer':[{'transformer_version':2,\n        'num_heads':2,\n        'num_layers':4,\n        'ffdim':2048,\n        'max_len':128,\n        'tta':15,\n        'noise':0.3,\n        'transformer_tamplate_add':''}]},\n        {'inference_fold':2,\n        'model_type':'tf_efficientnet_b5_ns',\n        'base_version':'pd',\n        'output_size':11,\n        'pool':True,\n        'name_tamplate':'image_{}',\n        'transformer':[{'transformer_version':'pdn03f02t128',\n        'num_heads':2,\n        'num_layers':4,\n        'ffdim':3072,\n        'max_len':128,\n        'tta':15,\n        'noise':0.3,\n        'transformer_tamplate_add':''}]},\n        {'inference_fold':1,\n        'model_type':'tf_efficientnet_b5_ns',\n        'base_version':'pdint',\n        'output_size':12,\n        'pool':True,\n        'name_tamplate':'image_{}',\n        'transformer':[{'transformer_version':'pdint128n03f02',\n        'num_heads':4,\n        'num_layers':4,\n        'max_len':128,\n        'tta':15,\n        'noise':0.3,\n        'ffdim':3072,\n        'transformer_tamplate_add':''}]},\n        {'inference_fold':0,\n        'model_type':'tf_efficientnet_b3_ns',\n        'base_version':'slice',\n        'output_size':12,\n        'pool':False,\n        'name_tamplate':'image_{}',\n        'transformer':[{'transformer_version':'slice',\n        'num_heads':4,\n        'num_layers':6,\n        'ffdim':2048,\n        'max_len':128,\n        'tta':15,\n        'noise':0.3,\n        'transformer_tamplate_add':''}]}]\n#         'model_type':'tf_efficientnet_b5_ns',\n#         'base_version':1,\n#         'output_size':11,\n#         'pool':False,\n#         'name_tamplate':'image_{}',\n#         'transformer':[{'transformer_version':2,\n#         'num_heads':2,\n#         'num_layers':4,\n#         'ffdim':2048,\n#         'transformer_tamplate_add':''},\n#         {'transformer_version':2,\n#         'num_heads':4,\n#         'num_layers':4,\n#         'ffdim':2048,\n#         'transformer_tamplate_add':''},\n#         {'transformer_version':2,\n#         'num_heads':2,\n#         'num_layers':4,\n#         'ffdim':3072,\n#         'transformer_tamplate_add':''}]}]\nfor mp in models:\n    for t in mp['transformer']:\n        t['transformer_name_tamplate']='transformer'+t['transformer_tamplate_add']+f'_{t[\"num_heads\"]}_{t[\"num_layers\"]}_{t[\"ffdim\"]}_'+'{}'\n\nseed_add = 123\nnum_tta=1\n# transformer_tta=15\n# max_len=128\ncols=  ['rv_lv_ratio_gte_1',\n        'rv_lv_ratio_lt_1',\n        'leftsided_pe',\n        'chronic_pe',\n        'negative_exam_for_pe',\n        'rightsided_pe',\n        'acute_and_chronic_pe',\n        'central_pe',\n        'indeterminate']\ncols_dict=dict(zip(cols,range(len(cols))))\nif params.platform=='myserver':\n    device = device_by_name('RTX')\n    numworkers=12\n    base_batch=32\n    trans_batch=32\n    img_type='pkl'\nelse:\n    device=('cuda:0')\n    numworkers=2\n    base_batch=16\n    trans_batch=32\n    img_type='dicom'\ntorch.cuda.set_device(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test_imgs = glob.glob(f\"{params.path.test}*/*/*\")\n# errored_files=[]\n# col = ['sop_instance_uid','study_instance_uid','series_instance_uid','instance_number','file_name']\n# df=dicom_get_df_data(test_imgs,image_stats=False,errored_files=errored_files,key_list=col)    \n# gp=df[['study_instance_uid','series_instance_uid','instance_number']].groupby(['series_instance_uid'])\n# gp_slice=gp.instance_number.agg(min_slice='min',max_slice='max').reset_index()\n# df=df.merge(gp_slice,on='series_instance_uid',how='left')\n# df['rel_slice']=(df.instance_number-df.min_slice)/(df.max_slice-df.min_slice)\n# df.rename(columns = {'sop_instance_uid':'SOPInstanceUID', 'study_instance_uid':'StudyInstanceUID', \n#                           'series_instance_uid':'SeriesInstanceUID'}, inplace = True)\n# print (f'create df is done size of df {df.shape}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from os import path\nif path.exists('../input/rsna-str-pulmonary-embolism-detection/train') and not do_full:\n    df=pd.read_csv(params.path.data+'test.csv').head(3000)\nelse:\n    df=pd.read_csv(params.path.data+'test.csv')\n# df.to_csv('public_test.csv', index = False)\nfile_names=df.StudyInstanceUID+'/'+df.SeriesInstanceUID+'/'+df.SOPInstanceUID+'.dcm'\n\npos=np.zeros(df.shape[0],dtype=np.long)\nprint ('start reading dicom for pos')\nload_fail=0\nfor i,f in enumerate(file_names):\n    try:\n        img_dicom = pydicom.read_file(params.path.test+f)\n        pos[i] = img_dicom.InstanceNumber if not do_z else float(img_dicom.ImagePositionPatient[-1]) \n    except Exception as e:\n        print (filename,e)\n        pos[i]=0\n        load_fail=load_fail+1\n\nif not do_z:\n    df['instance_number']=pos\n    gp=df[['StudyInstanceUID','SeriesInstanceUID','instance_number']].groupby(['SeriesInstanceUID'])\n    gp_slice=gp.instance_number.agg(min_slice='min',max_slice='max').reset_index()\n    df=df.merge(gp_slice,on='SeriesInstanceUID',how='left')\n    df['rel_slice']=(df.instance_number-df.min_slice)/(df.max_slice-df.min_slice)\nelse:\n    df['z']=pos\n    gp=df[['StudyInstanceUID','SeriesInstanceUID','z']].groupby(['SeriesInstanceUID'])\n    gp_slice=gp.z.agg(z_min='min',z_max='max').reset_index()\n    df=df.merge(gp_slice,on='SeriesInstanceUID',how='left')\n    df['rel_slice']=(df.z-df.z_min)/1200\n    df=df.sort_values('z').reset_index(drop=True)\n    df['instance_number']=df[['SeriesInstanceUID','SOPInstanceUID']].groupby('SeriesInstanceUID')['SOPInstanceUID'].cumcount()+1\n\n\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# define transforms\ntransform=transforms.Compose([RandomResizedCropTransform(scale=(0.7, 1.3), ratio=(0.7, 1.3)),\n                              RotateTransform(25),\n                              RandomFlipTransform(0.5,0.5),\n                              RandomChangeMeanStdTransform(30,0.1),\n                              CutoutTransform(0.5,0.2),\n                              CutoutTransform(0.25,0.3),\n                              ResizeTransform(512,512)])\n\ntransform_val=transforms.Compose([ResizeTransform(512,512)])\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MinDif():\n    def __init__(self,d):\n        self.d=d\n    def __call__(self,key):\n        return abs(self.d.__getitem__(key)-0.5).min()\n    \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"studydict={key:[] for key in df.loc[:,'StudyInstanceUID']}\nimage_dict={key:[] for key in df.loc[:,'SOPInstanceUID']}\nstudydict_res={key:[] for key in df.loc[:,'StudyInstanceUID']}\nimage_dict_res={key:[] for key in df.loc[:,'SOPInstanceUID']}\nsub_df=df.copy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"seed_add=0\nak=[3,3,6,6]\nbk=[60,60,150,150]\nfor kk,mp in enumerate(models): #(fold,model_type,model_version) in zip(inference_folds,model_types,base_versions):\n    # create features\n    image_reader=ImageReader(params.path.test,image_type='dicom',return_pos=False)\n    ds=ImageDataset(image_reader,sub_df,transform=transform_val)\n    #model_version=base_version\n    fold=mp['inference_fold']\n    model_type=mp['model_type']\n    model_version=mp['base_version']\n    name_tamplate=mp['name_tamplate']\n    output_size=mp['output_size']\n    torch.manual_seed(SEED+fold+seed_add)\n    np.random.seed(SEED+fold+seed_add)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    model = get_model(model_type,output_size=output_size, feature_size =256,amp=True,pretrained=False,pool=mp['pool']).to(device)\n    name=params.model_format.format(model_type,name_tamplate.format(SEED),model_version,fold)\n    print (name)\n    model.load_state_dict(torch.load(f'{params.path.models}{name}',map_location=device))\n    model.last_linear=Noop()\n    model=model.eval()\n    ds=ImageDataset(image_reader,sub_df,transform=transform_val,file_ext='.dcm')\n    print(f'starting with features for {name}')\n    dl=D.DataLoader(ds,num_workers=numworkers,batch_size=base_batch,shuffle=False)\n    features=np.zeros((len(ds),256),dtype=np.float32)\n    k=0\n    with torch.no_grad():\n#             tk0 = notebook.tqdm(dl) if verbose else dl\n        for i,batch in enumerate(notebook.tqdm(dl)):\n            features[k:k+batch[0].shape[0]]= model(batch[0].to(device)).to('cpu').detach().numpy()  \n            k=k+batch[0].shape[0]\n    featuress=[features]\n    print (f'featuress len {len(featuress)} just added {featuress[-1].shape}')\n    if num_tta>1:\n        ds=ImageDataset(image_reader,sub_df,transform=transform,file_ext='.dcm')\n        dl=D.DataLoader(ds,num_workers=numworkers,batch_size=base_batch,shuffle=False)\n        for i in range(num_tta-1):\n            features=np.zeros((len(ds),256),dtype=np.float32)\n            k=0\n            with torch.no_grad():\n    #             tk0 = notebook.tqdm(dl) if verbose else dl\n                for i,batch in enumerate(notebook.tqdm(dl)):\n                    features[k:k+batch[0].shape[0]]= model(batch[0].to(device)).to('cpu').detach().numpy()  \n                    k=k+batch[0].shape[0]\n            featuress.append(features)\n        print (f'ffeaturess len {len(featuress)} just added {featuress[-1].shape}')\n    features=np.stack(featuress,0)\n#         with open(params.path.features+(name.split('.')[0]+'.pkl'),'wb') as f:\n#             pickle.dump(features,f,protocol=4)\n#         del features,featuress\n#         print (f'features are saved for {name}')\n\n    preds=[]\n    inds=[]\n    all_patients=sub_df.SeriesInstanceUID.unique()\n    fold=mp['inference_fold']\n    model_type=mp['model_type']\n    base_version=mp['base_version']\n    name_tamplate=mp['name_tamplate']\n#         basic_name=params.model_format.format(model_type,name_tamplate.format(SEED),base_version,fold).split('.')[0]+'.pkl'\n#         with open(params.path.features+basic_name,'rb') as f:\n#             features=torch.tensor(pickle.load(f),dtype=torch.float32)\n#         print(f'features loaded {basic_name}')\n    for tr in mp['transformer']:\n        ffdim=tr['ffdim']\n        num_layers=tr['num_layers']\n        num_heads=tr['num_heads']\n        transformer_name_tamplate=tr['transformer_name_tamplate']\n        transformer_version=tr['transformer_version']\n        max_len=tr['max_len']\n        transformer_tta=tr['tta']\n        fnoise=tr['noise']\n        ds=PatientFeaturesDataset(torch.tensor(features,dtype=torch.float32),sub_df,all_patients,max_len=max_len,rand_split=(transformer_tta>1),rep=1,fnoise=fnoise)\n        model = get_transformer_model(dim_feedforward=ffdim,n_heads=num_heads,n_encoders=num_layers).to(device)\n        name=params.model_format.format(model_type,transformer_name_tamplate.format(SEED),transformer_version,fold)\n        model.load_state_dict(torch.load(f'{params.path.models}{name}',map_location=device))\n        model=model.eval()\n        print('start predicting')\n        for t in range(transformer_tta):\n            ds.reset()\n            dl=D.DataLoader(ds,num_workers=numworkers,batch_size=trans_batch,shuffle=False)\n            p=np.zeros((len(ds),max_len,14),dtype=np.float32)\n            ri=np.zeros((len(ds),max_len),dtype=np.long)\n            k=0\n            with torch.no_grad():\n    #             tk0 = notebook.tqdm(dl) if verbose else dl\n                for i,batch in enumerate(dl):\n                    y = model(batch[0].to(device),batch[1].to(device),batch[2].to(device),mask=(batch[1]==-1).to(device))\n                    p[k:k+batch[0].shape[0]]= y.to('cpu').detach().numpy()\n                    ri[k:k+batch[0].shape[0]] = batch[-1]\n                    k=k+batch[0].shape[0]\n\n            preds.append(p)\n            inds.append(ri)\n            print(f'{t} {name} finished')\n\n    #ensemble results\n    for t,p in enumerate(preds):\n        idxs=inds[t]\n        for i,pl in enumerate(p):\n            studydict[sub_df.loc[idxs[i,0],'StudyInstanceUID']].append(pl[-1,5:])\n            for j,ind in enumerate(idxs[i][idxs[i]>=0]):\n                image_dict[sub_df.loc[ind,'SOPInstanceUID']].append(pl[j,0])\n    for key in studydict_res.keys():\n        studydict_res[key]=torch.sigmoid(torch.tensor(np.mean(studydict[key],0))).numpy()\n    for key in image_dict_res.keys():\n        image_dict_res[key]=torch.sigmoid(torch.tensor(np.mean(image_dict[key],0))).item()\n\n    needs2=sorted(studydict_res,key = MinDif(studydict_res))[:len(studydict_res)//ak[kk]]\n    needs2_image=df[df.SOPInstanceUID.isin(sorted(image_dict_res,key =image_dict_res.__getitem__ )[:len(image_dict_res)//bk[kk]])].StudyInstanceUID.unique().tolist()\n    sub_df=df[(df.StudyInstanceUID.isin(needs2)) | (df.StudyInstanceUID.isin(needs2_image))].reset_index(drop=True).copy()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# [len(studydict[key]) for key in studydict.keys()]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#check consistency \ndef find_conflicts(studydict,image_dict):\n    conflict=[]\n    image_conflict=[]\n    h=np.arange(9)\n    for key in studydict.keys():\n        images=df[df.StudyInstanceUID==key].SOPInstanceUID.values\n        image_values=np.array([image_dict[image_key] for image_key in images])\n        if studydict[key][cols_dict['negative_exam_for_pe']]>0.5:\n            image_conflict.extend(images[image_values>0.5])\n            if studydict[key][h!=cols_dict['negative_exam_for_pe']].max()>0.5:\n                conflict.append(key)\n                continue\n        elif studydict[key][cols_dict['indeterminate']]>0.5:\n            image_conflict.extend(images[image_values>0.5])\n            if studydict[key][h!=cols_dict['indeterminate']].max()>0.5:\n                conflict.append(key)\n                continue\n                \n        else:\n            if image_values.max()<=0.5:\n                    conflict.append(key)\n                    continue            \n            if (studydict[key][cols_dict['rv_lv_ratio_gte_1']]>0.5)==(studydict[key][cols_dict['rv_lv_ratio_lt_1']]>0.5):\n                conflict.append(key)\n                continue\n            if (studydict[key][[cols_dict['chronic_pe'],cols_dict['acute_and_chronic_pe']]]>0.5).sum()>1:\n                    conflict.append(key)\n                    continue\n            if studydict[key][[cols_dict['central_pe'],\n                              cols_dict['rightsided_pe'],\n                             cols_dict['leftsided_pe']]].max()<=0.5:\n                    conflict.append(key)\n                    continue\n    return conflict,image_conflict\n        \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"c=find_conflicts(studydict_res,image_dict_res)\nprint(len(c[0]),len(c[1]))\nh=np.arange(9)\n\nfor key in studydict_res.keys():\n    if studydict_res[key][cols_dict['negative_exam_for_pe']]>0.5:\n        if studydict_res[key][h!=cols_dict['negative_exam_for_pe']].max()>studydict_res[key][cols_dict['negative_exam_for_pe']]:\n            studydict_res[key][cols_dict['negative_exam_for_pe']]=0.4999\n        else:\n            studydict_res[key][h!=cols_dict['negative_exam_for_pe']]=np.clip(studydict_res[key][h!=cols_dict['negative_exam_for_pe']],0,0.4999)\nfor key in studydict_res.keys():\n    if studydict_res[key][cols_dict['indeterminate']]>0.5:\n        if studydict_res[key][h!=cols_dict['indeterminate']].max()>studydict_res[key][cols_dict['indeterminate']]:\n            studydict_res[key][cols_dict['indeterminate']]=0.4999\n        else:\n            studydict_res[key][h!=cols_dict['indeterminate']]=np.clip(studydict_res[key][h!=cols_dict['indeterminate']],0,0.4999)\n\nfor key in studydict_res.keys():\n    if studydict_res[key][cols_dict['negative_exam_for_pe']]>0.5 or studydict_res[key][cols_dict['indeterminate']]>0.5:\n        images=df[df.StudyInstanceUID==key].SOPInstanceUID.values\n        for image_key in images:\n            image_dict_res[image_key] = min(image_dict_res[image_key],0.4999)\n    else:\n        images=df[df.StudyInstanceUID==key].SOPInstanceUID.values\n        am=np.argmax(np.array([image_dict_res[image_key] for image_key in images]))\n        image_dict_res[images[am]]=0.5001\n\nfor key in studydict_res.keys():\n    if studydict_res[key][cols_dict['negative_exam_for_pe']]<=0.5 and studydict_res[key][cols_dict['indeterminate']]<=0.5:\n        if (studydict_res[key][cols_dict['rv_lv_ratio_gte_1']]>0.5)==(studydict_res[key][cols_dict['rv_lv_ratio_lt_1']]>0.5):\n            if studydict_res[key][cols_dict['rv_lv_ratio_gte_1']]>0.5:\n                if studydict_res[key][cols_dict['rv_lv_ratio_gte_1']]>studydict_res[key][cols_dict['rv_lv_ratio_lt_1']]:\n                    studydict_res[key][cols_dict['rv_lv_ratio_lt_1']]=0.4999\n                else:\n                    studydict_res[key][cols_dict['rv_lv_ratio_gte_1']]=0.4999\n            else:\n                if studydict_res[key][cols_dict['rv_lv_ratio_gte_1']]<studydict_res[key][cols_dict['rv_lv_ratio_lt_1']]:\n                    studydict_res[key][cols_dict['rv_lv_ratio_lt_1']]=0.5001\n                else:\n                    studydict_res[key][cols_dict['rv_lv_ratio_gte_1']]=0.5001\n                \n        if (studydict_res[key][[cols_dict['chronic_pe'],cols_dict['acute_and_chronic_pe']]]>0.5).sum()>1:\n            if studydict_res[key][cols_dict['chronic_pe']]>studydict_res[key][cols_dict['acute_and_chronic_pe']]:\n                studydict_res[key][cols_dict['acute_and_chronic_pe']]=0.4999\n            else:\n                studydict_res[key][cols_dict['chronic_pe']]=0.4999\n        if studydict_res[key][[cols_dict['central_pe'],\n                          cols_dict['rightsided_pe'],\n                         cols_dict['leftsided_pe']]].max()<=0.5:\n            am = np.argmax(studydict_res[key][[cols_dict['central_pe'],\n                          cols_dict['rightsided_pe'],\n                         cols_dict['leftsided_pe']]])\n            studydict_res[key][[cols_dict['central_pe'],\n                          cols_dict['rightsided_pe'],\n                         cols_dict['leftsided_pe']][am]]=0.501\nc=find_conflicts(studydict_res,image_dict_res)\nprint(len(c[0]),len(c[1]))\nfor i in c[0]:\n    print(i,studydict_res[i])\nfor i in c[1]:\n    print (i,image_dict_res[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def check_consistency(sub, test):    \n    '''\n    Checks label consistency and returns the errors\n    \n    Args:\n    sub   = submission dataframe (pandas)\n    test  = test.csv dataframe (pandas)\n    '''\n    \n    # EXAM LEVEL\n    for i in test['StudyInstanceUID'].unique():\n        df_tmp = sub.loc[sub.id.str.contains(i, regex = False)].reset_index(drop = True)\n        df_tmp['StudyInstanceUID'] = df_tmp['id'].str.split('_').str[0]\n        df_tmp['label_type']       = df_tmp['id'].str.split('_').str[1:].apply(lambda x: '_'.join(x))\n        del df_tmp['id']\n        if i == test['StudyInstanceUID'].unique()[0]:\n            df = df_tmp.copy()\n        else:\n            df = pd.concat([df, df_tmp], axis = 0)\n    df_exam = df.pivot(index = 'StudyInstanceUID', columns = 'label_type', values = 'label')\n    \n    # IMAGE LEVEL\n    df_image = sub.loc[sub.id.isin(test.SOPInstanceUID)].reset_index(drop = True)\n    df_image = df_image.merge(test, how = 'left', left_on = 'id', right_on = 'SOPInstanceUID')\n    df_image.rename(columns = {\"label\": \"pe_present_on_image\"}, inplace = True)\n    del df_image['id']\n    \n    # MERGER\n    df = df_exam.merge(df_image, how = 'left', on = 'StudyInstanceUID')\n    ids    = ['StudyInstanceUID', 'SeriesInstanceUID', 'SOPInstanceUID']\n    labels = [c for c in df.columns if c not in ids]\n    df = df[ids + labels]\n    \n    # SPLIT NEGATIVE AND POSITIVE EXAMS\n    df['positive_images_in_exam'] = df['StudyInstanceUID'].map(df.groupby(['StudyInstanceUID']).pe_present_on_image.max())\n    df_pos = df.loc[df.positive_images_in_exam >  0.5]\n    df_neg = df.loc[df.positive_images_in_exam <= 0.5]\n    \n    # CHECKING CONSISTENCY OF POSITIVE EXAM LABELS\n    rule1a = df_pos.loc[((df_pos.rv_lv_ratio_lt_1  >  0.5)  & \n                         (df_pos.rv_lv_ratio_gte_1 >  0.5)) | \n                        ((df_pos.rv_lv_ratio_lt_1  <= 0.5)  & \n                         (df_pos.rv_lv_ratio_gte_1 <= 0.5))].reset_index(drop = True)\n    rule1a['broken_rule'] = '1a'\n    rule1b = df_pos.loc[(df_pos.central_pe    <= 0.5) & \n                        (df_pos.rightsided_pe <= 0.5) & \n                        (df_pos.leftsided_pe  <= 0.5)].reset_index(drop = True)\n    rule1b['broken_rule'] = '1b'\n    rule1c = df_pos.loc[(df_pos.acute_and_chronic_pe > 0.5) & \n                        (df_pos.chronic_pe           > 0.5)].reset_index(drop = True)\n    rule1c['broken_rule'] = '1c'\n    rule1d = df_pos.loc[(df_pos.indeterminate        > 0.5) | \n                        (df_pos.negative_exam_for_pe > 0.5)].reset_index(drop = True)\n    rule1d['broken_rule'] = '1d'\n\n    # CHECKING CONSISTENCY OF NEGATIVE EXAM LABELS\n    rule2a = df_neg.loc[((df_neg.indeterminate        >  0.5)  & \n                         (df_neg.negative_exam_for_pe >  0.5)) | \n                        ((df_neg.indeterminate        <= 0.5)  & \n                         (df_neg.negative_exam_for_pe <= 0.5))].reset_index(drop = True)\n    rule2a['broken_rule'] = '2a'\n    rule2b = df_neg.loc[(df_neg.rv_lv_ratio_lt_1     > 0.5) | \n                        (df_neg.rv_lv_ratio_gte_1    > 0.5) |\n                        (df_neg.central_pe           > 0.5) | \n                        (df_neg.rightsided_pe        > 0.5) | \n                        (df_neg.leftsided_pe         > 0.5) |\n                        (df_neg.acute_and_chronic_pe > 0.5) | \n                        (df_neg.chronic_pe           > 0.5)].reset_index(drop = True)\n    rule2b['broken_rule'] = '2b'\n    \n    # MERGING INCONSISTENT PREDICTIONS\n    errors = pd.concat([rule1a, rule1b, rule1c, rule1d, rule2a, rule2b], axis = 0)\n    \n    # OUTPUT\n    print('Found', len(errors), 'inconsistent predictions')\n    return errors","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# image_dict.update({f'{key}_{col}': studydict[key][i] for key in studydict.keys() for i,col in enumerate(cols)})\n# res_df=pd.DataFrame(data={'id':list(image_dict.keys()),'label':list(image_dict.values())})\n\n# res_df.to_csv('submission.csv', index = False)\n# res_df.head(10)\n# res_df.tail(10)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create submission file\nif len(c[0])+len(c[1])==0:\n    image_dict_res.update({f'{key}_{col}': studydict_res[key][i] for key in studydict_res.keys() for i,col in enumerate(cols)})\n    res_df=pd.DataFrame(data={'id':list(image_dict_res.keys()),'label':list(image_dict_res.values())})\n    errors=check_consistency(res_df, df)\n    if len(errors)==0 and load_fail==0:\n        res_df.to_csv('submission.csv', index = False)\n        res_df.head(10)\n        res_df.tail(10)\nelse:\n    image_dict_res.update({f'{key}_{col}': studydict_res[key][i] for key in studydict_res.keys() for i,col in enumerate(cols)})\n    res_df=pd.DataFrame(data={'id':list(image_dict_res.keys()),'label':list(image_dict_res.values())})\n    res_df.to_csv('no_submission.csv', index = False)\n    res_df.head(10)\n    res_df.tail(10)\n\n    print(c)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}