Example #1
0
class MaskIntersection(AbstractParallelRoutine):
    def __init__(self, config, in_folder, out_img_path, file_list_txt):
        super().__init__(config, in_folder, file_list_txt)
        self._out_img_path = out_img_path
        self._ref_img = ScanWrapper(self._in_data_folder.get_first_path())

    def run(self):
        result_list = self.run_parallel()
        out_mask = self._get_intersect_mask(result_list)

        self._ref_img.save_scan_same_space(self._out_img_path, out_mask)

    def _run_single_scan(self, idx):
        in_img = ScanWrapper(self._in_data_folder.get_file_path(idx))
        return in_img.get_data()

    def _run_chunk(self, chunk_list):
        result_list = []
        inter_mask = np.ones(self._ref_img.get_shape())
        for idx in chunk_list:
            self._in_data_folder.print_idx(idx)
            mask = self._run_single_scan(idx)
            inter_mask = np.multiply(inter_mask, mask)

        result_list.append(inter_mask)
        return result_list

    def _get_intersect_mask(self, mask_list):
        inter_mask = np.ones(self._ref_img.get_shape())
        for mask in mask_list:
            inter_mask = np.multiply(inter_mask, mask)

        return inter_mask
Example #2
0
class JacobianAffineCorrection(AbstractParallelRoutine):
    def __init__(self, config, in_jac_folder, in_affine_mat_folder, out_folder,
                 ref_img, file_list_txt):
        super().__init__(config, in_jac_folder, file_list_txt)
        self._ref_img = ScanWrapper(ref_img)
        self._in_affine_mat_folder = DataFolder.get_data_folder_obj(
            config, in_affine_mat_folder, data_list_txt=file_list_txt)
        self._out_data_folder = DataFolder.get_data_folder_obj(
            config, out_folder, data_list_txt=file_list_txt)

    def _run_single_scan(self, idx):
        in_data_path = self._in_data_folder.get_file_path(idx)
        in_affine_mat_path = self._in_affine_mat_folder.get_file_path(
            idx).replace('.nii.gz', '.txt')
        out_file_path = self._out_data_folder.get_file_path(idx)

        in_image = ScanWrapper(in_data_path)
        affine_mat = self._get_affine_matrix(in_affine_mat_path)

        new_log_jacobian_det = in_image.get_data() + np.log(
            np.linalg.det(affine_mat))

        self._ref_img.save_scan_same_space(out_file_path, new_log_jacobian_det)

    def _get_affine_matrix(self, mat_path):
        return np.loadtxt(mat_path)
Example #3
0
class AverageValidRegion(AbstractParallelRoutine):
    def __init__(self,
                 config,
                 in_scan_folder,
                 in_region_mask_folder,
                 file_list_txt,
                 out_average_img,
                 ambient=-5000):
        super().__init__(config, in_scan_folder, file_list_txt)
        self._in_region_mask_folder = DataFolder.get_data_folder_obj(
            config, in_region_mask_folder, data_list_txt=file_list_txt)
        self._out_img_path = out_average_img
        self._ref_img = ScanWrapper(self._in_data_folder.get_first_path())
        self._ambient = ambient

    def run_get_average(self):
        result_list = self.run_parallel()

        im_shape = self._ref_img.get_shape()
        sum_image = np.zeros(im_shape)
        region_count = np.zeros(im_shape)

        for result in result_list:
            sum_image += result['sum_image']
            region_count += result['region_count']

        sum_image = np.divide(sum_image,
                              region_count,
                              out=sum_image,
                              where=region_count > 0.5)

        sum_image_ma = np.ma.masked_array(sum_image, mask=region_count == 0)

        self._ref_img.save_scan_same_space(self._out_img_path,
                                           sum_image_ma.filled(self._ambient))
        self._ref_img.save_scan_same_space(
            self._out_img_path + '_region_count.nii.gz', region_count)

    def _run_chunk(self, chunk_list):
        result_list = []
        im_shape = self._ref_img.get_shape()
        sum_image_union = np.zeros(im_shape)
        region_mask_count_image = np.zeros(im_shape)
        for idx in chunk_list:
            self._in_data_folder.print_idx(idx)
            img_obj = ScanWrapper(self._in_data_folder.get_file_path(idx))
            mask_obj = ScanWrapper(
                self._in_region_mask_folder.get_file_path(idx))
            sum_image_union += img_obj.get_data()
            region_mask_count_image += mask_obj.get_data()

        result = {
            'sum_image': sum_image_union,
            'region_count': region_mask_count_image
        }

        result_list.append(result)
        return result_list
