Beispiel #1
0
    def relabel(self, path_to_input_segmentation, path_to_output_segmentation=None,
                list_old_labels=(), list_new_labels=(), path_to_input_labels_descriptor=None,
                path_to_output_labels_descriptor=None):
        """
        Masks of :func:`labels_manager.tools.manipulations.relabeller.relabeller` using filenames
        """

        pfi_in, pfi_out = get_pfi_in_pfi_out(path_to_input_segmentation, path_to_output_segmentation, self.pfo_in,
                                             self.pfo_out)
        im_labels = nib.load(pfi_in)
        data_labels = im_labels.get_data()
        data_relabelled = relabeller(data_labels, list_old_labels=list_old_labels,
                                     list_new_labels=list_new_labels)

        im_relabelled = set_new_data(im_labels, data_relabelled)

        nib.save(im_relabelled, pfi_out)

        if path_to_input_labels_descriptor is not None:
            pfi_in_ld = connect_path_tail_head(self.pfo_in, path_to_input_labels_descriptor)

            ldm_input = LdM(pfi_in_ld, labels_descriptor_convention=self.labels_descriptor_convention)
            ldm_relabelled = ldm_input.relabel(list_old_labels=list_old_labels, list_new_labels=list_new_labels)

            if path_to_output_labels_descriptor is None:
                ldm_relabelled.save_label_descriptor(pfi_in_ld)
            else:
                pfi_out_ld = connect_path_tail_head(self.pfo_out, path_to_output_labels_descriptor)
                ldm_relabelled.save_label_descriptor(pfi_out_ld)

        print('Relabelled image {0} saved in {1}.'.format(pfi_in, pfi_out))
        return pfi_out
def binarise_and_adjust_mask_from_segmentation_path(pfi_segm_input,
                                                    pfi_mask_output,
                                                    pfo_temp,
                                                    subject_name,
                                                    labels_to_exclude=(),
                                                    dil_factor=1,
                                                    ero_factor=1):
    """
    Sequence of topological operation to pass from the manual segmentation to a single binary mask
    covering the brain tissue and excluding the skull.
    :param pfi_segm_input:
    :param pfi_mask_output:
    :param pfo_temp:
    :param subject_name:
    :param labels_to_exclude:
    :param dil_factor: dilation factor before erosion
    :param ero_factor: erosion factor after dilation
    :return:
    """
    pfi_intermediate = jph(pfo_temp,
                           '{}_tmp_binarisation.nii.gz'.format(subject_name))

    print_and_run('cp {} {}'.format(pfi_segm_input, pfi_intermediate))

    if len(labels_to_exclude) > 0:

        im_segm = nib.load(pfi_intermediate)
        array_segm_new_data = relabeller(im_segm.get_data(),
                                         list_old_labels=labels_to_exclude,
                                         list_new_labels=[
                                             0,
                                         ] * len(labels_to_exclude))
        im_segm_new = set_new_data(im_segm, array_segm_new_data)
        nib.save(im_segm_new, pfi_intermediate)

    print_and_run('seg_maths {0} -bin {0}'.format(pfi_intermediate))

    # fill and dil the binarised segmentation
    print_and_run('seg_maths {0} -fill {1}'.format(pfi_intermediate,
                                                   pfi_intermediate))
    print_and_run('seg_maths {0} -dil {1} {0}'.format(pfi_intermediate,
                                                      dil_factor))
    print_and_run('seg_maths {0} -ero {1} {0}'.format(pfi_intermediate,
                                                      ero_factor))
    # print_and_run('seg_maths {0} -fill {0}'.format(pfi_intermediate))

    print_and_run('seg_maths {0} -fill {1}'.format(pfi_intermediate,
                                                   pfi_mask_output))
