register_masks.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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("Flipping of RegisteredTractMasks and saving to RegisteredTractMasks_adjusted: DONE\n")
  49. progress_bar.close()
  50. print("Registered all masks to t2w space of individual mice: DONE\n")
  51. # Parsing for all SmoothMicoBet.nii.gz files in DTI folders after a given input path.
  52. DTIBetPath = os.path.join(args.input,"**","dwi*","*SmoothMicoBet.nii.gz")
  53. DTIBetFiles = glob.glob(DTIBetPath,recursive=True)
  54. total_iterations = len(DTIBetFiles) * len(FloatingMasksFiles)
  55. progress_bar = tqdm(total=total_iterations, desc='Registration Progress (to diffusion dwi) and adjusting for fa, ad, md maps', unit='files')
  56. for ff in DTIBetFiles:
  57. temp = os.path.dirname(os.path.dirname(ff))
  58. t2MasksPath = os.path.join(temp,"anat","RegisteredTractMasks","*nii.gz")
  59. FloatingMasksFiles = glob.glob(t2MasksPath)
  60. for mm in FloatingMasksFiles:
  61. MaskName = os.path.basename(mm).replace("anat","dwi")
  62. NewMaskName = MaskName
  63. NewMaskFolder = os.path.join(os.path.dirname(ff),"RegisteredTractMasks")
  64. NewMaskAddress = os.path.join(NewMaskFolder,NewMaskName)
  65. if not os.path.exists(NewMaskFolder):
  66. os.makedirs(NewMaskFolder)
  67. Affine_matrix_files = glob.glob(os.path.join(os.path.dirname(ff),"*MatrixAff.txt"))
  68. if not Affine_matrix_files:
  69. missing_matrix_paths.append(os.path.dirname(ff))
  70. continue
  71. Affine_matrix = Affine_matrix_files[0]
  72. command = f"reg_resample -ref {ff} -flo {mm} -res {NewMaskAddress} -trans {Affine_matrix} -inter 0"
  73. command_args = shlex.split(command)
  74. try:
  75. result = subprocess.run(command_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  76. print(f"Output:\n{result.stdout.decode()}")
  77. print(f"Errors:\n{result.stderr.decode()}")
  78. except Exception as e:
  79. print(f"An error occurred: {e}")
  80. progress_bar.update(1)
  81. progress_bar.close()
  82. print("Registered all masks to t2w space of individual mice: DONE\n")
  83. # Adjust by flipping for the fa0 and ad files
  84. # Locate all files in the "RegisteredTractMasks" folder
  85. registered_masks_path = os.path.join(args.input,"**","RegisteredTractMasks", "*.nii.gz")
  86. registered_masks_files = glob.glob(registered_masks_path, recursive=True)
  87. total_iterations = len(registered_masks_files)
  88. progress_bar = tqdm(total=total_iterations, desc='Flipping Masks', unit='files')
  89. for mask_file in registered_masks_files:
  90. # Load the mask file
  91. mask_nifti = nib.load(mask_file)
  92. mask_data = mask_nifti.get_fdata()
  93. # Flip the mask along the Y and Z axes
  94. #flipped_mask = np.flip(np.flip(mask_data, axis=1), axis=2)
  95. flipped_mask = np.flip(mask_data, axis=2)
  96. # Determine the directory to save the adjusted mask
  97. mask_dir = os.path.dirname(os.path.dirname(mask_file))
  98. adjusted_masks_dir = os.path.join(mask_dir, "DSI_studio", "RegisteredTractMasks_adjusted")
  99. # Create the directory if it doesn't exist
  100. if not os.path.exists(adjusted_masks_dir) and not "anat" in mask_file:
  101. os.makedirs(adjusted_masks_dir)
  102. # Define the new file name and save the flipped mask
  103. if not "anat" in mask_file:
  104. adjusted_mask_file = os.path.join(adjusted_masks_dir, os.path.basename(mask_file).replace(".nii.gz","_flipped.nii.gz"))
  105. nib.save(nib.Nifti1Image(flipped_mask, mask_nifti.affine), adjusted_mask_file)
  106. progress_bar.update(1)
  107. progress_bar.close()
  108. print("Flipping of RegisteredTractMasks and saving to RegisteredTractMasks_adjusted: DONE\n")
  109. # Save the missing matrix paths to a CSV file
  110. missing_matrix_csv_path = os.path.join(args.input, "missing_matrix_paths.csv")
  111. with open(missing_matrix_csv_path, mode='w', newline='') as file:
  112. writer = csv.writer(file)
  113. if not missing_matrix_paths:
  114. writer.writerow(["Registration of all masks/maps was executed. All folders contained an Affine transformation matrix"])
  115. else:
  116. for path in missing_matrix_paths:
  117. writer.writerow([path])
  118. print("Saved missing matrix paths to CSV: DONE\n")
  119. if __name__ == "__main__":
  120. main()