コード例 #1
0
    def _register(_moving, _parameters, _output_path, _use_mask=None):
        if isinstance(_parameters, str):
            _parameters = [_parameters]
        if _use_mask is None:
            _use_mask = target_mask is not None or moving_mask is not None

        _output_path = os.path.abspath(_output_path)
        os.makedirs(_output_path, exist_ok=True)

        elastix_path = _local_exe("elastix")
        cwd = _local_lib_dir()

        reg = Registration()
        if elastix_path:
            reg._cmd = elastix_path
        reg.inputs.fixed_image = os.path.abspath(target)
        reg.inputs.moving_image = os.path.abspath(_moving)
        reg.inputs.parameters = [os.path.abspath(p) for p in _parameters]
        reg.inputs.output_path = os.path.abspath(_output_path)
        reg.terminal_output = preferences.nipype_logging
        if num_threads:
            reg.inputs.num_threads = num_threads
        if _use_mask and target_mask is not None:
            reg.inputs.fixed_mask = os.path.abspath(target_mask)
        if _use_mask and moving_mask is not None:
            reg.inputs.target_mask = os.path.abspath(moving_mask)
        for k, v in kwargs.items():
            setattr(reg.inputs, k, v)

        return reg.run(cwd=cwd).outputs
コード例 #2
0
    def __intraregister__(self, volumes: List[MedicalVolume]):
        """
        Intraregister different subvolumes to ensure they are in the same space during computation

        :param volumes: a list of MedicalVolumes
        :return:
        """
        if (not volumes) or (type(volumes) is not list) or (len(volumes) != __EXPECTED_NUM_ECHO_TIMES__):
            raise TypeError('volumes must be of type List[MedicalVolume]')

        num_echos = len(volumes)

        print('')
        print('==' * 40)
        print('Intraregistering...')
        print('==' * 40)

        # temporarily save subvolumes as nifti file
        raw_volumes_base_path = io_utils.check_dir(os.path.join(self.temp_path, 'raw'))

        # Use first subvolume as a basis for registration - save in nifti format to use with elastix/transformix
        volume_files = []
        for echo_index in range(num_echos):
            filepath = os.path.join(raw_volumes_base_path, '%03d' % echo_index + '.nii.gz')
            volume_files.append(filepath)

            volumes[echo_index].save_volume(filepath, data_format=ImageDataFormat.nifti)

        target_echo_index = 0
        target_image_filepath = volume_files[target_echo_index]

        nr = NiftiReader()
        intraregistered_volumes = [deepcopy(volumes[target_echo_index])]
        for echo_index in range(1, num_echos):
            moving_image = volume_files[echo_index]

            reg = Registration()
            reg.inputs.fixed_image = target_image_filepath
            reg.inputs.moving_image = moving_image
            reg.inputs.output_path = io_utils.check_dir(os.path.join(self.temp_path,
                                                                     'intraregistered',
                                                                     '%03d' % echo_index))
            reg.inputs.parameters = [fc.ELASTIX_AFFINE_PARAMS_FILE]
            reg.terminal_output = fc.NIPYPE_LOGGING
            print('Registering %s --> %s' % (str(echo_index), str(target_echo_index)))
            tmp = reg.run()

            warped_file = tmp.outputs.warped_file
            intrareg_vol = nr.load(warped_file)

            # copy affine from original volume, because nifti changes loading accuracy
            intrareg_vol = MedicalVolume(volume=intrareg_vol.volume,
                                         affine=volumes[echo_index].affine,
                                         headers=deepcopy(volumes[echo_index].headers))

            intraregistered_volumes.append(intrareg_vol)

        self.raw_volumes = deepcopy(volumes)
        self.volumes = intraregistered_volumes