def island_for_label(array_segm, label, m=0, special_label=-1):
    """
    As ndimage.label, with output ordered by the size of the connected component.
    :param array_segm:
    :param label:
    :param m: integer. If m = 0 the n connected components will be numbered from 1 (biggest) to n (smallest).
                             If m > 0, from the m-th largest components, all the components are set to the special
                             special_label.
    :param special_label: value used if m > 0.
    :return: segmentation with the components sorted.
    -----
    e.g.
    array_segm has 4 components of for the input label.
    If m = 0 it returns the components labelled from 1 to 4, where 1 is the biggest.
    if m = 2 the first two largest components are numbered 1 and 2, and the remaining 2 are labelled with special_label.
    """

    if label not in array_segm:
        print('Label {} not in the provided array.'.format(label))
        return array_segm

    binary_segm_comp, num_comp = ndimage.label(array_segm == label)

    if num_comp == 1:
        return binary_segm_comp

    voxels_per_components = np.array(
        [np.count_nonzero(binary_segm_comp == l + 1) for l in range(num_comp)])
    scores = voxels_per_components.argsort()[::-1] + 1
    new_labels = np.arange(num_comp) + 1

    binary_segm_components_sorted = relabeller(binary_segm_comp,
                                               scores,
                                               new_labels,
                                               verbose=1)

    if m > 0:
        binary_segm_components_sorted[
            binary_segm_components_sorted > m] = special_label

    return binary_segm_components_sorted
Beispiel #4
0
        # data:
        fin_punt_seg_original = 'punt_seg.nii.gz'
        fin_punt_seg_new      = 'punt_seg_relabelled.nii.gz'

        list_old_labels = [1, 2, 3, 4, 5, 6]
        list_new_labels = [2, 3, 4, 5, 6, 7]

        # Using the manager:
        lt.manipulate_labels.relabel(fin_punt_seg_original, fin_punt_seg_new,
                                     list_old_labels, list_new_labels)

        # Without the managers: loading the data and applying the relabeller
        im_seg = nib.load(jph(root_dir, 'data_examples', fin_punt_seg_original))
        data_seg = im_seg.get_data()
        data_seg_new = rel.relabeller(data_seg, list_old_labels, list_new_labels)

        im_relabelled = set_new_data(im_seg, data_seg_new)

        # Results comparison:
        nib_seg_new = nib.load(jph(root_dir, 'data_output', fin_punt_seg_new))
        nib_seg_new_data = nib_seg_new.get_data()
        np.testing.assert_array_equal(data_seg_new, nib_seg_new_data)

        if open_figures:
            # figure before:
            cmd = 'itksnap -g {0} -s {1}'.format(
                   jph(root_dir, 'data_examples', 'punt.nii.gz'),
                   jph(root_dir, 'data_examples', fin_punt_seg_original))
            os.system(cmd)
            # figure after
Beispiel #5
0
def test_relabeller_basic():
    data = np.array(range(10)).reshape(2, 5)
    relabelled_data = relabeller(data, range(10), range(10)[::-1])
    np.testing.assert_array_equal(relabelled_data, np.array(range(10)[::-1]).reshape(2,5))
Beispiel #6
0
def test_relabeller_wrong_input():
    data = np.array(range(10)).reshape(2, 5)
    with np.testing.assert_raises(IOError):
        relabeller(data, [1, 2], [3, 4, 4])
Beispiel #7
0
def test_relabeller_one_element_not_in_array():
    data = np.array(range(10)).reshape(2, 5)
    relabelled_data = relabeller(data, 15, 1, verbose=1)
    np.testing.assert_array_equal(relabelled_data, data)
Beispiel #8
0
def test_relabeller_one_element():
    data = np.array(range(10)).reshape(2, 5)
    relabelled_data = relabeller(data, 0, 1, verbose=1)
    expected_output = data[:]
    expected_output[0, 0] = 1
    np.testing.assert_array_equal(relabelled_data, expected_output)