Example #4
0
    def _run_single_scan(self, idx):
        in_img = ScanWrapper(self._in_data_folder.get_file_path(idx))
        out_mask_path = self._out_folder.get_file_path(idx)

        in_img_data = in_img.get_data()
        non_nan_mask = in_img_data == in_img_data

        logger.info(f'Save non-nan mask to {out_mask_path}')
        in_img.save_scan_same_space(out_mask_path, non_nan_mask.astype(int))
Example #5
0
def get_average_map(file_list, save_path):
    first_img = ScanWrapper(file_list[0])
    im_shape = first_img.get_shape()
    sum_map = np.zeros(im_shape, dtype=float)

    for idx_image in range(len(file_list)):
        img = ScanWrapper(file_list[idx_image])
        img_data = img.get_data()
        print(f'Adding {file_list[idx_image]} ({idx_image} / {len(file_list)})')
        print(f'Max intensity {np.max(img_data)}')
        sum_map += img_data

    average_map = sum_map / float(len(file_list))
    print(f'Average map max int {np.max(average_map)}')
    first_img.save_scan_same_space(save_path, average_map)
Example #6
0
class PreprocessAverageImputation(AbstractParallelRoutine):
    def __init__(self,
                 config,
                 in_folder,
                 out_folder,
                 average_img,
                 file_list_txt=None):
        super().__init__(config, in_folder, file_list_txt=file_list_txt)
        self._out_data_folder = DataFolder.get_data_folder_obj(
            config, out_folder, data_list_txt=file_list_txt)
        mkdir_p(out_folder)
        self._average_img = ScanWrapper(average_img)

    def _run_single_scan(self, idx):
        in_file_path = self._in_data_folder.get_file_path(idx)
        out_file_path = self._out_data_folder.get_file_path(idx)

        in_img = ScanWrapper(in_file_path).get_data()
        average_img = self._average_img.get_data()

        np.copyto(in_img, average_img, where=(in_img != in_img))
        np.copyto(in_img, 0, where=(in_img != in_img))
        self._average_img.save_scan_same_space(out_file_path, in_img)
