def erase_labels(self, path_to_input_segmentation, path_to_output_segmentation=None, labels_to_erase=(), path_to_input_labels_descriptor=None, path_to_output_labels_descriptor=None): 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_erased = erase_labels(data_labels, labels_to_erase=labels_to_erase) im_erased = set_new_data(im_labels, data_erased) nib.save(im_erased, 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.erase_labels(labels_to_erase, verbose=self.verbose) 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('Erased labels from image {0} saved in {1}.'.format(pfi_in, pfi_out)) return pfi_out
def test_get_multi_label_dict_standard_combine(): ldm_lr = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor_RL.txt')) multi_labels_dict_from_ldm = ldm_lr.get_multi_label_dict( combine_right_left=True) expected_multi_labels_dict = collections.OrderedDict() expected_multi_labels_dict.update({'background': [0]}) expected_multi_labels_dict.update({'label A Left': [1]}) expected_multi_labels_dict.update({'label A Right': [2]}) expected_multi_labels_dict.update({'label A': [1, 2]}) expected_multi_labels_dict.update({'label B Left': [3]}) expected_multi_labels_dict.update({'label B Right': [4]}) expected_multi_labels_dict.update({'label B': [3, 4]}) expected_multi_labels_dict.update({'label C': [5]}) expected_multi_labels_dict.update({'label D': [6]}) expected_multi_labels_dict.update({'label E Left': [7]}) expected_multi_labels_dict.update({'label E Right': [8]}) expected_multi_labels_dict.update({'label E': [7, 8]}) for k1, k2 in zip(multi_labels_dict_from_ldm.keys(), expected_multi_labels_dict.keys()): assert k1 == k2 assert multi_labels_dict_from_ldm[k1] == expected_multi_labels_dict[k2]
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 keep_one_label(self, path_to_input_segmentation, path_to_output_segmentation=None, label_to_keep=1, path_to_input_labels_descriptor=None, path_to_output_labels_descriptor=None): 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_one_label = keep_only_one_label(data_labels, label_to_keep) im_one_label = set_new_data(im_labels, data_one_label) nib.save(im_one_label, 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.keep_one_label(label_to_keep) 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('Label {0} kept from image {1} and saved in {2}.'.format(label_to_keep, pfi_in, pfi_out)) return pfi_out
def test_save_multi_labels_descriptor_custom(): # load it into a labels descriptor manager ldm_lr = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor_RL.txt')) # save it as labels descriptor text file pfi_multi_ld = jph(pfo_tmp_test, 'multi_labels_descriptor_LR.txt') ldm_lr.save_as_multi_label_descriptor(pfi_multi_ld) # expected lines: expected_lines = [['background', 0], ['label A Left', 1], ['label A Right', 2], ['label A', 1, 2], ['label B Left', 3], ['label B Right', 4], ['label B', 3, 4], ['label C', 5], ['label D', 6], ['label E Left', 7], ['label E Right', 8], ['label E', 7, 8]] # load saved labels descriptor with open(pfi_multi_ld, 'r') as g: multi_ld_lines = g.readlines() # modify as list of lists as the expected lines. multi_ld_lines_a_list_of_lists = [[ int(a) if a.isdigit() else a for a in [n.strip() for n in m.split('&') if not n.startswith('#')] ] for m in multi_ld_lines] # Compare: for li1, li2 in zip(expected_lines, multi_ld_lines_a_list_of_lists): assert li1 == li2
def test_relabel_bad_input(): ldm_original = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) old_labels = [2, 4, 180] new_labels = [9, 10, 12] with pytest.raises(IOError): ldm_original.relabel(old_labels, new_labels)
def test_signature_for_variable_convention_wrong_input_after_initialisation(): my_ldm = LabelsDescriptorManager(jph(pfo_tmp_test, 'labels_descriptor.txt'), labels_descriptor_convention='itk-snap') with pytest.raises(IOError): my_ldm.convention = 'spam' my_ldm.save_label_descriptor( jph(pfo_tmp_test, 'labels_descriptor_again.txt'))
def test_keep_one_label(): dict_expected = collections.OrderedDict() dict_expected.update({3: [[51, 51, 255], [1, 1, 1], 'label three']}) ldm_original = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) label_to_keep = 3 ldm_relabelled = ldm_original.keep_one_label(label_to_keep) for k in dict_expected.keys(): assert dict_expected[k] == ldm_relabelled.dict_label_descriptor[k]
def generate_reports_from_list(sj_list, controller, options): # Load regions with labels_descriptor_manager: ldm = LdM(pfi_labels_descriptor) label_descriptor_dict = ldm.get_dict_itk_snap() print label_descriptor_dict.keys() for d in label_descriptor_dict.keys(): print("{0} : '{1}',".format(d, label_descriptor_dict[d][2])) for sj_id in sj_list: generate_reports_for_subject(sj_id, controller=controller, ldm=ldm, options=options)
def test_check_missing_labels(): # Instantiate a labels descriptor manager pfi_ld = os.path.join(pfo_tmp_test, 'labels_descriptor.txt') ldm = LabelsDescriptorManager(pfi_ld, labels_descriptor_convention='itk-snap') # Create dummy image data = np.zeros([10, 10, 10]) data[:3, :3, :3] = 1 data[3:5, 3:5, 3:5] = 12 data[5:7, 5:7, 5:7] = 3 data[7:10, 7:10, 7:10] = 7 im_segm = nib.Nifti1Image(data, affine=np.eye(4)) # Apply check_missing_labels, then test the output pfi_log = os.path.join(pfo_tmp_test, 'check_imperfections_log.txt') in_descriptor_not_delineated, delineated_not_in_descriptor = check_missing_labels( im_segm, ldm, pfi_log) print(in_descriptor_not_delineated, delineated_not_in_descriptor) np.testing.assert_equal( in_descriptor_not_delineated, {8, 2, 4, 5, 6}) # in label descriptor, not in image np.testing.assert_equal(delineated_not_in_descriptor, {12}) # in image not in label descriptor assert os.path.exists(pfi_log)
def test_load_save_and_compare(): ldm = LabelsDescriptorManager(jph(pfo_tmp_test, 'labels_descriptor.txt')) ldm.save_label_descriptor(jph(pfo_tmp_test, 'labels_descriptor2.txt')) f1 = open(jph(pfo_tmp_test, 'labels_descriptor.txt'), 'r') f2 = open(jph(pfo_tmp_test, 'labels_descriptor2.txt'), 'r') for l1, l2 in zip(f1.readlines(), f2.readlines()): split_l1 = [ float(a) if is_a_string_number(a) else a for a in [a.strip() for a in l1.split(' ') if a is not ''] ] split_l2 = [ float(b) if is_a_string_number(b) else b for b in [b.strip() for b in l2.split(' ') if b is not ''] ] assert split_l1 == split_l2
def test_erase_labels(): dict_expected = collections.OrderedDict() dict_expected.update({0: [[0, 0, 0], [0, 0, 0], 'background']}) dict_expected.update({1: [[255, 0, 0], [1, 1, 1], 'label one (l1)']}) # copied over label two dict_expected.update({4: [[102, 102, 255], [1, 1, 1], 'label four']}) dict_expected.update({5: [[0, 204, 51], [1, 1, 1], 'label five (l5)']}) dict_expected.update({6: [[51, 255, 102], [1, 1, 1], 'label six']}) dict_expected.update({8: [[255, 50, 50], [1, 1, 1], 'label eight']}) ldm_original = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) labels_to_erase = [2, 3, 7] ldm_relabelled = ldm_original.erase_labels(labels_to_erase) for k in dict_expected.keys(): assert dict_expected[k] == ldm_relabelled.dict_label_descriptor[k]
def test_erase_labels_unexisting_labels(): dict_expected = collections.OrderedDict() dict_expected.update({0: [[0, 0, 0], [0, 0, 0], 'background']}) dict_expected.update({1: [[255, 0, 0], [1, 1, 1], 'label one (l1)']}) dict_expected.update({3: [[51, 51, 255], [1, 1, 1], 'label three']}) dict_expected.update({5: [[0, 204, 51], [1, 1, 1], 'label five (l5)']}) dict_expected.update({6: [[51, 255, 102], [1, 1, 1], 'label six']}) dict_expected.update({7: [[255, 255, 0], [1, 1, 1], 'label seven']}) dict_expected.update({8: [[255, 50, 50], [1, 1, 1], 'label eight']}) ldm_original = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) labels_to_erase = [2, 4, 16, 32] ldm_relabelled = ldm_original.erase_labels(labels_to_erase) for k in dict_expected.keys(): assert dict_expected[k] == ldm_relabelled.dict_label_descriptor[k]
def test_save_multi_labels_descriptor_custom_test_robustness(): # save this as file multi labels descriptor then read and check that it went in order! d = collections.OrderedDict() d.update({0: [[0, 0, 0], [0, 0, 0], 'background']}) d.update({1: [[255, 0, 0], [1, 1, 1], 'label A Right']}) d.update({2: [[204, 0, 0], [1, 1, 1], 'label A Left']}) d.update({3: [[51, 51, 255], [1, 1, 1], 'label B left']}) d.update({4: [[102, 102, 255], [1, 1, 1], 'label B Right']}) d.update({5: [[0, 204, 51], [1, 1, 1], 'label C ']}) d.update({6: [[51, 255, 102], [1, 1, 1], 'label D Right']}) # unpaired label d.update({7: [[255, 255, 0], [1, 1, 1], 'label E right ']}) # small r and spaces d.update({8: [[255, 50, 50], [1, 1, 1], 'label E Left ']}) # ... paired with small l and spaces with open(jph(pfo_tmp_test, 'labels_descriptor_RL.txt'), 'w+') as f: for j in d.keys(): line = '{0: >5}{1: >6}{2: >6}{3: >6}{4: >9}{5: >6}{6: >6} "{7}"\n'.format( j, d[j][0][0], d[j][0][1], d[j][0][2], d[j][1][0], d[j][1][1], d[j][1][2], d[j][2]) f.write(line) # load it with an instance of LabelsDescriptorManager ldm_lr = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor_RL.txt')) multi_labels_dict_from_ldm = ldm_lr.get_multi_label_dict( combine_right_left=True) expected_multi_labels_dict = collections.OrderedDict() expected_multi_labels_dict.update({'background': [0]}) expected_multi_labels_dict.update({'label A Right': [1]}) expected_multi_labels_dict.update({'label A Left': [2]}) expected_multi_labels_dict.update({'label A': [1, 2]}) expected_multi_labels_dict.update({'label B left': [3]}) expected_multi_labels_dict.update({'label B Right': [4]}) expected_multi_labels_dict.update({'label C': [5]}) expected_multi_labels_dict.update({'label D Right': [6]}) expected_multi_labels_dict.update({'label E right': [7]}) expected_multi_labels_dict.update({'label E Left': [8]}) for k1, k2 in zip(multi_labels_dict_from_ldm.keys(), expected_multi_labels_dict.keys()): assert k1 == k2 assert multi_labels_dict_from_ldm[k1] == expected_multi_labels_dict[k2]
def test_permute_labels_from_descriptor_check(): dict_expected = collections.OrderedDict() dict_expected.update({0: [[0, 0, 0], [0, 0, 0], 'background']}) dict_expected.update({3: [[255, 0, 0], [1, 1, 1], 'label one (l1)']}) # copied over label two dict_expected.update({4: [[204, 0, 0], [1, 1, 1], 'label two (l2)']}) dict_expected.update({2: [[51, 51, 255], [1, 1, 1], 'label three']}) dict_expected.update({1: [[102, 102, 255], [1, 1, 1], 'label four']}) dict_expected.update({5: [[0, 204, 51], [1, 1, 1], 'label five (l5)']}) dict_expected.update({6: [[51, 255, 102], [1, 1, 1], 'label six']}) dict_expected.update({7: [[255, 255, 0], [1, 1, 1], 'label seven']}) dict_expected.update({8: [[255, 50, 50], [1, 1, 1], 'label eight']}) ldm_original = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) perm = [[1, 2, 3, 4], [3, 4, 2, 1]] ldm_relabelled = ldm_original.permute_labels(perm) for k in dict_expected.keys(): dict_expected[k] == ldm_relabelled.dict_label_descriptor[k]
def test_relabel_standard(): dict_expected = collections.OrderedDict() dict_expected.update({0: [[0, 0, 0], [0, 0, 0], 'background']}) dict_expected.update({1: [[255, 0, 0], [1, 1, 1], 'label one (l1)']}) dict_expected.update({9: [[204, 0, 0], [1, 1, 1], 'label two (l2)']}) dict_expected.update({3: [[51, 51, 255], [1, 1, 1], 'label three']}) dict_expected.update({10: [[102, 102, 255], [1, 1, 1], 'label four']}) dict_expected.update({5: [[0, 204, 51], [1, 1, 1], 'label five (l5)']}) dict_expected.update({6: [[51, 255, 102], [1, 1, 1], 'label six']}) dict_expected.update({7: [[255, 255, 0], [1, 1, 1], 'label seven']}) dict_expected.update({8: [[255, 50, 50], [1, 1, 1], 'label eight']}) ldm_original = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) old_labels = [2, 4] new_labels = [9, 10] ldm_relabelled = ldm_original.relabel(old_labels, new_labels) for k in dict_expected.keys(): assert dict_expected[k] == ldm_relabelled.dict_label_descriptor[k]
def test_generate_none_list_colour_triples(): generate_dummy_label_descriptor(jph(pfo_tmp_test, 'labels_descriptor.txt'), list_labels=range(5), list_roi_names=['1', '2', '3', '4', '5'], list_colors_triplets=None) loaded_dummy_ldm = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) for k in loaded_dummy_ldm.dict_label_descriptor.keys(): assert len(loaded_dummy_ldm.dict_label_descriptor[k][0]) == 3 for k_rgb in loaded_dummy_ldm.dict_label_descriptor[k][0]: assert 0 <= k_rgb < 256
def missing_labels(self, path_input_segmentation, path_input_labels_descriptor, pfi_where_to_save_the_log_file=None): pfi_segm = connect_path_tail_head(self.pfo_in, path_input_segmentation) pfi_ld = connect_path_tail_head(self.pfo_in, path_input_labels_descriptor) ldm = LabelsDescriptorManager(pfi_ld) im_se = nib.load(pfi_segm) in_descriptor_not_delineated, delineated_not_in_descriptor = \ check_missing_labels(im_se, ldm, pfi_where_log=pfi_where_to_save_the_log_file) return in_descriptor_not_delineated, delineated_not_in_descriptor
def assign_all_other_labels_the_same_value(self, path_to_input_segmentation, path_to_output_segmentation=None, labels_to_keep=(), same_value_label=255, path_to_input_labels_descriptor=None, path_to_output_labels_descriptor=None): """ :param path_to_input_segmentation: :param path_to_output_segmentation: :param labels_to_keep: :param same_value_label: :param path_to_input_labels_descriptor: :param path_to_output_labels_descriptor: :return: """ 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_reassigned = assign_all_other_labels_the_same_value(data_labels, labels_to_keep=labels_to_keep, same_value_label=same_value_label) im_reassigned = set_new_data(im_labels, data_reassigned) nib.save(im_reassigned, 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.assign_all_other_labels_the_same_value(labels_to_keep=labels_to_keep, same_value_label=same_value_label) 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('Reassigned labels from image {0} saved in {1}.'.format(pfi_in, pfi_out)) return pfi_out
def test_assign_all_other_labels_the_same_value(): dict_expected = collections.OrderedDict() dict_expected.update({0: [[0, 0, 0], [0, 0, 0], 'background']}) # Possible bug dict_expected.update({1: [[255, 0, 0], [1, 1, 1], 'label one (l1)']}) # copied over label two dict_expected.update({4: [[102, 102, 255], [1, 1, 1], 'label four']}) dict_expected.update({7: [[255, 255, 0], [1, 1, 1], 'label seven']}) ldm_original = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) labels_to_keep = [0, 1, 4, 7] other_value = 12 ldm_relabelled = ldm_original.assign_all_other_labels_the_same_value( labels_to_keep, other_value) print(dict_expected) print(ldm_relabelled.dict_label_descriptor) for k in dict_expected.keys(): print() print(dict_expected[k]) print(ldm_relabelled.dict_label_descriptor[k]) assert dict_expected[k] == ldm_relabelled.dict_label_descriptor[k]
def test_relabel_labels_descriptor_with_merging(): dict_expected = collections.OrderedDict() dict_expected.update({0: [[0, 0, 0], [0, 0, 0], 'background']}) # dict_expected.update({1: [[255, 0, 0], [1, 1, 1], 'label one (l1)']}) # copied over label two dict_expected.update({1: [[204, 0, 0], [1, 1, 1], 'label two (l2)']}) dict_expected.update({5: [[51, 51, 255], [1, 1, 1], 'label three']}) dict_expected.update({4: [[102, 102, 255], [1, 1, 1], 'label four']}) dict_expected.update({5: [[0, 204, 51], [1, 1, 1], 'label five (l5)']}) dict_expected.update({6: [[51, 255, 102], [1, 1, 1], 'label six']}) dict_expected.update({7: [[255, 255, 0], [1, 1, 1], 'label seven']}) dict_expected.update({8: [[255, 50, 50], [1, 1, 1], 'label eight']}) ldm_original = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) old_labels = [1, 2, 3] new_labels = [1, 1, 5] ldm_relabelled = ldm_original.relabel(old_labels, new_labels, sort=True) for k in dict_expected.keys(): dict_expected[k] == ldm_relabelled.dict_label_descriptor[k]
def test_basic_dict_input(): dict_ld = collections.OrderedDict() # note that in the dictionary there are no double quotes " ", but by default the strings are '"label name"' dict_ld.update({0: [[0, 0, 0], [0, 0, 0], 'background']}) dict_ld.update({1: [[255, 0, 0], [1, 1, 1], 'label one (l1)']}) dict_ld.update({2: [[204, 0, 0], [1, 1, 1], 'label two (l2)']}) dict_ld.update({3: [[51, 51, 255], [1, 1, 1], 'label three']}) dict_ld.update({4: [[102, 102, 255], [1, 1, 1], 'label four']}) dict_ld.update({5: [[0, 204, 51], [1, 1, 1], 'label five (l5)']}) dict_ld.update({6: [[51, 255, 102], [1, 1, 1], 'label six']}) dict_ld.update({7: [[255, 255, 0], [1, 1, 1], 'label seven']}) dict_ld.update({8: [[255, 50, 50], [1, 1, 1], 'label eight']}) ldm = LabelsDescriptorManager(jph(pfo_tmp_test, 'labels_descriptor.txt')) for k in ldm.dict_label_descriptor.keys(): assert ldm.dict_label_descriptor[k] == dict_ld[k]
def freesurfer_surface_overlayed(pfi_anatomy, pfo_stl_surfaces, pfi_descriptor, convention_descriptor='itk-snap', suffix_surf='surf', add_colors=True, labels_to_delineate='all'): """ Manual step: from a segmentation export all the labels in stand-alone .stl files with ITK-snap, in a folder pfo_stl_surfaces, with suffix suffix_surf :param pfi_anatomy: :param pfo_stl_surfaces: :param pfi_descriptor: :param convention_descriptor: :param suffix_surf: :param add_colors: :param labels_to_delineate: :return: """ ldm = LabelsDescriptorManager( pfi_descriptor, labels_descriptor_convention=convention_descriptor) cmd = 'source $FREESURFER_HOME/SetUpFreeSurfer.sh; freeview -v {0} -f '.format( pfi_anatomy) if labels_to_delineate: labels_to_delineate = ldm.dict_label_descriptor.keys()[1:-1] for k in labels_to_delineate: pfi_surface = os.path.join(pfo_stl_surfaces, '{0}{1:05d}.stl'.format(suffix_surf, k)) assert os.path.exists(pfi_surface), pfi_surface if add_colors: triplet_rgb = '{0},{1},{2}'.format( ldm.dict_label_descriptor[k][0][0], ldm.dict_label_descriptor[k][0][1], ldm.dict_label_descriptor[k][0][2]) cmd += ' {0}:edgecolor={1}:color={1} '.format( pfi_surface, triplet_rgb) else: cmd += ' {0} '.format(pfi_surface) os.system(cmd)
def test_save_in_fsl_convention_reload_as_dict_and_compare(): ldm_itk = LabelsDescriptorManager( jph(pfo_tmp_test, 'labels_descriptor.txt')) # change convention ldm_itk.convention = 'fsl' ldm_itk.save_label_descriptor( jph(pfo_tmp_test, 'labels_descriptor_fsl.txt')) ldm_fsl = LabelsDescriptorManager(jph(pfo_tmp_test, 'labels_descriptor_fsl.txt'), labels_descriptor_convention='fsl') # NOTE: test works only with default 1.0 values - fsl convention is less informative than itk-snap.. for k in ldm_itk.dict_label_descriptor.keys(): ldm_itk.dict_label_descriptor[k] == ldm_fsl.dict_label_descriptor[k]
def test_get_rgb_image_from_segmentation_and_label_descriptor_simple(): ldm = LabelsDescriptorManager(jph(pfo_tmp_test, 'labels_descriptor.txt')) segm_data = np.zeros([20, 20, 20]) # block diagonal dummy segmentation segm_data[:5, :5, :5] = 1 segm_data[5:10, 5:10, 5:10] = 2 segm_data[10:15, 10:15, 10:15] = 3 segm_data[15:, 15:, 15:] = 4 im_segm = nib.Nifti1Image(segm_data, affine=np.eye(4)) im_segm_rgb = get_rgb_image_from_segmentation_and_label_descriptor( im_segm, ldm) segm_rgb_expected = np.zeros([20, 20, 20, 3]) segm_rgb_expected[:5, :5, :5, :] = np.array([255, 0, 0]) segm_rgb_expected[5:10, 5:10, 5:10, :] = np.array([204, 0, 0]) segm_rgb_expected[10:15, 10:15, 10:15, :] = np.array([51, 51, 255]) segm_rgb_expected[15:, 15:, 15:, :] = np.array([102, 102, 255]) np.testing.assert_equal(im_segm_rgb.get_data(), segm_rgb_expected)
244 : 'st R', 247 : 'mt L', 248 : 'mt R', 251 : 'fr L', 252 : 'fr R', 253 : 'pc' }) nomenclature_labels = '' # Sanity tests: if __name__ == '__main__': pfi_current_descriptor = '/Users/sebastiano/Dropbox/RabbitEOP-MRI/study/A_atlas/labels_descriptor.txt' ldm = LabelsDescriptorManager(pfi_current_descriptor) dict = ldm.dict_label_descriptor() labels_current_descriptor = dict.keys() labels_nomenclature_anatomical = [] for d in nomenclature_anatomical.keys(): labels_nomenclature_anatomical += nomenclature_anatomical[d] labels_nomenclature_taxonomical = [] for d in nomenclature_taxonomical.keys(): labels_nomenclature_taxonomical += nomenclature_taxonomical[d][1] print 'descriptor - anatomical : {}'.format(set(labels_current_descriptor) - set(labels_nomenclature_anatomical)) print 'anatomical - descriptor : {}'.format(set(labels_nomenclature_anatomical) - set(labels_current_descriptor))
def exploratory_data_analysis(control): # input pfi_labels_descriptor = jph(ph.pfo_mutli_atlas_leave_one_out, 'labels_descriptor.txt') pfi_ground_truth = jph(ph.pfo_target, 'segm', '{}_segm.nii.gz'.format(ph.selected_target)) assert os.path.exists(pfi_labels_descriptor), pfi_labels_descriptor assert os.path.exists(pfi_ground_truth), pfi_ground_truth # output per phase pfi_dict_paths_struct = jph(ph.pfo_target, 'segm', 'paths_methods.pickle') pfi_data_frame_dice_score = jph(ph.pfo_target, 'segm', 'dice_scores_region_methods.csv') pfi_figure_params_selection = jph(ph.pfo_target, 'boxplot_parameter_selection.pdf') if control['save_path_structure']: dict_paths_methods = OrderedDict() steps_params = [ 'STEPS_pr_{0}_{1}'.format(k, n) for n in [5, 7] for k in [5, 7, 10] ] for met in ['MV'] + ['STAPLE_pr_1'] + steps_params: for tag_suffix in ['Mono', 'Multi']: name_method = '{}_{}'.format(met, tag_suffix) path_to_method = jph( ph.pfo_target, 'segm', 'automatic{}'.format(tag_suffix), '{}_{}_CrossValidation{}.nii.gz'.format( ph.selected_target, met, tag_suffix)) assert os.path.exists(path_to_method), path_to_method dict_paths_methods.update({name_method: path_to_method}) pprint(dict_paths_methods) pickle.dump(dict_paths_methods, open(pfi_dict_paths_struct, 'w+')) if control['collect_data']: print('------------- DATA COLLECTION --------------') # input dict_paths_methods = pickle.load(open(pfi_dict_paths_struct)) ldm = LabelsDescriptorManager( pfi_labels_descriptor ) # 218 : [[128, 0, 128], [1.0, 1.0, 1.0], 'Corpus callosum' im_ground_segm = nib.load(pfi_ground_truth) # output to fill: df_dice_scores = pd.DataFrame() for met, met_path in dict_paths_methods.items(): print('---') print('\n\nMethod: {}'.format(met)) im_segm = nib.load(met_path) ds = dist.dice_score(im_ground_segm, im_segm, labels_list=ldm.dict_label_descriptor.keys(), labels_names=[ ldm.dict_label_descriptor[k][-1] for k in ldm.dict_label_descriptor.keys() ], verbose=1) df_dice_scores.insert(len(df_dice_scores.columns), met, ds) print(df_dice_scores) df_dice_scores.to_csv(pfi_data_frame_dice_score) if control['show_graph']: print('-------------- Showing graph -------------') df_dice_scores = pd.read_csv(pfi_data_frame_dice_score, index_col=0) dict_paths_methods = pickle.load(open(pfi_dict_paths_struct)) print(df_dice_scores) font_top = { 'family': 'serif', 'color': 'darkblue', 'weight': 'normal', 'size': 14 } font_bl = { 'family': 'serif', 'color': 'black', 'weight': 'normal', 'size': 12 } legend_prop = {'size': 11} sns.set_style('darkgrid') fig, ax = plt.subplots(figsize=(11, 6.5)) fig.canvas.set_window_title('boxplot_parameters_selection') fig.subplots_adjust(left=0.075, right=0.95, top=0.9, bottom=0.25) bp = ax.boxplot(1 - df_dice_scores.as_matrix(), patch_artist=True, notch=True) for xv in [2 * j + 0.5 for j in range(1, 8)]: ax.axvline(xv, color='k', linestyle='--', linewidth=0.4) ax.set_xticks([2 * j + 1.5 for j in range(8)]) ax.set_xticklabels([ d.replace('_Mono', '').replace('pr_', '').replace('E_1', 'E') for d in dict_paths_methods.keys()[::2] ], rotation=45, fontdict=font_bl) ax.set_title( 'Segmentation propagation and labels fusion parameters selection', fontdict=font_top) ax.set_ylim(0, 0.55) ax.set_xlabel('Label fusion methods', fontdict=font_bl, labelpad=5) ax.set_ylabel('1 - Dice score', fontdict=font_bl, labelpad=5) colors = ['lightgrey', 'lightblue'] for patch_id, patch in enumerate(bp['boxes']): color = colors[patch_id % 2] patch.set_facecolor(color) legend_elements = [ Line2D([0], [0], color='lightgrey', lw=4, label='Mono'), Line2D([0], [0], color='lightblue', lw=4, label='Multi') ] ax.legend(handles=legend_elements, loc='upper right') plt.tight_layout() plt.savefig(pfi_figure_params_selection, dpi=150) plt.show(block=True)
assert os.path.exists(pfo_probabilistic_template_results ), 'Run probabilistic_multi_atlas_creator.py first' assert os.path.exists(pfi_labels_descritpor) pfo_tmp = path_manager.pfo_tmp os.system('mkdir -p {}'.format(pfo_tmp)) # Controller: labels_to_keep = [11, 12, 31, 32, 69, 70, 233] if True: print('From segmentations to RGB with the selected labels:') nis_app = nis.App() ldm = LdM(pfi_labels_descritpor) for sj_id in path_manager.atlas_subjects: print('Subject {}'.format(sj_id)) # Input: pfi_segmentation = jph(pfo_probabilistic_template, 'all_segm', '{}_segm.nii.gz'.format(sj_id)) assert os.path.exists(pfi_segmentation), pfi_segmentation # Output pfi_my_labels_segmentation = jph( pfo_tmp, '{}_my_labels.nii.gz'.format(sj_id)) pfi_rgb_segmentation = jph(pfo_tmp, '{}_rgb.nii.gz'.format(sj_id)) # remove all other labels:
metrics_def = [dice_score, covariance_distance, hausdorff_distance, normalised_symmetric_contour_distance] dict_metric_to_metric_name = {'dice_score': 'Dice Score', 'covariance_distance': 'Covariance Distance', 'hausdorff_distance': 'Hausdorff Distance', 'normalised_symmetric_contour_distance': 'Normalised Symmetric Contour Distance'} methods_names = [] mod = '' for cat in segm_tags: for segm in segm_suffix: if mod == '': methods_names += ['{0}_{1}'.format(segm, cat)] else: methods_names += ['{0}_{1}_{2}'.format(mod, segm, cat)] ldm = LabelsDescriptorManager(path_manager.pfi_labels_descriptor) label_descriptor_dict = ldm.dict_label_descriptor(as_string=False) all_labels_list = list(label_descriptor_dict.keys()) all_labels_list.remove(0) all_labels_list.remove(255) all_labels_names = [] for l in all_labels_list: all_labels_names += [label_descriptor_dict[l][2]] # OUTPUT - figures and tables # Data, global pfi_df_global_outline_error = jph(path_manager.pfo_data_elaborations_leave_one_out, 'global_outline_error.pickle') pfi_df_global_dice_score = jph(path_manager.pfo_data_elaborations_leave_one_out, 'global_dice_score.pickle') pfi_barchart_global_dice_score_per_subjects = jph(path_manager.pfo_data_elaborations_leave_one_out, 'Barchart_global_dice_score.pdf')
def run_probabilistic_atlas_generator(commands, options): # Atlas data (input) - only the atlas, the label descriptor leading_modality = 'T1' pfi_labels_descriptor = jph(path_manager.pfo_multi_atlas, 'labels_descriptor.txt') # Probabilistic Atlas output if options['Bimodal']: pfo_subjects = jph(path_manager.pfo_root_probabilistic_atlas, 'subjects_bimodal') pfo_masks = jph(path_manager.pfo_root_probabilistic_atlas, 'masks_bimodal') else: pfo_subjects = jph(path_manager.pfo_root_probabilistic_atlas, 'subjects') pfo_masks = jph(path_manager.pfo_root_probabilistic_atlas, 'masks') pfo_all_segmentations = jph(path_manager.pfo_root_probabilistic_atlas, 'all_segm') pfo_tmp = jph(path_manager.pfo_root_probabilistic_atlas, 'z_tmp') pfo_pa_results = jph(path_manager.pfo_root_probabilistic_atlas, 'a_results') # most important # --- Main folder probabilistic atlas: print_and_run('mkdir {}'.format(path_manager.pfo_root_probabilistic_atlas)) if commands['Create_structure']: for p in [ pfo_subjects, pfo_masks, pfo_all_segmentations, pfo_pa_results, pfo_tmp ]: print_and_run('mkdir -p {}'.format(p)) # prepare folders structure and folder segmentations if commands['Prepare_data_in_folder_structure']: assert os.path.exists(pfo_all_segmentations) assert os.path.exists(pfo_tmp) for sj in path_manager.atlas_subjects: pfi_leading_mod = jph( path_manager.pfo_multi_atlas, sj, 'mod', '{0}_{1}.nii.gz'.format(sj, leading_modality)) pfi_segm = jph(path_manager.pfo_multi_atlas, sj, 'segm', '{0}_segm.nii.gz'.format(sj)) assert os.path.exists(pfi_leading_mod), pfi_leading_mod assert os.path.exists(pfi_segm), pfi_segm # ---- SEGMENTATION - just copy in the adequate folder --- pfi_segm_for_p_atlas = jph(pfo_all_segmentations, '{0}_segm.nii.gz'.format(sj)) print_and_run('cp {0} {1}'.format(pfi_segm, pfi_segm_for_p_atlas)) # ---- MASK AS BINARISED SEGMENTATION --- pfi_brain_mask = jph(pfo_tmp, '{0}_brain_tissue.nii.gz'.format(sj)) binarise_and_adjust_mask_from_segmentation_path( pfi_segm_input=pfi_segm_for_p_atlas, pfi_mask_output=pfi_brain_mask, pfo_temp=pfo_tmp, subject_name=sj, labels_to_exclude=[ 201, ]) # copy the obtained mask in the final masks folder, ready to create the probabilistic atlas. pfi_brain_mask_for_p_atlas = jph(pfo_masks, '{0}_mask.nii.gz'.format(sj)) print_and_run('cp {0} {1}'.format(pfi_brain_mask, pfi_brain_mask_for_p_atlas)) # ---- MAIN MODALITY --- # Trim: pfi_leading_mod_trimmed = jph( pfo_tmp, '{0}_{1}_trimmed.nii.gz'.format(sj, leading_modality)) print_and_run('seg_maths {0} -mul {1} {2}'.format( pfi_leading_mod, pfi_brain_mask_for_p_atlas, pfi_leading_mod_trimmed)) if options['Bimodal']: # prepare segmentation to be set in the second channel pfi_segm_prepared_for_second_channel = jph( pfo_tmp, '{}_segm_giraffe_skin.nii.gz'.format(sj)) prepare_mask_eroded_contour_from_segmentation_path( pfi_segm_for_p_atlas, pfi_segm_prepared_for_second_channel, pfo_tmp) # create stack mask and copy in the final folder: - will overwrite pfi_brain_mask_for_p_atlas pfi_stack_mask = jph( pfo_masks, '{0}_mask.nii.gz'.format(sj) ) # maks bimodal - will overwrite pfi_brain_mask_for_p_atlas cmd = 'seg_maths {0} -merge 1 4 {1} {2}'.format( pfi_brain_mask_for_p_atlas, pfi_brain_mask_for_p_atlas, pfi_stack_mask) print_and_run(cmd) # create stack modalities and copy in the final folder: pfi_stack_T1 = jph( pfo_subjects, '{}_bimodal.nii.gz'.format(sj)) # pfo_subject_bimodal cmd = 'seg_maths {0} -merge 1 4 {1} {2}'.format( pfi_leading_mod_trimmed, pfi_segm_prepared_for_second_channel, pfi_stack_T1) print_and_run(cmd) else: pfi_leading_mod_final = jph( pfo_subjects, '{0}_{1}.nii.gz'.format(sj, leading_modality)) print_and_run('cp {0} {1}'.format(pfi_leading_mod_trimmed, pfi_leading_mod_final)) pass if commands['Create_probabilistic_atlas']: here = os.path.dirname(os.path.realpath(__file__)) pfi_niftiyreg_run = jph(here, 'local_groupwise_niftyreg_run.sh') if options['Bimodal']: pfi_niftiyreg_param = jph( here, 'local_groupwise_niftyreg_params_bimodal.sh') cmd = 'cd {0}; ./groupwise_niftyreg_run.sh groupwise_niftyreg_params_bimodal.sh; cd {1}'.format( path_manager.pfo_root_probabilistic_atlas, here) else: pfi_niftiyreg_param = jph(here, 'local_groupwise_niftyreg_params.sh') cmd = 'cd {0}; ./groupwise_niftyreg_run.sh groupwise_niftyreg_params.sh; cd {1}'.format( path_manager.pfo_root_probabilistic_atlas, here) print_and_run('cp {0} {1}'.format( pfi_niftiyreg_run, jph(path_manager.pfo_root_probabilistic_atlas, 'groupwise_niftyreg_run.sh'))) if options['Bimodal']: print_and_run('cp {0} {1}'.format( pfi_niftiyreg_param, jph(path_manager.pfo_root_probabilistic_atlas, 'groupwise_niftyreg_params_bimodal.sh'))) else: print_and_run('cp {0} {1}'.format( pfi_niftiyreg_param, jph(path_manager.pfo_root_probabilistic_atlas, 'groupwise_niftyreg_params.sh'))) print_and_run(cmd) # Apply transformations obtained to create the probabilistic atlas global mask and average the results: if commands['Warp_anatomical']: # IMPORTANT!! This must be manually set and coherent with the content of the .sh params files # --- parameters: # number of affine loop to perform [for the paper 7] AFF_IT_NUM = 7 # number of non-rigid loop to perform [for the paper 7] NRR_IT_NUM = 7 if options['Bimodal']: results_folder = 'results_bimodal' subjects_folder = 'subjects_bimodal' masks_folder = 'masks_bimodal' mod_suffix = 'bimodal' else: results_folder = 'results' subjects_folder = 'subjects' masks_folder = 'masks' mod_suffix = 'T1' # suffix according to the study number (should indicate number of iterations and mono/multi) suffix_result = 'aff{0}nrig{1}'.format(AFF_IT_NUM, NRR_IT_NUM) # ---- pipeline: # copy and rename the results of the groupwise registration pfi_result_groupwise = jph( path_manager.pfo_root_probabilistic_atlas, results_folder, 'nrr_{}'.format(NRR_IT_NUM), 'average_nonrigid_it_{}.nii.gz'.format(NRR_IT_NUM)) assert os.path.exists(pfi_result_groupwise), pfi_result_groupwise pfi_result_groupwise_copy = jph( pfo_pa_results, 'PA_{0}_{1}.nii.gz'.format(mod_suffix, suffix_result)) cmd = 'seg_maths {0} -thr 0 {1}'.format(pfi_result_groupwise, pfi_result_groupwise_copy) print_and_run(cmd) # if multimodal, take only the first timepoint if results_folder == 'results_bimodal': pfi_result_groupwise_copy_tp1 = jph( pfo_pa_results, 'PA_T1_{0}_{1}_tp1.nii.gz'.format(mod_suffix, suffix_result)) cmd = 'seg_maths {0} -tp 0 {1}'.format( pfi_result_groupwise_copy, pfi_result_groupwise_copy_tp1) print_and_run(cmd) # resample each segmentation with the final transformation pfi_reference_image = jph(path_manager.pfo_root_probabilistic_atlas, subjects_folder, '1305_{}.nii.gz'.format(mod_suffix)) assert os.path.exists(pfi_reference_image), pfi_reference_image for sj in path_manager.atlas_subjects: print sj # Resample the segmentations. pfi_segmentation_sj = jph( path_manager.pfo_root_probabilistic_atlas, 'all_segm', '{}_segm.nii.gz'.format(sj)) pfi_sj_final_transformation = jph( path_manager.pfo_root_probabilistic_atlas, results_folder, 'nrr_{}'.format(NRR_IT_NUM), 'nrr_cpp_{0}_{1}_it{2}.nii.gz'.format(sj, mod_suffix, NRR_IT_NUM)) assert os.path.exists(pfi_segmentation_sj), pfi_segmentation_sj assert os.path.exists( pfi_sj_final_transformation), pfi_sj_final_transformation pfi_sj_warped_segmentation = jph( pfo_pa_results, 'segm_{0}_warped_on_average_atlas.nii.gz'.format(sj)) cmd = 'reg_resample -ref {0} -flo {1} -trans {2} -res {3} -inter 0'.format( pfi_reference_image, pfi_segmentation_sj, pfi_sj_final_transformation, pfi_sj_warped_segmentation) print_and_run(cmd) # Resample the Masks. pfi_mask_sj = jph(path_manager.pfo_root_probabilistic_atlas, masks_folder, '{0}_mask.nii.gz'.format(sj)) assert os.path.exists(pfi_mask_sj), pfi_mask_sj pfi_sj_warped_mask = jph( pfo_pa_results, 'mask_{0}_warped_on_average_atlas.nii.gz'.format(sj)) cmd = 'reg_resample -ref {0} -flo {1} -trans {2} -res {3} -inter 0'.format( pfi_reference_image, pfi_mask_sj, pfi_sj_final_transformation, pfi_sj_warped_mask) print_and_run(cmd) # ------------------------------------------------------------------------- # # Now we have the resulting warped segmentations and the probabilistic T1. # We can do some manipulations to have what we need: # ------------------------------------------------------------------------- # # We can generate an image with the probabilities for each label if commands['Create_probability_for_each_level']: if options['Bimodal']: subjects_folder = 'subjects_bimodal' mod_suffix = 'bimodal' else: subjects_folder = 'subjects' mod_suffix = 'T1' pfo_probabilities = jph(pfo_pa_results, 'probabilities') print_and_run('mkdir -p {}'.format(pfo_probabilities)) ldm = LdM(pfi_labels_descriptor) dict_labels = ldm.get_dict() for l in dict_labels.keys(): print '\nLabel {}'.format(l) pfi_prob_finding_label_l = jph(pfo_probabilities, 'prob_label_{}.nii.gz'.format(l)) # generate new empty data: pfi_reference_image = jph( path_manager.pfo_root_probabilistic_atlas, subjects_folder, '1305_{}.nii.gz'.format(mod_suffix)) assert os.path.exists(pfi_reference_image), pfi_reference_image im_ref = nib.load(pfi_reference_image) data_label_l = np.zeros_like(im_ref) # fill data_label_l with all the labels for sj in path_manager.atlas_subjects: print 'Subject {}'.format(sj) pfi_sj_warped_segmentation = jph( pfo_pa_results, 'segm_{0}_warped_on_average_atlas.nii.gz'.format(sj)) im_warp_segm_sj = nib.load(pfi_sj_warped_segmentation) where_l = im_warp_segm_sj.get_data() == l data_label_l = data_label_l + where_l.astype(np.float64) # normalise the filled labels: m = np.max(data_label_l) # in case the label is not present in the segmentation warn the user if m > 0: data_label_l = data_label_l / float(m) else: print 'Label {} not present in the segmentations'.format(l) im_prob_label_l = set_new_data(im_ref, data_label_l) nib.save(im_prob_label_l, pfi_prob_finding_label_l)