Beispiel #9
0
    def symmetrise_with_registration(self,
                                     filename_anatomy,
                                     filename_segmentation,
                                     list_labels_input,
                                     result_img_path,
                                     results_folder_path=None,
                                     list_labels_transformed=None,
                                     coord='z',
                                     reuse_registration=False):
        """
        Symmetrise a segmentation with registration: it uses NiftyReg.
        The old side is symmetrised in the new side, with new relabelling.
        Method based on paths even if in tools
        :param filename_anatomy: Path to File anatomical image
        :param filename_segmentation: Path to File segmentation of the anatomical image
        :param results_folder_path: Path to FOlder where intermediate results are stored
        :param result_img_path: Path to File symmetrised segmentation
        :param list_labels_input: labels that will be taken into account in the symmetrisation from the old side.
        :param list_labels_transformed: corresponding labels in the same order. If None, labels of the new side
        will be kept with the same numbering in the new side.
        :param reuse_registration: if a registration is already present in the pfo_results, and you only need to change the
        labels value, it will spare you some time when set to True.
        :param coord: coordinate of the registration: in RAS, 'z' will symmetrise Left on Right.
        :return: symmetrised segmentation.
        ---
        NOTE: requires niftyreg.
        """

        pfi_in_anatomy = connect_path_tail_head(self.pfo_in, filename_anatomy)
        pfi_in_segmentation = connect_path_tail_head(self.pfo_in, filename_segmentation)

        if results_folder_path is None:
            if self.pfo_out is not None:
                results_folder_path = self.pfo_out
            else:
                results_folder_path = self.pfo_in
        else:
            results_folder_path = os.path.dirname(pfi_in_segmentation)

        pfi_out_segmentation = connect_path_tail_head(results_folder_path, result_img_path)

        def flip_data_path(input_im_path, output_im_path, axis='x'):
            # wrap flip data, having path for inputs and outputs.
            if not os.path.isfile(input_im_path):
                raise IOError('input image file does not exist.')

            im_labels = nib.load(input_im_path)
            data_labels = im_labels.get_data()
            data_flipped = flip_data(data_labels, axis_direction=axis)

            im_relabelled = set_new_data(im_labels, data_flipped)
            nib.save(im_relabelled, output_im_path)

        # side A is the input, side B is the one where we want to symmetrise.
        # --- Initialisation  --- #

        # check input:
        if not os.path.isfile(pfi_in_anatomy):
            raise IOError('input image file {} does not exist.'.format(pfi_in_anatomy))
        if not os.path.isfile(pfi_in_segmentation):
            raise IOError('input segmentation file {} does not exist.'.format(pfi_in_segmentation))

        # erase labels that are not in the list from image and descriptor

        out_labels_side_A_path = os.path.join(results_folder_path, 'z_labels_side_A.nii.gz')
        labels_im = nib.load(pfi_in_segmentation)
        labels_data = labels_im.get_data()
        labels_to_erase = list(set(labels_data.flat) - set(list_labels_input + [0]))

        # Relabel: from pfi_segmentation to out_labels_side_A_path
        im_pfi_segmentation = nib.load(pfi_in_segmentation)

        segmentation_data_relabelled = relabeller(im_pfi_segmentation.get_data(), list_old_labels=labels_to_erase,
                                                  list_new_labels=[0, ] * len(labels_to_erase))
        nib_labels_side_A_path = set_new_data(im_pfi_segmentation, segmentation_data_relabelled)
        nib.save(nib_labels_side_A_path, out_labels_side_A_path)

        # --- Create side B  --- #

        # flip anatomical image and register it over the non flipped
        out_anatomical_flipped_path = os.path.join(results_folder_path, 'z_anatomical_flipped.nii.gz')
        flip_data_path(pfi_in_anatomy, out_anatomical_flipped_path, axis=coord)

        # flip the labels
        out_labels_flipped_path = os.path.join(results_folder_path, 'z_labels_flipped.nii.gz')
        flip_data_path(out_labels_side_A_path, out_labels_flipped_path, axis=coord)

        # register anatomical flipped over non flipped
        out_anatomical_flipped_warped_path = os.path.join(results_folder_path, 'z_anatomical_flipped_warped.nii.gz')
        out_affine_transf_path = os.path.join(results_folder_path, 'z_affine_transformation.txt')

        if not reuse_registration:
            cmd = 'reg_aladin -ref {0} -flo {1} -aff {2} -res {3}'.format(pfi_in_anatomy,
                                                                          out_anatomical_flipped_path,
                                                                          out_affine_transf_path,
                                                                          out_anatomical_flipped_warped_path)
            print('Registration started!\n')
            os.system(cmd)

            # propagate the registration to the flipped labels
            out_labels_side_B_path = os.path.join(results_folder_path, 'z_labels_side_B.nii.gz')
            cmd = 'reg_resample -ref {0} -flo {1} ' \
                  '-res {2} -trans {3} -inter {4}'.format(out_labels_side_A_path,
                                                          out_labels_flipped_path,
                                                          out_labels_side_B_path,
                                                          out_affine_transf_path,
                                                          0)

            print('Resampling started!\n')
            os.system(cmd)
        else:
            out_labels_side_B_path = os.path.join(results_folder_path, 'z_labels_side_B.nii.gz')

        # update labels of the side B if necessarily
        if list_labels_transformed is not None:
            print('relabelling step!')

            assert len(list_labels_transformed) == len(list_labels_input)

            # relabel from out_labels_side_B_path to out_labels_side_B_path
            im_segmentation_side_B = nib.load(out_labels_side_B_path)

            data_segmentation_side_B_new = relabeller(im_segmentation_side_B.get_data(),
                                                      list_old_labels=list_labels_input,
                                                      list_new_labels=list_labels_transformed)
            nib_segmentation_side_B_new = set_new_data(im_segmentation_side_B, data_segmentation_side_B_new)
            nib.save(nib_segmentation_side_B_new, out_labels_side_B_path)

        # --- Merge side A and side B in a single volume according to a criteria --- #
        # out_labels_side_A_path,  out_labels_side_B_path --> result_path.nii.gz

        nib_side_A = nib.load(out_labels_side_A_path)
        nib_side_B = nib.load(out_labels_side_B_path)

        data_side_A = nib_side_A.get_data()
        data_side_B = nib_side_B.get_data()

        symmetrised_data = np.zeros_like(data_side_A)

        # To manage the intersections of labels between old and new side. Vectorize later...
        dims = data_side_A.shape

        print('Pointwise symmetrisation started!')

        for z in range(dims[0]):
            for x in range(dims[1]):
                for y in range(dims[2]):
                    if (data_side_A[z, x, y] == 0 and data_side_B[z, x, y] != 0) or \
                            (data_side_A[z, x, y] != 0 and data_side_B[z, x, y] == 0):
                        symmetrised_data[z, x, y] = np.max([data_side_A[z, x, y], data_side_B[z, x, y]])
                    elif data_side_A[z, x, y] != 0 and data_side_B[z, x, y] != 0:
                        if data_side_A[z, x, y] == data_side_B[z, x, y]:
                            symmetrised_data[z, x, y] = data_side_A[z, x, y]
                        else:
                            symmetrised_data[z, x, y] = 255  # devil label!

        im_symmetrised = set_new_data(nib_side_A, symmetrised_data)
        nib.save(im_symmetrised, pfi_out_segmentation)
