From a858c161136c3fdb2b7396e3fd90443c5fba5cdc Mon Sep 17 00:00:00 2001 From: LuciMoore Date: Thu, 1 Feb 2024 15:10:50 -0800 Subject: [PATCH 1/8] modified postbibsnet workflow to include crude chirality correction based on separating image down the middle into left and right first before applying the more refined correction using nonlinear registration with templates --- src/postbibsnet.py | 91 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/src/postbibsnet.py b/src/postbibsnet.py index 8cccaaa..4730c9d 100755 --- a/src/postbibsnet.py +++ b/src/postbibsnet.py @@ -55,6 +55,17 @@ def run_postBIBSnet(j_args): else: # if j_args["ID"]["has_T2w"]: t1or2 = 2 + LOGGER.info("Generating crude L/R mask for first iteration of chirality correction") + # Generate crude chirality correction mask file first + left_right_mask_nifti_fpath = create_crude_LR_mask( + sub_ses, j_args + ) + + LOGGER.info("Applying crude L/R mask for first iteration of chirality correction") + #Apply crude LR mask to BIBSNet segmentation + nifti_file_paths, chiral_out_dir, xfm_ref_img_dict = run_correct_chirality(left_right_mask_nifti_fpath, j_args) + + LOGGER.info("Generating L/R mask from registration using templates for second iteration of chirality correction") # Run left/right registration script and chirality correction left_right_mask_nifti_fpath = run_left_right_registration( sub_ses, tmpl_age, t1or2, j_args @@ -68,7 +79,7 @@ def run_postBIBSnet(j_args): left_right_mask_nifti_fpath ) LOGGER.info("Finished dilating left/right segmentation mask") - nifti_file_paths, chiral_out_dir, xfm_ref_img_dict = run_correct_chirality(dilated_LRmask_fpath, j_args) + nifti_file_paths, chiral_out_dir, xfm_ref_img_dict = run_correct_chirality_iteration2(dilated_LRmask_fpath, j_args) for t in only_Ts_needed_for_bibsnet_model(j_args["ID"]): nii_outfpath = reverse_regn_revert_to_native( nifti_file_paths, chiral_out_dir, xfm_ref_img_dict[t], t, j_args @@ -160,6 +171,84 @@ def run_correct_chirality(l_r_mask_nifti_fpath, j_args): return nii_fpaths, chiral_out_dir, chiral_ref_img_fpaths_dict +def run_correct_chirality_iteration2(l_r_mask_nifti_fpath, j_args): + """ + :param l_r_mask_nifti_fpath: String, valid path to existing left/right + registration output mask file + :param j_args: Dictionary containing all args + :return nii_fpaths: Dictionary output of correct_chirality + :return chiral_out_dir: String file path to output directory + :return chiral_ref_img_fpaths_dict: Dictionary containing T1w and T2w file paths + """ + sub_ses = get_subj_ID_and_session(j_args) + + # Define paths to dirs/files used in chirality correction script + chiral_out_dir = os.path.join(j_args["optional_out_dirs"]["postbibsnet"], + *sub_ses, "chirality_correction") # subj_ID, session, + os.makedirs(chiral_out_dir, exist_ok=True) + segment_lookup_table_path = os.path.join(SCRIPT_DIR, "data", "look_up_tables", + "FreeSurferColorLUT.txt") + + out_cciteration1_seg=nii_fpaths["corrected"] + + # Select an arbitrary T1w image path to use to get T1w space + # (unless in T2w-only mode, in which case use an arbitrary T2w image) + chiral_ref_img_fpaths_dict = {} + for t in only_Ts_needed_for_bibsnet_model(j_args["ID"]): + chiral_ref_img_fpaths = glob(os.path.join( + j_args["common"]["bids_dir"], *sub_ses, "anat", f"*_T{t}w.nii.gz" + )) + chiral_ref_img_fpaths.sort() + chiral_ref_img_fpaths_dict[t] = chiral_ref_img_fpaths[0] + + # Run chirality correction script and return the image to native space + msg = "{} running chirality correction on " + out_cciteration1_seg + LOGGER.info(msg.format("Now")) + nii_fpaths = correct_chirality( + out_cciteration1_seg, segment_lookup_table_path, + l_r_mask_nifti_fpath, chiral_out_dir + ) + LOGGER.info(msg.format("Finished")) + + return nii_fpaths, chiral_out_dir, chiral_ref_img_fpaths_dict + +def create_crude_LR_mask(sub_ses, j_args): + # Define paths to dirs/files used in chirality correction script + outdir_LR_reg = os.path.join(j_args["optional_out_dirs"]["postbibsnet"], + *sub_ses) + os.makedirs(outdir_LR_reg, exist_ok=True) + + chiral_out_dir = os.path.join(j_args["optional_out_dirs"]["postbibsnet"], + *sub_ses, "chirality_correction") # subj_ID, session, + os.makedirs(chiral_out_dir, exist_ok=True) + + # Get BIBSnet output file, and if there are multiple, then raise an error + out_BIBSnet_seg = os.path.join(j_args["optional_out_dirs"]["bibsnet"], + *sub_ses, "output", "*.nii.gz") + + left_right_mask_nifti_fpath = os.path.join(outdir_LR_reg, "LRmask.nii.gz") + + img = nib.load(out_BIBSnet_seg) + data = img.get_fdata() + affine = img.affine + + # Determine the midpoint of X-axis and make new image + midpoint_x = data.shape[0] // 2 + modified_data = np.zeros_like(data) + + # Assign value 1 to left-side voxels with values greater than 0 value 2 to right-side voxels with values greater than 0 + modified_data[:midpoint_x, :, :][data[:midpoint_x, :, :] > 0] = 1 + modified_data[midpoint_x:, :, :][data[midpoint_x:, :, :] > 0] = 2 + + nib.save(img, out_BIBSnet_seg) + save_nifti(modified_data, affine, left_right_mask_nifti_fpath) + + return left_right_mask_nifti_fpath + +def save_nifti(data, affine, file_path): + img = nib.Nifti1Image(data, affine) + nib.save(img, file_path) + def run_left_right_registration(sub_ses, age_months, t1or2, j_args): """ From 78c51191d73853aab9d1f6589832fcf969ff60fe Mon Sep 17 00:00:00 2001 From: LuciMoore Date: Thu, 1 Feb 2024 15:30:58 -0800 Subject: [PATCH 2/8] changed name of crude LR mask to be different from refined LR mask and added logic to save final j_args dictionary to csv file --- src/postbibsnet.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/postbibsnet.py b/src/postbibsnet.py index 4730c9d..e3eb0b7 100755 --- a/src/postbibsnet.py +++ b/src/postbibsnet.py @@ -8,6 +8,7 @@ import numpy as np import json from scipy import ndimage +import csv from src.logger import LOGGER @@ -57,13 +58,13 @@ def run_postBIBSnet(j_args): LOGGER.info("Generating crude L/R mask for first iteration of chirality correction") # Generate crude chirality correction mask file first - left_right_mask_nifti_fpath = create_crude_LR_mask( + crude_left_right_mask_nifti_fpath = create_crude_LR_mask( sub_ses, j_args ) LOGGER.info("Applying crude L/R mask for first iteration of chirality correction") #Apply crude LR mask to BIBSNet segmentation - nifti_file_paths, chiral_out_dir, xfm_ref_img_dict = run_correct_chirality(left_right_mask_nifti_fpath, j_args) + nifti_file_paths, chiral_out_dir, xfm_ref_img_dict = run_correct_chirality(crude_left_right_mask_nifti_fpath, j_args) LOGGER.info("Generating L/R mask from registration using templates for second iteration of chirality correction") # Run left/right registration script and chirality correction @@ -121,6 +122,14 @@ def run_postBIBSnet(j_args): return j_args + # Write j_args out to csv + j_args_csv = 'j_args.csv' + with open(j_args_csv, 'w', newline='') as csvfile: + csv_writer = csv.writer(csvfile) + csv_writer.writerow(['Key', 'Value']) + for key, value in j_args.items(): + csv_writer.writerow([key, value]) + def run_correct_chirality(l_r_mask_nifti_fpath, j_args): """ @@ -226,7 +235,7 @@ def create_crude_LR_mask(sub_ses, j_args): out_BIBSnet_seg = os.path.join(j_args["optional_out_dirs"]["bibsnet"], *sub_ses, "output", "*.nii.gz") - left_right_mask_nifti_fpath = os.path.join(outdir_LR_reg, "LRmask.nii.gz") + crude_left_right_mask_nifti_fpath = os.path.join(outdir_LR_reg, "crude_LRmask.nii.gz") img = nib.load(out_BIBSnet_seg) data = img.get_fdata() @@ -243,7 +252,7 @@ def create_crude_LR_mask(sub_ses, j_args): nib.save(img, out_BIBSnet_seg) save_nifti(modified_data, affine, left_right_mask_nifti_fpath) - return left_right_mask_nifti_fpath + return crude_left_right_mask_nifti_fpath def save_nifti(data, affine, file_path): img = nib.Nifti1Image(data, affine) From fb2408794ace0368255486c97a7656cee33383e4 Mon Sep 17 00:00:00 2001 From: LuciMoore Date: Thu, 1 Feb 2024 18:44:40 -0800 Subject: [PATCH 3/8] fixed path to grab output BIBSNet aseg in crude LR mask function --- src/postbibsnet.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/postbibsnet.py b/src/postbibsnet.py index e3eb0b7..1c15f0e 100755 --- a/src/postbibsnet.py +++ b/src/postbibsnet.py @@ -234,10 +234,16 @@ def create_crude_LR_mask(sub_ses, j_args): # Get BIBSnet output file, and if there are multiple, then raise an error out_BIBSnet_seg = os.path.join(j_args["optional_out_dirs"]["bibsnet"], *sub_ses, "output", "*.nii.gz") + seg_BIBSnet_outfiles = glob(out_BIBSnet_seg) + if len(seg_BIBSnet_outfiles) != 1: + LOGGER.error(f"There must be exactly one BIBSnet segmentation file: " + "{}\nResume at postBIBSnet stage once this is fixed." + .format(out_BIBSnet_seg)) + sys.exit() crude_left_right_mask_nifti_fpath = os.path.join(outdir_LR_reg, "crude_LRmask.nii.gz") - img = nib.load(out_BIBSnet_seg) + img = nib.load(seg_BIBSnet_outfiles[0]) data = img.get_fdata() affine = img.affine @@ -249,8 +255,8 @@ def create_crude_LR_mask(sub_ses, j_args): modified_data[:midpoint_x, :, :][data[:midpoint_x, :, :] > 0] = 1 modified_data[midpoint_x:, :, :][data[midpoint_x:, :, :] > 0] = 2 - nib.save(img, out_BIBSnet_seg) - save_nifti(modified_data, affine, left_right_mask_nifti_fpath) + nib.save(img, seg_BIBSnet_outfiles[0]) + save_nifti(modified_data, affine, crude_left_right_mask_nifti_fpath) return crude_left_right_mask_nifti_fpath From 0e46f54139622847d423c159657f42e161e0c2af Mon Sep 17 00:00:00 2001 From: LuciMoore Date: Fri, 2 Feb 2024 14:18:49 -0800 Subject: [PATCH 4/8] replace writing j_args out to csv with LOGGER.debug to write out to logs --- src/postbibsnet.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/postbibsnet.py b/src/postbibsnet.py index 1c15f0e..f897630 100755 --- a/src/postbibsnet.py +++ b/src/postbibsnet.py @@ -122,14 +122,8 @@ def run_postBIBSnet(j_args): return j_args - # Write j_args out to csv - j_args_csv = 'j_args.csv' - with open(j_args_csv, 'w', newline='') as csvfile: - csv_writer = csv.writer(csvfile) - csv_writer.writerow(['Key', 'Value']) - for key, value in j_args.items(): - csv_writer.writerow([key, value]) - + # Write j_args out to logs + LOGGER.debug(j_args) def run_correct_chirality(l_r_mask_nifti_fpath, j_args): """ From 688b17f1439f4dcccccdfe43adbdecdce2b44620 Mon Sep 17 00:00:00 2001 From: LuciMoore Date: Wed, 7 Feb 2024 17:44:04 -0800 Subject: [PATCH 5/8] removed erroneous line from crude LR mask creation that corrupts files --- src/postbibsnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/postbibsnet.py b/src/postbibsnet.py index f897630..cb7f68a 100755 --- a/src/postbibsnet.py +++ b/src/postbibsnet.py @@ -249,7 +249,7 @@ def create_crude_LR_mask(sub_ses, j_args): modified_data[:midpoint_x, :, :][data[:midpoint_x, :, :] > 0] = 1 modified_data[midpoint_x:, :, :][data[midpoint_x:, :, :] > 0] = 2 - nib.save(img, seg_BIBSnet_outfiles[0]) + #nib.save(img, seg_BIBSnet_outfiles[0]) save_nifti(modified_data, affine, crude_left_right_mask_nifti_fpath) return crude_left_right_mask_nifti_fpath From ce00b2e9f99aabd277537012dc7f29677afae9af Mon Sep 17 00:00:00 2001 From: LuciMoore Date: Wed, 14 Feb 2024 14:12:25 -0800 Subject: [PATCH 6/8] combined run_correct_chirality functions into 1 and added extra argument to specifcy the 2 different LR masks to use when running correct_chirality twice within function --- src/postbibsnet.py | 58 +++++++++++----------------------------------- 1 file changed, 14 insertions(+), 44 deletions(-) diff --git a/src/postbibsnet.py b/src/postbibsnet.py index cb7f68a..50334d3 100755 --- a/src/postbibsnet.py +++ b/src/postbibsnet.py @@ -62,10 +62,6 @@ def run_postBIBSnet(j_args): sub_ses, j_args ) - LOGGER.info("Applying crude L/R mask for first iteration of chirality correction") - #Apply crude LR mask to BIBSNet segmentation - nifti_file_paths, chiral_out_dir, xfm_ref_img_dict = run_correct_chirality(crude_left_right_mask_nifti_fpath, j_args) - LOGGER.info("Generating L/R mask from registration using templates for second iteration of chirality correction") # Run left/right registration script and chirality correction left_right_mask_nifti_fpath = run_left_right_registration( @@ -80,7 +76,11 @@ def run_postBIBSnet(j_args): left_right_mask_nifti_fpath ) LOGGER.info("Finished dilating left/right segmentation mask") - nifti_file_paths, chiral_out_dir, xfm_ref_img_dict = run_correct_chirality_iteration2(dilated_LRmask_fpath, j_args) + + LOGGER.info("Running chirality correction") + nifti_file_paths, chiral_out_dir, xfm_ref_img_dict = run_correct_chirality(crude_left_right_mask_nifti_fpath, dilated_LRmask_fpath, j_args) + + LOGGER.info("Reverting corrected segmentation to native space") for t in only_Ts_needed_for_bibsnet_model(j_args["ID"]): nii_outfpath = reverse_regn_revert_to_native( nifti_file_paths, chiral_out_dir, xfm_ref_img_dict[t], t, j_args @@ -125,8 +125,10 @@ def run_postBIBSnet(j_args): # Write j_args out to logs LOGGER.debug(j_args) -def run_correct_chirality(l_r_mask_nifti_fpath, j_args): +def run_correct_chirality(crude_l_r_mask_nifti_fpath, l_r_mask_nifti_fpath, j_args): """ + :param crude_l_r_mask_nifti_fpath: String, valid path to existing crude left/right + output mask file :param l_r_mask_nifti_fpath: String, valid path to existing left/right registration output mask file :param j_args: Dictionary containing all args @@ -163,54 +165,22 @@ def run_correct_chirality(l_r_mask_nifti_fpath, j_args): chiral_ref_img_fpaths.sort() chiral_ref_img_fpaths_dict[t] = chiral_ref_img_fpaths[0] - # Run chirality correction script and return the image to native space + # Run chirality correction first using the crude LR mask applied to the segmentation output from nnUNet in the BIBSNet stage msg = "{} running chirality correction on " + seg_BIBSnet_outfiles[0] LOGGER.info(msg.format("Now")) nii_fpaths = correct_chirality( seg_BIBSnet_outfiles[0], segment_lookup_table_path, - l_r_mask_nifti_fpath, chiral_out_dir + crude_l_r_mask_nifti_fpath, chiral_out_dir ) - LOGGER.info(msg.format("Finished")) - - return nii_fpaths, chiral_out_dir, chiral_ref_img_fpaths_dict - -def run_correct_chirality_iteration2(l_r_mask_nifti_fpath, j_args): - """ - :param l_r_mask_nifti_fpath: String, valid path to existing left/right - registration output mask file - :param j_args: Dictionary containing all args - :return nii_fpaths: Dictionary output of correct_chirality - :return chiral_out_dir: String file path to output directory - :return chiral_ref_img_fpaths_dict: Dictionary containing T1w and T2w file paths - """ - sub_ses = get_subj_ID_and_session(j_args) - - # Define paths to dirs/files used in chirality correction script - chiral_out_dir = os.path.join(j_args["optional_out_dirs"]["postbibsnet"], - *sub_ses, "chirality_correction") # subj_ID, session, - os.makedirs(chiral_out_dir, exist_ok=True) - segment_lookup_table_path = os.path.join(SCRIPT_DIR, "data", "look_up_tables", - "FreeSurferColorLUT.txt") - - out_cciteration1_seg=nii_fpaths["corrected"] - # Select an arbitrary T1w image path to use to get T1w space - # (unless in T2w-only mode, in which case use an arbitrary T2w image) - chiral_ref_img_fpaths_dict = {} - for t in only_Ts_needed_for_bibsnet_model(j_args["ID"]): - chiral_ref_img_fpaths = glob(os.path.join( - j_args["common"]["bids_dir"], *sub_ses, "anat", f"*_T{t}w.nii.gz" - )) - chiral_ref_img_fpaths.sort() - chiral_ref_img_fpaths_dict[t] = chiral_ref_img_fpaths[0] - - # Run chirality correction script and return the image to native space - msg = "{} running chirality correction on " + out_cciteration1_seg + # Run chirality correction a second time using the refined LR mask generated from registration with template files applied to the segmentation corrected with the crude LR mask + msg = "{} running chirality correction on " + nii_fpaths["corrected"] LOGGER.info(msg.format("Now")) nii_fpaths = correct_chirality( - out_cciteration1_seg, segment_lookup_table_path, + nii_fpaths["corrected"], segment_lookup_table_path, l_r_mask_nifti_fpath, chiral_out_dir ) + LOGGER.info(msg.format("Finished")) return nii_fpaths, chiral_out_dir, chiral_ref_img_fpaths_dict From a0d92f5aa4a024d4f5280e3366f2c72a704cc9fe Mon Sep 17 00:00:00 2001 From: LuciMoore Date: Thu, 15 Feb 2024 14:16:28 -0800 Subject: [PATCH 7/8] fixed crude LR mask to have correct values assigned (1 for L hemi/right side of image and 2 for R hemi/left side of image) --- src/postbibsnet.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/postbibsnet.py b/src/postbibsnet.py index 50334d3..f91df39 100755 --- a/src/postbibsnet.py +++ b/src/postbibsnet.py @@ -215,9 +215,9 @@ def create_crude_LR_mask(sub_ses, j_args): midpoint_x = data.shape[0] // 2 modified_data = np.zeros_like(data) - # Assign value 1 to left-side voxels with values greater than 0 value 2 to right-side voxels with values greater than 0 - modified_data[:midpoint_x, :, :][data[:midpoint_x, :, :] > 0] = 1 - modified_data[midpoint_x:, :, :][data[midpoint_x:, :, :] > 0] = 2 + # Assign value 1 to right-side voxels with values greater than 0 value 2 to left-side voxels with values greater than 0 (note that these actually correspond to left and right brain hemispheres respectively) + modified_data[midpoint_x:, :, :][data[midpoint_x:, :, :] > 0] = 1 + modified_data[:midpoint_x, :, :][data[:midpoint_x, :, :] > 0] = 2 #nib.save(img, seg_BIBSnet_outfiles[0]) save_nifti(modified_data, affine, crude_left_right_mask_nifti_fpath) From 0a8070493762aeb941481bb44c2a9928f468eec9 Mon Sep 17 00:00:00 2001 From: LuciMoore Date: Thu, 15 Feb 2024 15:06:09 -0800 Subject: [PATCH 8/8] added intermediate crudecorrected aseg filepath in correct_chirality function and additional argument iteration plus corresponding logic to handle each iteration approporiately and generate cleaner filenames --- src/postbibsnet.py | 116 ++++++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 38 deletions(-) diff --git a/src/postbibsnet.py b/src/postbibsnet.py index f91df39..9c7460e 100755 --- a/src/postbibsnet.py +++ b/src/postbibsnet.py @@ -170,15 +170,15 @@ def run_correct_chirality(crude_l_r_mask_nifti_fpath, l_r_mask_nifti_fpath, j_ar LOGGER.info(msg.format("Now")) nii_fpaths = correct_chirality( seg_BIBSnet_outfiles[0], segment_lookup_table_path, - crude_l_r_mask_nifti_fpath, chiral_out_dir + crude_l_r_mask_nifti_fpath, chiral_out_dir, 1 ) # Run chirality correction a second time using the refined LR mask generated from registration with template files applied to the segmentation corrected with the crude LR mask - msg = "{} running chirality correction on " + nii_fpaths["corrected"] + msg = "{} running chirality correction on " + nii_fpaths["crudecorrected"] LOGGER.info(msg.format("Now")) nii_fpaths = correct_chirality( - nii_fpaths["corrected"], segment_lookup_table_path, - l_r_mask_nifti_fpath, chiral_out_dir + nii_fpaths["crudecorrected"], segment_lookup_table_path, + l_r_mask_nifti_fpath, chiral_out_dir, 2 ) LOGGER.info(msg.format("Finished")) @@ -340,7 +340,7 @@ def copy_to_derivatives_dir(file_to_copy, derivs_dir, sub_ses, space, new_fname_ def correct_chirality(nifti_input_file_path, segment_lookup_table, - nii_fpath_LR_mask, chiral_out_dir): + nii_fpath_LR_mask, chiral_out_dir, iteration): """ Creates an output file with chirality corrections fixed. :param nifti_input_file_path: String, path to a segmentation file with @@ -351,42 +351,82 @@ def correct_chirality(nifti_input_file_path, segment_lookup_table, :param xfm_ref_img: String, path to (T1w, unless running in T2w-only mode) image to use as a reference when applying transform :param j_args: Dictionary containing all args + :param iteration: either 1 or 2 for iteration1 or iteration2 of chirality correction :return: Dict with paths to native and chirality-corrected images """ - nifti_file_paths = dict() - for which_nii in ("native-T1", "native-T2", "corrected"): - nifti_file_paths[which_nii] = os.path.join(chiral_out_dir, "_".join(( - which_nii, os.path.basename(nifti_input_file_path) - ))) + if iteration==1: + nifti_file_paths = dict() + for which_nii in ("native-T1", "native-T2", "crudecorrected"): + nifti_file_paths[which_nii] = os.path.join(chiral_out_dir, "_".join(( + which_nii, os.path.basename(nifti_input_file_path) + ))) + + free_surfer_label_to_region = get_id_to_region_mapping(segment_lookup_table) + segment_name_to_number = {v: k for k, v in free_surfer_label_to_region.items()} + img = nib.load(nifti_input_file_path) + data = img.get_data() + left_right_img = nib.load(nii_fpath_LR_mask) + left_right_data = left_right_img.get_data() + + new_data = data.copy() + data_shape = img.header.get_data_shape() + left_right_data_shape = left_right_img.header.get_data_shape() + width = data_shape[0] + height = data_shape[1] + depth = data_shape[2] + assert \ + width == left_right_data_shape[0] and height == left_right_data_shape[1] and depth == left_right_data_shape[2] + for i in range(width): + for j in range(height): + for k in range(depth): + voxel = data[i][j][k] + region = free_surfer_label_to_region[voxel] + chirality_voxel = int(left_right_data[i][j][k]) + if not (region.startswith(LEFT) or region.startswith(RIGHT)): + continue + if chirality_voxel == CHIRALITY_CONST["LEFT"] or chirality_voxel == CHIRALITY_CONST["RIGHT"]: + check_and_correct_region( + chirality_voxel == CHIRALITY_CONST["LEFT"], region, segment_name_to_number, new_data, i, j, k) + fixed_img = nib.Nifti1Image(new_data, img.affine, img.header) + nib.save(fixed_img, nifti_file_paths["crudecorrected"]) + + elif iteration==2: + # Drop "crudecorrected_" from nifti_input_file_path to make filenames cleaner + nifti_input_file_path_mod=(os.path.basename(nifti_input_file_path)).split('_', 1)[1] + nifti_file_paths = dict() + for which_nii in ("native-T1", "native-T2", "corrected"): + nifti_file_paths[which_nii] = os.path.join(chiral_out_dir, "_".join(( + which_nii, nifti_input_file_path_mod + ))) - free_surfer_label_to_region = get_id_to_region_mapping(segment_lookup_table) - segment_name_to_number = {v: k for k, v in free_surfer_label_to_region.items()} - img = nib.load(nifti_input_file_path) - data = img.get_data() - left_right_img = nib.load(nii_fpath_LR_mask) - left_right_data = left_right_img.get_data() - - new_data = data.copy() - data_shape = img.header.get_data_shape() - left_right_data_shape = left_right_img.header.get_data_shape() - width = data_shape[0] - height = data_shape[1] - depth = data_shape[2] - assert \ - width == left_right_data_shape[0] and height == left_right_data_shape[1] and depth == left_right_data_shape[2] - for i in range(width): - for j in range(height): - for k in range(depth): - voxel = data[i][j][k] - region = free_surfer_label_to_region[voxel] - chirality_voxel = int(left_right_data[i][j][k]) - if not (region.startswith(LEFT) or region.startswith(RIGHT)): - continue - if chirality_voxel == CHIRALITY_CONST["LEFT"] or chirality_voxel == CHIRALITY_CONST["RIGHT"]: - check_and_correct_region( - chirality_voxel == CHIRALITY_CONST["LEFT"], region, segment_name_to_number, new_data, i, j, k) - fixed_img = nib.Nifti1Image(new_data, img.affine, img.header) - nib.save(fixed_img, nifti_file_paths["corrected"]) + free_surfer_label_to_region = get_id_to_region_mapping(segment_lookup_table) + segment_name_to_number = {v: k for k, v in free_surfer_label_to_region.items()} + img = nib.load(nifti_input_file_path) + data = img.get_data() + left_right_img = nib.load(nii_fpath_LR_mask) + left_right_data = left_right_img.get_data() + + new_data = data.copy() + data_shape = img.header.get_data_shape() + left_right_data_shape = left_right_img.header.get_data_shape() + width = data_shape[0] + height = data_shape[1] + depth = data_shape[2] + assert \ + width == left_right_data_shape[0] and height == left_right_data_shape[1] and depth == left_right_data_shape[2] + for i in range(width): + for j in range(height): + for k in range(depth): + voxel = data[i][j][k] + region = free_surfer_label_to_region[voxel] + chirality_voxel = int(left_right_data[i][j][k]) + if not (region.startswith(LEFT) or region.startswith(RIGHT)): + continue + if chirality_voxel == CHIRALITY_CONST["LEFT"] or chirality_voxel == CHIRALITY_CONST["RIGHT"]: + check_and_correct_region( + chirality_voxel == CHIRALITY_CONST["LEFT"], region, segment_name_to_number, new_data, i, j, k) + fixed_img = nib.Nifti1Image(new_data, img.affine, img.header) + nib.save(fixed_img, nifti_file_paths["corrected"]) return nifti_file_paths