コード例 #3
0
ファイル: scans.py プロジェクト: EdgarRios111/DOSMA
    def __interregister_base_file__(
        self,
        base_image_info: tuple,
        target_path: str,
        temp_path: str,
        mask_path: str = None,
        parameter_files=(fc.ELASTIX_RIGID_PARAMS_FILE,
                         fc.ELASTIX_AFFINE_PARAMS_FILE)):
        """Interregister the base moving image to the target image

        :param base_image_info: tuple of filepath, echo index (eg. 'scans/000.nii.gz, 0)
        :param target_path: filepath to target scan - should be in nifti (.nii.gz) format
        :param temp_path: path to store temporary data
        :param mask_path: path to mask to use to use as focus points for registration, mask must be binary
                            recommend that this is the path to a dilated version of the mask for registration purposes
        :param parameter_files: list of filepaths to elastix parameter files to use for transformations
        :return: tuple of the path to the transformed moving image and a list of filepaths to elastix transformations
                    (e.g. '/result.nii.gz', ['/tranformation0.txt', '/transformation1.txt'])
        """
        base_image_path, base_time_id = base_image_info
        # Register base image to the target image
        print('Registering %s (base image)' % base_image_path)
        transformation_files = []

        use_mask_arr = [False, True]
        reg_output = None
        moving_image = base_image_path

        for i in range(len(parameter_files)):
            use_mask = use_mask_arr[i]
            pfile = parameter_files[i]

            reg = Registration()
            reg.inputs.fixed_image = target_path
            reg.inputs.moving_image = moving_image
            reg.inputs.output_path = io_utils.check_dir(
                os.path.join(temp_path, '%03d_param%i' % (base_time_id, i)))
            reg.inputs.parameters = pfile

            if use_mask and mask_path is not None:
                fixed_mask_filepath = self.__dilate_mask__(
                    mask_path, temp_path)
                reg.inputs.fixed_mask = fixed_mask_filepath

            reg.terminal_output = fc.NIPYPE_LOGGING

            reg_output = reg.run()
            reg_output = reg_output.outputs
            assert reg_output is not None

            # update moving image to output
            moving_image = reg_output.warped_file

            transformation_files.append(reg_output.transform[0])

        return reg_output.warped_file, transformation_files
コード例 #4
0
ファイル: scans.py プロジェクト: jeffreydominic/DOSMA
    def __interregister_base_file__(self, base_image_info: tuple, target_path: str, temp_path: str,
                                    mask_path: str = None,
                                    parameter_files=(fc.ELASTIX_RIGID_PARAMS_FILE, fc.ELASTIX_AFFINE_PARAMS_FILE)):
        """Interregister the base moving image to the target image.

        Args:
            base_image_info (tuple[str, int]): File path, echo index (eg. 'scans/000.nii.gz, 0).
            target_path (str): File path to target scan. Must be in nifti (.nii.gz) format.
            temp_path (str): Directory path to store temporary data.
            mask_path (str): Path to mask to use to use as focus points for registration. Mask must be binary. Recommend
                using dilated mask.
            parameter_files (list[str]): Transformix parameter files to use for transformations.

        Returns:
            tuple[str, list[str]): File path to the transformed moving image and a list of file paths to elastix
                transformations (e.g. '/result.nii.gz', ['/tranformation0.txt', '/transformation1.txt']).
        """
        base_image_path, base_time_id = base_image_info

        # Register base image to the target image.
        logging.info("Registering %s (base image)".format(base_image_path))
        transformation_files = []

        use_mask_arr = [False, True]
        reg_output = None
        moving_image = base_image_path

        for i in range(len(parameter_files)):
            use_mask = use_mask_arr[i]
            pfile = parameter_files[i]

            reg = Registration()
            reg.inputs.fixed_image = target_path
            reg.inputs.moving_image = moving_image
            reg.inputs.output_path = io_utils.mkdirs(os.path.join(temp_path,
                                                                     '{:03d}_param{}'.format(base_time_id, i)))
            reg.inputs.parameters = pfile

            if use_mask and mask_path is not None:
                fixed_mask_filepath = self.__dilate_mask__(mask_path, temp_path)
                reg.inputs.fixed_mask = fixed_mask_filepath

            reg.terminal_output = fc.NIPYPE_LOGGING

            reg_output = reg.run()
            reg_output = reg_output.outputs
            assert reg_output is not None

            # Update moving image to output.
            moving_image = reg_output.warped_file

            transformation_files.append(reg_output.transform[0])

        return reg_output.warped_file, transformation_files