Beispiel #10
0
def process_T1_per_subject(sj, steps):

    print('\nProcessing T1 {} started.\n'.format(sj))

    if sj not in list_all_subjects(pfo_subjects_parameters):
        raise IOError('Subject parameters not known. Subject {}'.format(sj))

    sj_parameters = pickle.load(open(jph(pfo_subjects_parameters, sj), 'r'))

    study = sj_parameters['study']
    category = sj_parameters['category']

    options_T1 = sj_parameters['options_T1']

    suffix_T1_architecture = sj_parameters['names_architecture'][
        'T1']  # default is 3D

    pfo_input_sj_3D = jph(root_study_rabbits, '02_nifti', study, category, sj,
                          sj + '_' + suffix_T1_architecture)
    pfo_output_sj = jph(root_study_rabbits, 'A_data', study, category, sj)

    # select appropriate atlas:
    if study == 'ACS' or study == 'PTB' or study == 'TestStudy':
        pfo_atlas = root_atlas
    elif study == 'W8':
        pfo_atlas = root_atlas_W8
    else:
        raise IOError('Parameter **study** not included in the current logic.')

    # input sanity check:
    if not os.path.exists(pfo_input_sj_3D):
        raise IOError('Input folder nifti data T1 does not exist. {}'.format(
            pfo_input_sj_3D))

    # --  Generate intermediate and output folder
    pfo_mod = jph(pfo_output_sj, 'mod')
    pfo_segm = jph(pfo_output_sj, 'segm')
    pfo_mask = jph(pfo_output_sj, 'masks')
    pfo_tmp = jph(pfo_output_sj, 'z_tmp', 'z_T1' + suffix_T1_architecture)

    print_and_run('mkdir -p {}'.format(pfo_output_sj))
    print_and_run('mkdir -p {}'.format(pfo_mod))
    print_and_run('mkdir -p {}'.format(pfo_segm))
    print_and_run('mkdir -p {}'.format(pfo_mask))
    print_and_run('mkdir -p {}'.format(pfo_tmp))

    reference_subject = options_T1['pivot']

    # If the element is in  template retrieve the original roi mask and reg mask
    if sj_parameters['in_atlas']:
        reference_subject = sj

        # turn off all the not useful stuff:
        options_T1['roi_mask'] = ''
        steps['adjust_mask'] = False
        steps['create_lesion_maks'] = False

    if steps['orient_to_standard']:
        print('- orient to standard {}'.format(sj))

        pfi_input_original = jph(pfo_input_sj_3D, sj + '_3D.nii.gz')
        assert check_path_validity(pfi_input_original)
        pfi_std = jph(pfo_tmp, sj + '_to_std.nii.gz')
        orient2std(pfi_input_original, pfi_std)
        del pfi_input_original, pfi_std

    if steps['create_roi_masks']:

        pfi_std = jph(pfo_tmp, '{}_to_std.nii.gz'.format(sj))
        assert check_path_validity(pfi_std)

        # --- Get the reference masks from the stereotaxic orientation ---
        # reference subject:
        pfi_sj_ref_coord_system = jph(pfo_atlas, reference_subject, 'mod',
                                      '{}_T1.nii.gz'.format(reference_subject))
        # original mask
        pfi_reference_roi_mask = jph(
            pfo_atlas, reference_subject, 'masks',
            '{}_roi_mask.nii.gz'.format(reference_subject))
        pfi_reference_reg_mask = jph(
            pfo_atlas, reference_subject, 'masks',
            '{}_reg_mask.nii.gz'.format(reference_subject))

        assert check_path_validity(pfi_sj_ref_coord_system)
        assert check_path_validity(pfi_reference_roi_mask)
        assert check_path_validity(pfi_reference_reg_mask)

        # --- Get the angle difference from histological (template) to bicommissural (data) and orient header ---
        if isinstance(sj_parameters['angles'][0], list):
            angles = sj_parameters['angles'][0]
        else:
            angles = sj_parameters['angles']

        angle_parameter = angles[1]

        print('Get initial roi mask using the pivot.')

        pfi_sj_ref_coord_system_hd_oriented = jph(
            pfo_tmp, 'reference_for_mask_registration.nii.gz')
        pfi_reference_roi_mask_hd_oriented = jph(
            pfo_tmp, 'reference_for_mask_roi_mask.nii.gz')
        pfi_reference_reg_mask_hd_oriented = jph(
            pfo_tmp, 'reference_for_mask_reg_mask.nii.gz')

        nis_app = nis.App()
        nis_app.header.apply_small_rotation(
            pfi_sj_ref_coord_system,
            pfi_sj_ref_coord_system_hd_oriented,
            angle=angle_parameter,
            principal_axis='pitch')
        nis_app.header.apply_small_rotation(pfi_reference_roi_mask,
                                            pfi_reference_roi_mask_hd_oriented,
                                            angle=angle_parameter,
                                            principal_axis='pitch')
        nis_app.header.apply_small_rotation(pfi_reference_reg_mask,
                                            pfi_reference_reg_mask_hd_oriented,
                                            angle=angle_parameter,
                                            principal_axis='pitch')

        # set translational part to zero
        nis_app.header.modify_translational_part(
            pfi_sj_ref_coord_system_hd_oriented,
            pfi_sj_ref_coord_system_hd_oriented, np.array([0, 0, 0]))
        nis_app.header.modify_translational_part(
            pfi_reference_roi_mask_hd_oriented,
            pfi_reference_roi_mask_hd_oriented, np.array([0, 0, 0]))
        nis_app.header.modify_translational_part(
            pfi_reference_reg_mask_hd_oriented,
            pfi_reference_reg_mask_hd_oriented, np.array([0, 0, 0]))

        assert check_path_validity(pfi_sj_ref_coord_system_hd_oriented)
        assert check_path_validity(pfi_reference_roi_mask_hd_oriented)
        pfi_affine_transformation_ref_on_subject = jph(
            pfo_tmp, 'aff_ref_on_' + sj + '.txt')
        pfi_3d_warped_ref_on_subject = jph(pfo_tmp,
                                           'warp_ref_on_' + sj + '.nii.gz')
        cmd = 'reg_aladin -ref {0} -flo {1} -fmask {2} -aff {3} -res {4} -omp {5} -speeeeed '.format(  # -rigOnly
            pfi_std, pfi_sj_ref_coord_system_hd_oriented,
            pfi_reference_roi_mask_hd_oriented,
            pfi_affine_transformation_ref_on_subject,
            pfi_3d_warped_ref_on_subject, num_cores_run)
        print_and_run(cmd)

        print('- propagate affine registration T1 to roi masks {}'.format(sj))
        pfi_roi_mask_not_adjusted = jph(
            pfo_tmp, sj + '_T1_roi_mask_not_adjusted.nii.gz')
        cmd = 'reg_resample -ref {0} -flo {1} -trans {2} -res {3} -inter 0'.format(
            pfi_std, pfi_reference_roi_mask_hd_oriented,
            pfi_affine_transformation_ref_on_subject,
            pfi_roi_mask_not_adjusted)
        print_and_run(cmd)

        print('- propagate affine registration T1 to reg masks {}'.format(sj))
        pfi_reg_mask_not_adjusted = jph(
            pfo_tmp, sj + '_T1_reg_mask_not_adjusted.nii.gz')
        cmd = 'reg_resample -ref {0} -flo {1} -trans {2} -res {3} -inter 0'.format(
            pfi_std, pfi_reference_reg_mask_hd_oriented,
            pfi_affine_transformation_ref_on_subject,
            pfi_reg_mask_not_adjusted)
        print_and_run(cmd)

        if sj_parameters['in_atlas']:
            # if sj is in multi-atlas just copy the masks as they are in the destination, and then manipulate
            pfi_roi_mask = jph(pfo_mask, '{}_T1_roi_mask.nii.gz'.format(sj))
            # pfi_reg_mask = jph(pfo_mask, '{}_T1_reg_mask.nii.gz'.format(sj))
            cmd = 'cp {} {}'.format(pfi_roi_mask_not_adjusted, pfi_roi_mask)
            print_and_run(cmd)
            # cmd = 'cp {} {}'.format(pfi_reg_mask_not_adjusted, pfi_reg_mask)
            # print_and_run(cmd)

        del pfi_std, pfi_sj_ref_coord_system, pfi_reference_roi_mask, \
            angle_parameter, angles, pfi_sj_ref_coord_system_hd_oriented, pfi_reference_roi_mask_hd_oriented, \
            pfi_affine_transformation_ref_on_subject, pfi_3d_warped_ref_on_subject, cmd

    if steps['adjust_mask']:
        print('- adjust mask {}'.format(sj))
        # Input:
        pfi_roi_mask_not_adjusted = jph(
            pfo_tmp, sj + '_T1_roi_mask_not_adjusted.nii.gz')
        assert os.path.exists(
            pfi_roi_mask_not_adjusted), pfi_roi_mask_not_adjusted
        # Parameters:
        dilation_param = options_T1['mask_dilation']
        # Main output:
        pfi_roi_mask = jph(pfo_mask, '{}_T1_roi_mask.nii.gz'.format(sj))

        if dilation_param < 0:  # if negative, erode.
            cmd = 'seg_maths {0} -ero {1} {2}'.format(
                pfi_roi_mask_not_adjusted, -1 * dilation_param, pfi_roi_mask)
        elif dilation_param > 0:
            cmd = 'seg_maths {0} -dil {1} {2}'.format(
                pfi_roi_mask_not_adjusted, dilation_param, pfi_roi_mask)
        else:
            cmd = 'cp {} {}'.format(pfi_roi_mask_not_adjusted, pfi_roi_mask)

        del dilation_param, pfi_roi_mask_not_adjusted

        print_and_run(cmd)
        del pfi_roi_mask, cmd

    if steps['cut_masks']:
        if options_T1['crop_roi']:
            print('- cut masks {}'.format(sj))
            pfi_std = jph(pfo_tmp, sj + '_to_std.nii.gz')
            pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz')
            assert check_path_validity(pfi_std)
            assert check_path_validity(pfi_roi_mask)
            pfi_3d_cropped_roi = jph(pfo_tmp, sj + '_cropped.nii.gz')
            cmd = 'seg_maths {0} -mul {1} {2}'.format(pfi_std, pfi_roi_mask,
                                                      pfi_3d_cropped_roi)
            print '\nCutting newly-created ciccione mask on the subject: subject {0}.\n'.format(
                sj)
            print_and_run(cmd)
            del pfi_std, pfi_roi_mask, pfi_3d_cropped_roi, cmd
        else:
            pfi_std = jph(pfo_tmp, sj + '_to_std.nii.gz')
            assert check_path_validity(pfi_std)
            pfi_3d_cropped_roi = jph(pfo_tmp, sj + '_cropped.nii.gz')
            cmd = 'cp {0} {1}'.format(pfi_std, pfi_3d_cropped_roi)
            print_and_run(cmd)

    if steps['step_bfc']:
        print('- step bfc {}'.format(sj))
        pfi_3d_cropped_roi = jph(pfo_tmp, sj + '_cropped.nii.gz')
        assert check_path_validity(pfi_3d_cropped_roi)
        pfi_3d_bias_field_corrected = jph(pfo_tmp, sj + '_bfc.nii.gz')
        bfc_param = sj_parameters['bias_field_parameters']
        pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz')
        bias_field_correction(pfi_3d_cropped_roi,
                              pfi_3d_bias_field_corrected,
                              pfi_mask=pfi_roi_mask,
                              prefix='',
                              convergenceThreshold=bfc_param[0],
                              maximumNumberOfIterations=bfc_param[1],
                              biasFieldFullWidthAtHalfMaximum=bfc_param[2],
                              wienerFilterNoise=bfc_param[3],
                              numberOfHistogramBins=bfc_param[4],
                              numberOfControlPoints=bfc_param[5],
                              splineOrder=bfc_param[6],
                              print_only=False)

        del pfi_3d_cropped_roi, pfi_3d_bias_field_corrected, bfc_param, pfi_roi_mask

    if steps['create_lesion_maks']:
        print('Extract lesion mask: Subject {}'.format(sj))
        # output:
        pfi_lesion_mask = jph(pfo_mask, sj + '_T1_lesion_mask.nii.gz')
        if options_T1['lesion_mask_method'] == 0:
            percentile = sj_parameters['options_T1']['window_percentile']
            median_filter = sj_parameters['options_T1']['median_filter']
            print(
                'remove percentiles, values added manually: percentile {}, median filter {}'
                .format(percentile, median_filter))
            pfi_3d_bias_field_corrected = jph(pfo_tmp, sj + '_bfc.nii.gz')
            pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz')
            assert check_path_validity(pfi_3d_bias_field_corrected)
            assert check_path_validity(pfi_roi_mask)
            percentile_lesion_mask_extractor(
                im_input_path=pfi_3d_bias_field_corrected,
                im_output_path=pfi_lesion_mask,
                im_mask_foreground_path=pfi_roi_mask,
                percentiles=percentile,
                safety_on=False,
                median_filter=median_filter,
                pfo_tmp=pfo_tmp)
        elif options_T1['lesion_mask_method'] > 0:
            K = options_T1['lesion_mask_method']
            print(
                'remove the first (not background) and the last gaussians after MoG fitting, with K = {}.'
                .format(K))
            pfi_3d_bias_field_corrected = jph(pfo_tmp, sj + '_bfc.nii.gz')
            pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz')
            assert os.path.exists(pfi_3d_bias_field_corrected)
            assert check_path_validity(pfi_roi_mask)
            pfi_mog_segm = jph(pfo_tmp, '{}_mog_segm.nii.gz'.format(sj))
            pfi_T1_bfc = nib.load(pfi_3d_bias_field_corrected)
            pfi_roi_mask = nib.load(pfi_roi_mask)

            im_T1_bfc = nib.load(pfi_T1_bfc)
            im_roi_mask = nib.load(pfi_T1_bfc)
            c_array, p_array = MoG_array(im_T1_bfc.get_data(),
                                         K=K,
                                         pre_process_median_filter=True,
                                         mask_array=im_roi_mask.get_data(),
                                         pre_process_only_interquartile=True)
            c = set_new_data(im_T1_bfc, c_array)
            p = set_new_data(im_T1_bfc, p_array)
            nib.save(c, '/Users/sebastiano/Desktop/zzz.nii.gz')
            old_labels = list(range(K))  # [0, 1, 2, 3, 4]
            new_labels = [
                1,
            ] * len(old_labels)
            new_labels[0], new_labels[1], new_labels[-1] = 0, 0, 0
            im_crisp = set_new_data(c,
                                    np.copy(
                                        relabeller(c.get_data(), old_labels,
                                                   new_labels)),
                                    new_dtype=np.uint8)
            nib.save(im_crisp, pfi_mog_segm)
            # final tuning:
            cmd0 = 'seg_maths {0} -ero 3 {0}'.format(pfi_mog_segm,
                                                     pfi_mog_segm)
            cmd1 = 'seg_maths {0} -fill {0}'.format(pfi_mog_segm)
            cmd2 = 'seg_maths {0} -dil 3 {0}'.format(pfi_mog_segm)
            cmd3 = 'seg_maths {0} -fill {0}'.format(pfi_mog_segm)
            print_and_run(cmd0)
            print_and_run(cmd1)
            print_and_run(cmd2)
            print_and_run(cmd3)
            # pfi_lesion_mask IS pfi_roi_mask - pfi_mog_segm
            pfi_mog_segm_and_roi = jph(pfo_tmp, '{}_T1_MoGsegm_and_roi.nii.gz')
            cmd11 = 'seg_maths {0} -mul {1} {2}'.format(
                pfi_roi_mask, pfi_mog_segm, pfi_mog_segm_and_roi)
            print_and_run(cmd11)
            cmd22 = 'seg_maths {0} -sub {1} {2}'.format(
                pfi_roi_mask, pfi_mog_segm_and_roi, pfi_lesion_mask)
            print_and_run(cmd22)

    if steps['create_reg_mask']:

        if sj_parameters['in_atlas']:
            print('Get registration mask: Subject {} is in atlas'.format(sj))
            pfi_reg_mask_not_adjusted = jph(
                pfo_tmp, '{}_T1_reg_mask_not_adjusted.nii.gz'.format(sj))
            assert os.path.exists(pfi_reg_mask_not_adjusted), \
                'Processing T1, subject {}. Run the step create_roi_mask first'.format(sj)
            pfi_reg_mask = jph(pfo_mask, '{}_T1_reg_mask.nii.gz'.format(sj))
            cmd = 'cp {} {}'.format(pfi_reg_mask_not_adjusted, pfi_reg_mask)
            print_and_run(cmd)

        else:
            print('Create registration mask: Subject {}'.format(sj))
            # output:
            pfi_reg_mask = jph(pfo_mask, sj + '_T1_reg_mask.nii.gz')
            # registration mask is defined as the difference between roi_mask and lesion_mask
            pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz')
            pfi_lesion_mask = jph(pfo_mask, sj + '_T1_lesion_mask.nii.gz')
            assert os.path.exists(pfi_roi_mask), pfi_roi_mask
            assert os.path.exists(pfi_lesion_mask), pfi_lesion_mask
            pfi_roi_mask_and_lesion_mask = jph(
                pfo_tmp, '{}_T1_ROI_and_LM.nii.gz'.format(sj))
            cmd11 = 'seg_maths {0} -mul {1} {2}'.format(
                pfi_roi_mask, pfi_lesion_mask, pfi_roi_mask_and_lesion_mask)
            print_and_run(cmd11)
            cmd22 = 'seg_maths {0} -sub {1} {2}'.format(
                pfi_roi_mask, pfi_roi_mask_and_lesion_mask, pfi_reg_mask)
            print_and_run(cmd22)

    if steps['save_results']:
        print('- save results {}'.format(sj))
        pfi_3d_bias_field_corrected = jph(pfo_tmp, sj + '_bfc.nii.gz')
        assert check_path_validity(pfi_3d_bias_field_corrected)
        pfi_3d_final_destination = jph(pfo_mod, sj + '_T1.nii.gz')
        cmd = 'cp {0} {1}'.format(pfi_3d_bias_field_corrected,
                                  pfi_3d_final_destination)
        print_and_run(cmd)
        del pfi_3d_bias_field_corrected, pfi_3d_final_destination, cmd