register_masks.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import argparse
  2. import subprocess
  3. import shlex
  4. import os
  5. import glob
  6. import csv
  7. import nibabel as nib
  8. import numpy as np
  9. from tqdm import tqdm
  10. def main():
  11. parser = argparse.ArgumentParser(description="Image Registration and Resampling")
  12. parser.add_argument("-i", "--input", required=True, help="Path to main folder of the nii Converted Data that are already processed with AIDAmri, e.g proc_data")
  13. parser.add_argument("-m", "--masks", required=True, help="Path to the folder containing the drawn masks. They should be in the MTPL space!")
  14. args = parser.parse_args()
  15. missing_matrix_paths = []
  16. # Parsing for all BiasBet.nii.gz files in T2w folders after a given input path.
  17. T2BetPath = os.path.join(args.input,"**","anat","*BiasBet.nii.gz")
  18. T2BetFiles = glob.glob(T2BetPath,recursive=True)
  19. # Parsing for all given masks.
  20. FloatingMasksPath = os.path.join(args.masks, "*.nii*")
  21. FloatingMasksFiles = glob.glob(FloatingMasksPath)
  22. total_iterations = len(T2BetFiles) * len(FloatingMasksFiles)
  23. progress_bar = tqdm(total=total_iterations, desc='Registration Progress (Mask to Anatomical T2w)', unit='files')
  24. for ff in T2BetFiles:
  25. for mm in FloatingMasksFiles:
  26. MaskName = os.path.basename(mm).replace(".nii","").replace(".gz","")
  27. NewMaskName = MaskName + "_anat" + ".nii.gz"
  28. NewMaskFolder = os.path.join(os.path.dirname(ff),"RegisteredTractMasks")
  29. NewMaskAddress = os.path.join(NewMaskFolder,NewMaskName)
  30. if not os.path.exists(NewMaskFolder):
  31. os.makedirs(NewMaskFolder)
  32. Affine_matrix_files = glob.glob(os.path.join(os.path.dirname(ff),"*MatrixAff.txt"))
  33. if not Affine_matrix_files:
  34. missing_matrix_paths.append(os.path.dirname(ff))
  35. continue
  36. Affine_matrix = Affine_matrix_files[0]
  37. # Execute the command
  38. command = f"reg_resample -ref {ff} -flo {mm} -res {NewMaskAddress} -trans {Affine_matrix} -inter 0"
  39. command_args = shlex.split(command)
  40. try:
  41. result = subprocess.run(command_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  42. print(f"Output:\n{result.stdout.decode()}")
  43. print(f"Errors:\n{result.stderr.decode()}")
  44. except Exception as e:
  45. print(f"An error occurred: {e}")
  46. progress_bar.update(1)
  47. progress_bar.close()
  48. print("Registered all masks to t2w space of individual mice: DONE\n")
  49. # Parsing for all SmoothMicoBet.nii.gz files in DTI folders after a given input path.
  50. DTIBetPath = os.path.join(args.input,"**","dwi*","*SmoothMicoBet.nii.gz")
  51. DTIBetFiles = glob.glob(DTIBetPath,recursive=True)
  52. total_iterations = len(DTIBetFiles) * len(FloatingMasksFiles)
  53. progress_bar = tqdm(total=total_iterations, desc='Registration Progress (to diffusion dwi) and adjusting for fa, ad, md maps', unit='files')
  54. for ff in DTIBetFiles:
  55. temp = os.path.dirname(os.path.dirname(ff))
  56. t2MasksPath = os.path.join(temp,"anat","RegisteredTractMasks","*nii.gz")
  57. FloatingMasksFiles = glob.glob(t2MasksPath)
  58. for mm in FloatingMasksFiles:
  59. MaskName = os.path.basename(mm).replace("anat","dwi")
  60. NewMaskName = MaskName
  61. NewMaskFolder = os.path.join(os.path.dirname(ff),"RegisteredTractMasks")
  62. NewMaskAddress = os.path.join(NewMaskFolder,NewMaskName)
  63. if not os.path.exists(NewMaskFolder):
  64. os.makedirs(NewMaskFolder)
  65. Affine_matrix_files = glob.glob(os.path.join(os.path.dirname(ff),"*MatrixAff.txt"))
  66. if not Affine_matrix_files:
  67. missing_matrix_paths.append(os.path.dirname(ff))
  68. continue
  69. Affine_matrix = Affine_matrix_files[0]
  70. command = f"reg_resample -ref {ff} -flo {mm} -res {NewMaskAddress} -trans {Affine_matrix} -inter 0"
  71. command_args = shlex.split(command)
  72. try:
  73. result = subprocess.run(command_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  74. print(f"Output:\n{result.stdout.decode()}")
  75. print(f"Errors:\n{result.stderr.decode()}")
  76. except Exception as e:
  77. print(f"An error occurred: {e}")
  78. progress_bar.update(1)
  79. progress_bar.close()
  80. print("Registered all masks to t2w space of individual mice: DONE\n")
  81. # Adjust by flipping for the fa0 and ad files
  82. # Locate all files in the "RegisteredTractMasks" folder
  83. registered_masks_path = os.path.join(args.input,"**","RegisteredTractMasks", "*.nii.gz")
  84. registered_masks_files = glob.glob(registered_masks_path, recursive=True)
  85. total_iterations = len(registered_masks_files)
  86. progress_bar = tqdm(total=total_iterations, desc='Flipping Masks', unit='files')
  87. for mask_file in registered_masks_files:
  88. # Load the mask file
  89. mask_nifti = nib.load(mask_file)
  90. mask_data = mask_nifti.get_fdata()
  91. # Flip the mask along the Y and Z axes
  92. #flipped_mask = np.flip(np.flip(mask_data, axis=1), axis=2)
  93. flipped_mask = np.flip(mask_data, axis=2)
  94. # Determine the directory to save the adjusted mask
  95. mask_dir = os.path.dirname(os.path.dirname(mask_file))
  96. adjusted_masks_dir = os.path.join(mask_dir, "DSI_studio", "RegisteredTractMasks_adjusted")
  97. # Create the directory if it doesn't exist
  98. if not os.path.exists(adjusted_masks_dir):
  99. os.makedirs(adjusted_masks_dir)
  100. # Define the new file name and save the flipped mask
  101. adjusted_mask_file = os.path.join(adjusted_masks_dir, os.path.basename(mask_file).replace(".nii.gz","_flipped.nii.gz"))
  102. nib.save(nib.Nifti1Image(flipped_mask, mask_nifti.affine), adjusted_mask_file)
  103. progress_bar.update(1)
  104. progress_bar.close()
  105. print("Flipping of RegisteredTractMasks and saving to RegisteredTractMasks_adjusted: DONE\n")
  106. # Save the missing matrix paths to a CSV file
  107. missing_matrix_csv_path = os.path.join(args.input, "missing_matrix_paths.csv")
  108. with open(missing_matrix_csv_path, mode='w', newline='') as file:
  109. writer = csv.writer(file)
  110. if not missing_matrix_paths:
  111. writer.writerow(["Registration of all masks/maps was executed. All folders contained an Affine transformation matrix"])
  112. else:
  113. for path in missing_matrix_paths:
  114. writer.writerow([path])
  115. print("Saved missing matrix paths to CSV: DONE\n")
  116. if __name__ == "__main__":
  117. main()