Example #7
0
class AverageScans:
    def __init__(self,
                 config,
                 in_folder=None,
                 data_file_txt=None,
                 in_data_folder_obj=None):
        self._data_folder = None
        if in_data_folder_obj is None:
            self._data_folder = DataFolder(in_folder, data_file_txt)
        else:
            self._data_folder = in_data_folder_obj
        self._standard_ref = ScanWrapper(self._data_folder.get_first_path())
        self._num_processes = config['num_processes']

    def get_average_image_union(self, save_path):
        im_shape = self._get_std_shape()

        average_union = np.zeros(im_shape)
        average_union.fill(np.nan)
        non_null_mask_count_image = np.zeros(im_shape)

        chunk_list = self._data_folder.get_chunks_list(self._num_processes)

        pool = Pool(processes=self._num_processes)

        print('Average in union')
        print('Step.1 Summation')
        image_average_union_result_list = [
            pool.apply_async(self._sum_images_union, (file_idx_chunk, ))
            for file_idx_chunk in chunk_list
        ]
        for thread_idx in range(len(image_average_union_result_list)):
            result = image_average_union_result_list[thread_idx]
            result.wait()
            print(
                f'Thread with idx {thread_idx} / {len(image_average_union_result_list)} is completed'
            )
            print('Adding to averaged_image...')
            averaged_image_chunk = result.get()
            average_union = self._add_image_union(average_union,
                                                  averaged_image_chunk)
            print('Done.')

        print('Step.2 Non-nan counter')
        non_null_mask_count_result = [
            pool.apply_async(self._sum_non_null_count, (file_idx_chunk, ))
            for file_idx_chunk in chunk_list
        ]
        for thread_idx in range(len(non_null_mask_count_result)):
            result = non_null_mask_count_result[thread_idx]
            result.wait()
            print(
                f'Thread with idx {thread_idx} / {len(non_null_mask_count_result)} is completed'
            )
            print('Adding to averaged_image...')
            averaged_image_chunk = result.get()
            non_null_mask_count_image = np.add(non_null_mask_count_image,
                                               averaged_image_chunk)
            print('Done.')

        average_union = np.divide(average_union,
                                  non_null_mask_count_image,
                                  out=average_union,
                                  where=non_null_mask_count_image > 0)

        self._standard_ref.save_scan_same_space(save_path, average_union)
        print('Done.')

    def _sum_images_union(self, chunk_list):
        print('Sum images, union non-null region. Loading images...')
        im_shape = self._get_std_shape()
        sum_image = np.zeros(im_shape)
        sum_image.fill(np.nan)

        for id_file in chunk_list:
            file_path = self._data_folder.get_file_path(id_file)
            self._data_folder.print_idx(id_file)

            im = nib.load(file_path)
            im_data = im.get_data()
            sum_image = self._add_image_union(sum_image, im_data)

        return sum_image

    def _sum_non_null_count(self, chunk_list):
        print('Count non-null per voxel. Loading images...')
        im_shape = self._get_std_shape()
        sum_image = np.zeros(im_shape)

        for id_file in chunk_list:
            file_path = self._data_folder.get_file_path(id_file)
            self._data_folder.print_idx(id_file)
            im = nib.load(file_path)
            im_data = im.get_data()

            sum_image = np.add(sum_image,
                               1,
                               out=sum_image,
                               where=np.logical_not(np.isnan(im_data)))

        return sum_image

    def _get_std_shape(self):
        return self._standard_ref.get_data().shape

    @staticmethod
    def _add_image_inter(image1, image2):
        return np.add(image1,
                      image2,
                      out=np.full_like(image1, np.nan),
                      where=np.logical_not(
                          np.logical_or(np.isnan(image1), np.isnan(image2))))

    @staticmethod
    def _add_image_union(image1, image2):
        add_image = np.full_like(image1, np.nan)
        add_image[np.logical_not(
            np.logical_and(np.isnan(image1), np.isnan(image2)))] = 0

        add_image = np.add(add_image,
                           image1,
                           out=add_image,
                           where=np.logical_not(np.isnan(image1)))
        add_image = np.add(add_image,
                           image2,
                           out=add_image,
                           where=np.logical_not(np.isnan(image2)))

        return add_image

    @staticmethod
    def sum_non_null_count(file_list, in_folder):
        print('Count non-null per voxel. Loading images...')
        im_temp = nib.load(os.path.join(in_folder, file_list[0]))
        im_temp_data = im_temp.get_data()

        sum_image = np.zeros_like(im_temp_data)

        for id_file in range(len(file_list)):
            file_name = file_list[id_file]
            print('%s (%d/%d)' % (file_name, id_file, len(file_list)))
            file_path = os.path.join(in_folder, file_name)
            im = nib.load(file_path)
            im_data = im.get_data()

            sum_image = np.add(sum_image,
                               1,
                               out=sum_image,
                               where=np.logical_not(np.isnan(im_data)))

        return sum_image