コード例 #5
0
    def __intraregister__(self, volumes: List[MedicalVolume]):
        """Intraregister volumes.

        Sets `self.volumes` to intraregistered volumes.

        Args:
            volumes (list[MedicalVolume]): Volumes to register.

        Raises:
            TypeError: If `volumes` is not `list[MedicalVolume]`.
        """
        if ((not volumes) or (type(volumes) is not list)
                or (len(volumes) != __EXPECTED_NUM_ECHO_TIMES__)):
            raise TypeError("`volumes` must be of type List[MedicalVolume]")

        num_echos = len(volumes)

        logging.info("")
        logging.info("==" * 40)
        logging.info("Intraregistering...")
        logging.info("==" * 40)

        # temporarily save subvolumes as nifti file
        raw_volumes_base_path = io_utils.mkdirs(
            os.path.join(self.temp_path, "raw"))

        # Use first subvolume as a basis for registration
        # Save in nifti format to use with elastix/transformix
        volume_files = []
        for echo_index in range(num_echos):
            filepath = os.path.join(raw_volumes_base_path,
                                    "{:03d}.nii.gz".format(echo_index))
            volume_files.append(filepath)

            volumes[echo_index].save_volume(filepath,
                                            data_format=ImageDataFormat.nifti)

        target_echo_index = 0
        target_image_filepath = volume_files[target_echo_index]

        nr = NiftiReader()
        intraregistered_volumes = [deepcopy(volumes[target_echo_index])]
        for echo_index in range(1, num_echos):
            moving_image = volume_files[echo_index]

            reg = Registration()
            reg.inputs.fixed_image = target_image_filepath
            reg.inputs.moving_image = moving_image
            reg.inputs.output_path = io_utils.mkdirs(
                os.path.join(self.temp_path, "intraregistered",
                             "{:03d}".format(echo_index)))
            reg.inputs.parameters = [fc.ELASTIX_AFFINE_PARAMS_FILE]
            reg.terminal_output = preferences.nipype_logging
            logging.info("Registering {} -> {}".format(str(echo_index),
                                                       str(target_echo_index)))
            tmp = reg.run()

            warped_file = tmp.outputs.warped_file
            intrareg_vol = nr.load(warped_file)

            # copy affine from original volume, because nifti changes loading accuracy
            intrareg_vol = MedicalVolume(
                volume=intrareg_vol.volume,
                affine=volumes[echo_index].affine,
                headers=deepcopy(volumes[echo_index].headers()),
            )

            intraregistered_volumes.append(intrareg_vol)

        self.volumes = intraregistered_volumes
コード例 #6
0
    def __intraregister__(self, subvolumes):
        """Intraregister cubequant subvolumes to each other
        Patient could have moved between acquisition of different subvolumes, so different subvolumes of cubequant scan
            have to be registered with each other

        The first spin lock time has the highest SNR, so it is used as the target
        Subvolumes corresponding to the other spin lock times are registered to the target

        Affine registration is done using elastix

        :param subvolumes: dictionary of subvolumes mapping spin lock time index --> MedicalVolume
                                (e.g. {0 --> MedicalVolume A, 1 --> MedicalVolume B}
        :return: a dictionary of base, other files spin-lock index --> nifti filepath
        """

        if subvolumes is None:
            raise ValueError('subvolumes must be dict()')

        print('')
        print('==' * 40)
        print('Intraregistering...')
        print('==' * 40)

        # temporarily save subvolumes as nifti file
        ordered_spin_lock_time_indices = natsorted(list(subvolumes.keys()))
        raw_volumes_base_path = io_utils.check_dir(
            os.path.join(self.temp_path, 'raw'))

        # Use first spin lock time as a basis for registration
        spin_lock_nii_files = []
        for spin_lock_time_index in ordered_spin_lock_time_indices:
            filepath = os.path.join(raw_volumes_base_path,
                                    '%03d' % spin_lock_time_index + '.nii.gz')
            spin_lock_nii_files.append(filepath)

            subvolumes[spin_lock_time_index].save_volume(filepath)

        target_filepath = spin_lock_nii_files[0]

        intraregistered_files = []
        for i in range(1, len(spin_lock_nii_files)):
            spin_file = spin_lock_nii_files[i]
            spin_lock_time_index = ordered_spin_lock_time_indices[i]

            reg = Registration()
            reg.inputs.fixed_image = target_filepath
            reg.inputs.moving_image = spin_file
            reg.inputs.output_path = io_utils.check_dir(
                os.path.join(self.temp_path, 'intraregistered',
                             '%03d' % spin_lock_time_index))
            reg.inputs.parameters = [fc.ELASTIX_AFFINE_PARAMS_FILE]
            reg.terminal_output = fc.NIPYPE_LOGGING
            print('Registering %s --> %s' %
                  (str(spin_lock_time_index),
                   str(ordered_spin_lock_time_indices[0])))
            tmp = reg.run()

            warped_file = tmp.outputs.warped_file
            intraregistered_files.append((spin_lock_time_index, warped_file))

        return {
            'BASE':
            (ordered_spin_lock_time_indices[0], spin_lock_nii_files[0]),
            'FILES': intraregistered_files
        }
