Skip to content

Commit

Permalink
Updated project files
Browse files Browse the repository at this point in the history
  • Loading branch information
Arman committed Sep 25, 2024
1 parent 0ea21ae commit 9477179
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 10 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,40 @@ mv fixed_image.nii.gz moving_image.nii.gz incoming
apptainer exec docker://fnndsc/pl-images-register:latest images_register [--args] incoming outgoing
```

If there is only one moving image, it will be registered onto the fixed image.
If there are multiple moving images, each one will be registered to the fixed image separately.

For multiple moving images, all of them should be placed in a folder, and the folder should be passed to the
parser under moving_images_folder.

Example 1:

Inputs:
```shell
input_dir/fixed_image.nii.gz
input_dir/moving_image.nii.gz
```
Outputs:
```shell
output_dir/moving_image_registered.nii.gz
output_dir/moving_image_transform.mat
```
Example 2:

Inputs:
```shell
input_dir/fixed_image.nii.gz
input_dir/moving_images_folder/moving_image1.nii.gz, moving_image2.nii.gz, moving_image3.nii.gz, etc.
```
Outputs:
```shell
output_dir/moving_images_folder/moving_image1_registered.nii.gz, moving_image2_registered.nii.gz,
moving_image3.nii.gz, etc.
output_dir/moving_images_folder/moving_image1_transform.mat, moving_image2_transform.mat,
moving_image3_transform.mat, etc.
```
Please not that all images (fixed, moving, registered) must be in nii.gz format.

## Development

The registration algorithms are found in images_register.py module.
Expand Down
68 changes: 58 additions & 10 deletions images_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# --------------------------------------------- ENVIRONMENT SETUP -----------------------------------------------------
# Project imports:
from registration_tools import rigid_registration
from os_tools import sub_niftis

# System imports:
from os.path import join
Expand Down Expand Up @@ -36,24 +37,59 @@
'the transformation matrix. The fixed, moving, and registered moving images '
'are all in NIfTI format.',
formatter_class=ArgumentDefaultsHelpFormatter)

# parser.add_argument('-V', '--version', action='version',
# version=f'%(prog)s {__version__}')

"""
If there is only one moving image, it will be registered onto the fixed image.
If there are multiple moving images, each one will be registered to the fixed image separately.
For multiple moving images, all of them should be placed in a folder, and the folder should be passed to the
parser under moving_images_folder.
Example 1:
Inputs:
input_dir/fixed_image.nii.gz
input_dir/moving_image.nii.gz
Outputs:
output_dir/moving_image_registered.nii.gz
output_dir/moving_image_transform.mat
Example 2:
Inputs:
input_dir/fixed_image.nii.gz
input_dir/moving_images_folder/moving_image1.nii.gz, moving_image2.nii.gz, moving_image3.nii.gz, etc.
Outputs:
output_dir/moving_images_folder/moving_image1_registered.nii.gz, moving_image2_registered.nii.gz,
moving_image3.nii.gz, etc.
output_dir/moving_images_folder/moving_image1_transform.mat, moving_image2_transform.mat,
moving_image3_transform.mat, etc.
Please not that all images (fixed, moving, registered) must be in nii.gz format.
"""

parser.add_argument('--fixed_image', type=str, default='fixed_image.nii.gz',
help='relative path to the fixed image in relation to input folder')
parser.add_argument('--moving_image', type=str, default='moving_image.nii.gz',
help='relative path to the moving image in relation to input folder')
parser.add_argument('--registered_image', type=str, default='registered_image.nii.gz',
help='relative path to the registered image in relation to output folder')
parser.add_argument('--transform_matrix', type=str, default='transform.mat',
help='relative path to the transformation matrix in relation to output folder')
help='relative path to the moving image in relation to input folder.'
'The moving image must be in .nii.gz format.')
parser.add_argument('--moving_images_folder', type=str, default='None',
help='relative path to the folder containing multiple moving images.'
'Every image in this folder will be registered to the fixed image.'
'All moving images must be in .nii.gz format.')

# ------------------------------------------- ChRIS PLUGIN WRAPPER ----------------------------------------------------

# The main function of this *ChRIS* plugin is denoted by this ``@chris_plugin`` "decorator."
# Some metadata about the plugin is specified here. There is more metadata specified in setup.py.
#
# documentation: https://fnndsc.github.io/chris_plugin/chris_plugin.html#chris_plugin

# ------------------------------------------- ChRIS PLUGIN WRAPPER ----------------------------------------------------
@chris_plugin(
parser=parser,
title='Images registration',
Expand All @@ -77,11 +113,23 @@ def main(options: Namespace, inputdir: Path, outputdir: Path):
print(DISPLAY_TITLE)

fixed_image_path = join(inputdir, options.fixed_image)
moving_image_path = join(inputdir, options.moving_image)
registered_image_path = join(outputdir, options.registered_image)
transform_matrix_path = join(outputdir, options.transform_matrix)

rigid_registration(fixed_image_path, moving_image_path, registered_image_path, transform_matrix_path)
if options.moving_images_folder == 'None':
moving_image_path = join(inputdir, options.moving_image)
registered_image_path = join(outputdir, options.moving_image.replace('.nii.gz', '_registered.nii.gz'))
transform_matrix_path = join(outputdir, options.moving_image.replace('.nii.gz', '_transform.mat'))

rigid_registration(fixed_image_path, moving_image_path, registered_image_path, transform_matrix_path)

else:
moving_images_list = sub_niftis(join(inputdir, options.moving_images_folder), complete_path=False)
for i, moving_image in enumerate(moving_images_list):
moving_image_path = join(inputdir, options.moving_images_folder, moving_image)
registered_image_path = join(outputdir, options.moving_images_folder,
options.moving_image.replace('.nii.gz', '_registered.nii.gz'))
transform_matrix_path = join(outputdir, options.moving_images_folder,
options.moving_image.replace('.nii.gz', '_transform.mat'))
rigid_registration(fixed_image_path, moving_image_path, registered_image_path, transform_matrix_path)

# ------------------------------------------------ EXECUTE MAIN -------------------------------------------------------

Expand Down
65 changes: 65 additions & 0 deletions os_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""
Developed by Arman Avesta, MD, PhD
FNNDSC | Boston Children's Hospital | Harvard Medical School
This file contains functions to help with file & folder organization, parallel processing, and other operating system
functionalities.
"""

# ----------------------------------------------- ENVIRONMENT SETUP ---------------------------------------------------
# Project imports:

# System imports:
import os
from os.path import join, dirname
from typing import List

# ---------------------------------------------- HELPER FUNCTIONS -----------------------------------------------------

def subdirs(root: str, complete_path: bool = False, prefix: str = None, suffix: str = None, sort: bool = True) \
-> List[str]:
if complete_path:
func = os.path.join
else:
func = lambda x, y: y
res = [func(root, subdir) for subdir in os.listdir(root) if os.path.isdir(join(root, subdir))
and (prefix is None or subdir.startswith(prefix))
and (suffix is None or subdir.endswith(suffix))]
if sort:
res.sort()
return res


def subfiles(root: str, complete_path: bool = True, prefix: str = None, suffix: str = None, sort: bool = True) \
-> List[str]:
if complete_path:
func = os.path.join
else:
func = lambda x, y: y
res = [func(root, subdir) for subdir in os.listdir(root) if os.path.isfile(join(root, subdir))
and (prefix is None or subdir.startswith(prefix))
and (suffix is None or subdir.endswith(suffix))]
if sort:
res.sort()
return res


def sub_niftis(root: str, complete_path: bool = True, sort: bool = True) -> List[str]:
return subfiles(root, complete_path=complete_path, sort=sort, suffix='.nii.gz')



def split_path(path: str) -> List[str]:
"""
splits at each separator. This is different from os.path.split which only splits at last separator
"""
return path.split(os.sep)


# -------------------------------------------------- CODE TESTING -----------------------------------------------------

if __name__ == '__main__':

path = '/Users/arman/projects/pl-images-register/data/nifti'
niftis_list = sub_niftis(path, complete_path=False)
print(niftis_list)

0 comments on commit 9477179

Please sign in to comment.