def leave_one_out_by_subject(dic_path, dic_3d, denoising=True, reg='Affine', metric='MI', use_levels=True, weight=2.5, eq=1, mode_weighted_sim=False, weighted_label_fusion=False):
    """
    Leave one out cross validation taking 1 SUBJECT out of the dictionary at each step
    and computing the resulting dice coefficient, the time of computation and an error map

    :param dic_path: path to the dictionary to use to do the model validation

    """
    import time
    from msct_multiatlas_seg import Model, SegmentationParam, SupervisedSegmentationMethod
    from sct_segment_graymatter import FullGmSegmentation
    init = time.time()

    wm_dice_file = open('wm_dice_coeff.txt', 'w')
    gm_dice_file = open('gm_dice_coeff.txt', 'w')
    wm_csa_file = open('wm_csa.txt', 'w')
    gm_csa_file = open('gm_csa.txt', 'w')
    hd_file = open('hd.txt', 'w')
    n_slices = 0
    e = None

    level_label = {0: '', 1: 'C1', 2: 'C2', 3: 'C3', 4: 'C4', 5: 'C5', 6: 'C6', 7: 'C7', 8: 'T1', 9: 'T2', 10: 'T3', 11: 'T4', 12: 'T5', 13: 'T6'}
    # for the error map
    gm_diff_by_level = {'C1': [], 'C2': [], 'C3': [], 'C4': [], 'C5': [], 'C6': [], 'C7': [], 'T1': [], 'T2': [], '': []}
    wm_diff_by_level = {'C1': [], 'C2': [], 'C3': [], 'C4': [], 'C5': [], 'C6': [], 'C7': [], 'T1': [], 'T2': [], '': []}

    for subject_dir in os.listdir(dic_path):
        subject_path = dic_path + '/' + subject_dir
        if os.path.isdir(subject_path):
            try:
                tmp_dir = 'tmp_' + subject_dir + '_as_target'
                sct.run('mkdir ' + tmp_dir)

                tmp_dic_name = 'dic'
                sct.run('cp -r ' + dic_path + ' ./' + tmp_dir + '/' + tmp_dic_name + '/')
                sct.run('cp -r ' + dic_3d + '/' + subject_dir + ' ./' + tmp_dir + '/')
                sct.run('mv ./' + tmp_dir + '/' + tmp_dic_name + '/' + subject_dir + ' ./' + tmp_dir + '/' + subject_dir + '_by_slice')

                # Gray matter segmentation using this subject as target
                os.chdir(tmp_dir)
                model_param = SegmentationParam()
                model_param.path_model = tmp_dic_name
                model_param.todo_model = 'compute'
                model_param.weight_gamma = float(weight)
                model_param.use_levels = use_levels
                model_param.res_type = 'prob'
                model_param.reg = reg.split(':')
                model_param.reg_metric = metric
                model_param.equation_id = eq
                model_param.mode_weight_similarity = mode_weighted_sim
                model_param.weight_label_fusion = weighted_label_fusion
                model_param.target_denoising = denoising

                model = Model(model_param=model_param, k=0.8)

                n_slices_model = model.dictionary.J

                target = ''
                sc_seg = ''
                ref_gm_seg_im = ''
                level = ''
                for file_name in os.listdir(subject_dir):  # 3d files

                    if 'im' in file_name:
                        target = subject_dir + '/' + file_name
                    elif 'level' in file_name:
                        level = subject_dir + '/' + file_name
                    elif 'gm' in file_name:
                        ref_gm_seg_im = subject_dir + '/' + file_name
                    elif file_name in 'seg':
                        sc_seg = subject_dir + '/' + file_name


                full_gmseg = FullGmSegmentation(target, sc_seg, None, level, ref_gm_seg=ref_gm_seg_im, model=model, param=model_param)

                # ## VALIDATION ##
                # Dice coeff
                subject_dice = open(full_gmseg.dice_name, 'r')
                dice_lines_list = subject_dice.readlines()
                subject_dice.close()

                gm_dices = None
                wm_dices = None
                n_subject_slices = len(full_gmseg.gm_seg.target_seg_methods.target)
                n_slices += n_subject_slices

                for i, line in enumerate(dice_lines_list):
                    if 'Gray Matter' in line:
                        gm_dices = dice_lines_list[i+10:i+10+n_subject_slices]

                    if 'White Matter' in line:
                        wm_dices = dice_lines_list[i+10:i+10+n_subject_slices]

                subject_slices_levels = {}
                for slice_dice in wm_dices:
                    target_slice, wm_dice = slice_dice[:-1].split(' ')

                    if int(target_slice) < 10:
                        target_slice = 'slice0' + target_slice
                    else:
                        target_slice = 'slice' + target_slice

                    slice_level = ''
                    for file_name in os.listdir('./' + subject_dir + '_by_slice'):
                        if target_slice in file_name:
                            slice_level = file_name[file_name.find(target_slice)+8:file_name.find(target_slice)+10]
                            subject_slices_levels[target_slice] = slice_level
                    wm_dice_file.write(subject_dir + ' ' + target_slice + ' ' + slice_level + ': ' + wm_dice + ' ; nslices: ' + str(n_slices_model) + '\n')

                for slice_dice in gm_dices:
                    target_slice, gm_dice = slice_dice[:-1].split(' ')

                    if int(target_slice) < 10:
                        target_slice = 'slice0' + target_slice
                    else:
                        target_slice = 'slice' + target_slice
                    slice_level = subject_slices_levels[target_slice]

                    gm_dice_file.write(subject_dir + ' ' + target_slice + ' ' + slice_level + ': ' + gm_dice + ' ; nslices: ' + str(n_slices_model) + '\n')

                # hausdorff distance
                subject_hd = open(full_gmseg.hausdorff_name, 'r')
                hd_res_list = subject_hd.readlines()[1:-4]
                for line in hd_res_list:
                    n_slice, res_slice = line.split(':')
                    hd, med1, med2 = res_slice.split('-')
                    n_slice = n_slice[-1:]
                    med1 = float(med1)
                    med2 = float(med2[:-2])

                    if int(n_slice) < 10:
                        target_slice = 'slice0' + n_slice
                    else:
                        target_slice = 'slice' + n_slice
                    slice_level = subject_slices_levels[target_slice]
                    hd_file.write(subject_dir + ' ' + target_slice + ' ' + slice_level + ': ' + str(hd) + ' - ' + str(max(med1, med2)) + '\n')

                # error map

                print 'ERROR MAP BY LEVEL COMPUTATION'
                path_validation = full_gmseg.tmp_dir + '/validation/'
                ref_gm_seg_im = Image(path_validation + 'ref_gm_seg.nii.gz')
                ref_wm_seg_im = Image(path_validation + 'ref_wm_seg.nii.gz')
                res_gm_seg_im = Image(path_validation + 'res_gm_seg_bin_RPI.nii.gz')
                res_wm_seg_im = Image(path_validation + 'res_wm_seg_bin_RPI.nii.gz')

                ref_gm_seg_im.change_orientation('IRP')
                ref_wm_seg_im.change_orientation('IRP')
                res_gm_seg_im.change_orientation('IRP')
                res_wm_seg_im.change_orientation('IRP')

                for i_slice in range(len(ref_gm_seg_im.data)):
                    slice_gm_error = abs(ref_gm_seg_im.data[i_slice] - res_gm_seg_im.data[i_slice])
                    slice_wm_error = abs(ref_wm_seg_im.data[i_slice] - res_wm_seg_im.data[i_slice])
                    if int(i_slice) < 10:
                        target_slice = 'slice0' + str(i_slice)
                    else:
                        target_slice = 'slice' + str(i_slice)
                    slice_level = subject_slices_levels[target_slice]
                    gm_diff_by_level[slice_level].append(slice_gm_error)
                    wm_diff_by_level[slice_level].append(slice_wm_error)

                # csa
                sct.run('sct_process_segmentation -i ' + full_gmseg.res_names['corrected_wm_seg'] + ' -p csa')
                tmp_csa_file = open('csa.txt')
                csa_lines = tmp_csa_file.readlines()
                tmp_csa_file.close()
                for slice_csa in csa_lines:
                    target_slice, wm_csa = slice_csa.split(',')
                    if int(target_slice) < 10:
                        target_slice = 'slice0' + target_slice
                    else:
                        target_slice = 'slice' + target_slice
                    slice_level = subject_slices_levels[target_slice]
                    wm_csa_file.write(subject_dir + ' ' + target_slice + ' ' + slice_level + ': ' + wm_csa[:-1] + '\n')
                sct.run('mv csa.txt csa_corrected_wm_seg.txt')

                sct.run('sct_process_segmentation -i ' + full_gmseg.res_names['gm_seg'] + ' -p csa')
                tmp_csa_file = open('csa.txt')
                csa_lines = tmp_csa_file.readlines()
                tmp_csa_file.close()
                for slice_csa in csa_lines:
                    target_slice, gm_csa = slice_csa.split(',')
                    if int(target_slice) < 10:
                        target_slice = 'slice0' + target_slice
                    else:
                        target_slice = 'slice' + target_slice
                    slice_level = subject_slices_levels[target_slice]
                    gm_csa_file.write(subject_dir + ' ' + target_slice + ' ' + slice_level + ': ' + gm_csa[:-1] + '\n')
                sct.run('mv csa.txt csa_gm_seg.txt')

                os.chdir('..')

            except Exception, e:
                sct.printv('WARNING: an error occurred ...', 1, 'warning')
                print e
            # else:
            #    sct.run('rm -rf ' + tmp_dir)
    # error map
    for l, level_error in gm_diff_by_level.items():
        try:
            n = len(level_error)
            if n != 0:
                Image(param=sum(level_error)/n, absolutepath='error_map_gm_' + str(l) + '.nii.gz').save()
        except ZeroDivisionError:
            sct.printv('WARNING: no data for level ' + str(l), 1, 'warning')

    for l, level_error in wm_diff_by_level.items():
        try:
            n = len(level_error)
            if n != 0:
                Image(param=sum(level_error)/n, absolutepath='error_map_wm_' + str(l) + '.nii.gz').save()
        except ZeroDivisionError:
            sct.printv('WARNING: no data for level ' + str(l), 1, 'warning')

    if e is None:
        wm_dice_file.close()
        gm_dice_file.close()
        wm_csa_file.close()
        gm_csa_file.close()
        hd_file.close()

        # Image(param=error_map_abs_sum/n_slices, absolutepath='error_map_abs.nii.gz').save()
        t = time.time() - init
        print 'Done in ' + str(t) + ' sec'


# ------------------------------------------------------------------------------------------------------------------
dataset/ETHPy150Open neuropoly/spinalcordtoolbox/scripts/msct_gmseg_utils.py/leave_one_out_by_subject/swapped operands of `in`