コード例 #7
0
ファイル: cube_quant.py プロジェクト: jeffreydominic/DOSMA
    def __intraregister__(self, subvolumes):
        """Intra-register volumes.

        Patient could have moved between acquisition of different volumes, so different volumes of CubeQuant scan
            have to be registered with each other.

        The first spin lock time has the highest SNR, so it is used as the target. Volumes corresponding to the other
            spin lock times are registered to the target.

        Affine registration is done using Elastix.

        Args:
            subvolumes (dict[int, MedicalVolume]): Dictionary of spin lock time index -> volume. (e.g.
                {0 --> MedicalVolume A, 1 --> MedicalVolume B}).

        Returns:
            dict[int, str]: Dictionary of base, other files spin-lock index -> output nifti file path.
        """

        if subvolumes is None:
            raise TypeError("subvolumes must be dict")

        logging.info("")
        logging.info("==" * 40)
        logging.info("Intraregistering...")
        logging.info("==" * 40)

        # temporarily save subvolumes as nifti file
        ordered_spin_lock_time_indices = natsorted(list(subvolumes.keys()))
        raw_volumes_base_path = io_utils.mkdirs(
            os.path.join(self.temp_path, "raw"))

        # Use first spin lock time as a basis for registration
        spin_lock_nii_files = []
        for spin_lock_time_index in ordered_spin_lock_time_indices:
            filepath = os.path.join(
                raw_volumes_base_path,
                "{:03d}.nii.gz".format(spin_lock_time_index))
            spin_lock_nii_files.append(filepath)

            subvolumes[spin_lock_time_index].save_volume(filepath)

        target_filepath = spin_lock_nii_files[0]

        intraregistered_files = []
        for i in range(1, len(spin_lock_nii_files)):
            spin_file = spin_lock_nii_files[i]
            spin_lock_time_index = ordered_spin_lock_time_indices[i]

            reg = Registration()
            reg.inputs.fixed_image = target_filepath
            reg.inputs.moving_image = spin_file
            reg.inputs.output_path = io_utils.mkdirs(
                os.path.join(self.temp_path, "intraregistered",
                             "{:03d}".format(spin_lock_time_index)))
            reg.inputs.parameters = [fc.ELASTIX_AFFINE_PARAMS_FILE]
            reg.terminal_output = fc.NIPYPE_LOGGING
            logging.info("Registering {} -> {}".format(
                str(spin_lock_time_index),
                str(ordered_spin_lock_time_indices[0])))
            tmp = reg.run()

            warped_file = tmp.outputs.warped_file
            intraregistered_files.append((spin_lock_time_index, warped_file))

        return {
            "BASE":
            (ordered_spin_lock_time_indices[0], spin_lock_nii_files[0]),
            "FILES": intraregistered_files
        }