Exemplo n.º 1
0
    def auto_find_minimisation_sqsum(self, slices: List[int], recon_params: ReconstructionParameters,
                                     initial_cor: Union[float, List[float]], progress: Progress) -> List[float]:
        """

        :param slices: Slice indices to be reconstructed
        :param recon_params: Reconstruction parameters
        :param initial_cor: Initial COR for the slices. Will be used as the start for the minimisation.
                            If a float is passed it will be used for all slices.
                            If a list is passed, the COR will be retrieved for each slice.
        :param progress: Progress reporter
        """

        # Ensure we have some sample data
        if self.images is None:
            return [0.0]

        if isinstance(initial_cor, list):
            assert len(slices) == len(initial_cor), "A COR for each slice index being reconstructed must be provided"
        else:
            # why be efficient when you can be lazy?
            initial_cor = [initial_cor] * len(slices)

        reconstructor = get_reconstructor_for(recon_params.algorithm)
        progress = Progress.ensure_instance(progress, num_steps=len(slices))
        progress.update(0, msg=f"Calculating COR for slice {slices[0]}")
        cors = []
        for idx, slice in enumerate(slices):
            cor = reconstructor.find_cor(self.images, slice, initial_cor[idx], recon_params)
            cors.append(cor)
            progress.update(msg=f"Calculating COR for slice {slice}")
        return cors
Exemplo n.º 2
0
    def test_add_callback_incorrect_type(self):
        p = Progress(5)

        not_a_progress_handler = "I'm a string!"

        with self.assertRaises(ValueError):
            p.add_progress_handler(not_a_progress_handler)
Exemplo n.º 3
0
def _execute_seq(data, angle: float, progress: Progress):
    progress = Progress.ensure_instance(progress, num_steps=data.shape[0], task_name='Rotate Stack')

    with progress:
        img_count = data.shape[0]
        progress.add_estimated_steps(img_count)
        for idx in range(0, img_count):
            data[idx] = _rotate_image(data[idx], angle)
            progress.update(1, f"Rotating by {angle}")

    return data
Exemplo n.º 4
0
def start_async_task_view(parent: 'Qt.QMainWindow', task: Callable, on_complete: Callable, kwargs=None):
    atd = AsyncTaskDialogView(parent, auto_close=True)
    if not kwargs:
        kwargs = {'progress': Progress()}
    else:
        kwargs['progress'] = Progress()
    kwargs['progress'].add_progress_handler(atd.presenter)

    atd.presenter.set_task(task)
    atd.presenter.set_on_complete(on_complete)
    atd.presenter.set_parameters(**kwargs)
    atd.presenter.do_start_processing()
Exemplo n.º 5
0
def create_factors(data: np.ndarray, roi=None, cores=None, chunksize=None, progress=None):
    """
    Calculate the scale factors as the mean of the ROI
    :param data: The data stack from which the scale factors will be calculated
    :param roi: Region of interest for which the scale factors will be calculated
    :param cores: Number of cores that will perform the calculation
    :param chunksize: How many chunks of work each core will receive
    :return: The scale factor for each image.
    """

    progress = Progress.ensure_instance(progress, num_steps=data.shape[0])
    with progress:
        img_num = data.shape[0]
        # make sure to clean up if for some reason the scale factor array still exists
        with pu.temp_shared_array((img_num, 1, 1)) as scale_factors:
            # turn into a 1D array, from the 3D that is returned
            scale_factors = scale_factors.reshape(img_num)

            # calculate the scale factor from original image
            calc_sums_partial = ptsm.create_partial(_calc_avg,
                                                    fwd_function=ptsm.return_to_second,
                                                    roi_left=roi[0] if roi else 0,
                                                    roi_top=roi[1] if roi else 0,
                                                    roi_right=roi[2] if roi else data[0].shape[1] - 1,
                                                    roi_bottom=roi[3] if roi else data[0].shape[0] - 1)

            data, scale_factors = ptsm.execute(data, scale_factors, calc_sums_partial, cores, chunksize)

        return scale_factors
Exemplo n.º 6
0
    def filter_func(data, threshold=None, progress=None):
        """
        Cut off values above threshold relative to the max pixels.

        :param data: Input data as a 3D numpy.ndarray
        :param threshold: The threshold related to the minimum pixel value that
                          will be clipped
        :return: The processed 3D numpy.ndarray
        """
        progress = Progress.ensure_instance(progress, task_name='Cut Off')

        if threshold and threshold > 0.0:
            with progress:
                sample = data.data
                dmin = np.amin(sample)
                dmax = np.amax(sample)

                progress.update(
                    msg=f"Applying cut-off with level: {threshold}, min value "
                    f"{dmin}, max value {dmax}")

                rel_cut_off = dmin + threshold * (dmax - dmin)

                np.minimum(sample, rel_cut_off, out=sample)

        return data
Exemplo n.º 7
0
    def filter_func(data,
                    diff=None,
                    radius=_default_radius,
                    mode=_default_mode,
                    axis=0,
                    type=_default_dim,
                    cores=None,
                    progress=None):
        """
        Requires tomopy to be available.

        :param data: Input data as a 3D numpy.ndarray
        :param diff: Pixel value difference above which to crop bright pixels
        :param radius: Size of the median filter to apply
        :param mode: Spot brightness to remove.
                     Either 'bright' or 'dark'.
        :param cores: The number of cores that will be used to process the data.

        :return: The processed 3D numpy.ndarray
        """
        progress = Progress.ensure_instance(progress,
                                            task_name='Outliers',
                                            num_steps=3)
        if not utility.multiprocessing_necessary(data.data.shape, cores):
            cores = 1

        if diff and radius and diff > 0 and radius > 0:
            with progress:
                progress.update(
                    msg="Applying outliers with threshold: {0} and "
                    "radius {1}".format(diff, radius))

                sample = data.data
                # By default tomopy only clears bright outliers.
                # As a workaround inverting the image makes the dark outliers the brightest
                if mode == OUTLIERS_DARK:
                    np.negative(sample, out=sample)

                tomopy = importer.do_importing('tomopy')
                if type == "2D":
                    tomopy.misc.corr.remove_outlier(sample,
                                                    diff,
                                                    radius,
                                                    axis,
                                                    ncore=cores,
                                                    out=sample)
                else:
                    tomopy.misc.corr.remove_outlier1d(sample,
                                                      diff,
                                                      radius,
                                                      axis,
                                                      ncore=cores,
                                                      out=sample)
                progress.update()

                # reverse the inversion
                if mode == OUTLIERS_DARK:
                    np.negative(sample, out=sample)

        return data
Exemplo n.º 8
0
def _execute(data,
             size,
             mode,
             order,
             cores=None,
             chunksize=None,
             progress=None):
    log = getLogger(__name__)
    progress = Progress.ensure_instance(progress, task_name='Gaussian filter')

    # Parallel CPU version of the Gaussian filter
    # create the partial function to forward the parameters
    f = psm.create_partial(scipy_ndimage.gaussian_filter,
                           fwd_func=psm.return_fwd_func,
                           sigma=size,
                           mode=mode,
                           order=order)

    log.info("Starting PARALLEL gaussian filter, with pixel data type: {0}, "
             "filter size/width: {1}.".format(data.dtype, size))

    progress.update()
    data = psm.execute(data,
                       f,
                       cores,
                       chunksize,
                       progress,
                       msg="Gaussian filter")

    progress.mark_complete()
    log.info("Finished  gaussian filter, with pixel data type: {0}, "
             "filter size/width: {1}.".format(data.dtype, size))
Exemplo n.º 9
0
    def filter_func(data: Images,
                    circular_mask_ratio=0.95,
                    circular_mask_value=0.,
                    cores=None,
                    progress=None) -> Images:
        """
        :param data: Input data as a 3D numpy.ndarray
        :param circular_mask_ratio: The ratio to the full image.
                                    The ratio must be 0 < ratio < 1
        :param circular_mask_value: The value that all pixels in the mask
                                    will be set to.

        :return: The processed 3D numpy.ndarray
        """
        progress = Progress.ensure_instance(progress,
                                            num_steps=1,
                                            task_name='Circular Mask')

        if circular_mask_ratio and 0 < circular_mask_ratio < 1:
            tomopy = importer.do_importing('tomopy')

            with progress:
                progress.update(msg="Applying circular mask")

                # for some reason this doesn't like the ncore param, even though
                # it's in the official tomopy docs
                tomopy.circ_mask(arr=data.data,
                                 axis=0,
                                 ratio=circular_mask_ratio,
                                 val=circular_mask_value,
                                 ncore=cores)

        return data
Exemplo n.º 10
0
    def filter_func(images: Images, minus_log=True, progress=None):
        """
        This filter should be used on transmission images (background corrected
        images).

        It converts the images from transmission to attenuation.

        :param images: Sample data which is to be processed. Expected in radiograms
        :param minus_log: Specify whether to calculate minus log or just return.

        :return: Inverted image
        """
        progress = Progress.ensure_instance(progress, task_name='Minus Log')

        if minus_log:
            # import early to check if tomopy is available
            tomopy = importer.do_importing('tomopy')

            with progress:
                progress.update(msg="Calculating -log on the sample data")
                sample = images.data
                # this check prevents division by 0 errors from the minus_log
                sample[sample == 0] = 1e-6

                # the operation is done in place
                tomopy.prep.normalize.minus_log(sample, out=sample)

        return images
Exemplo n.º 11
0
    def full(images: Images,
             cors: List[ScalarCoR],
             recon_params: ReconstructionParameters,
             progress: Optional[Progress] = None) -> Images:
        progress = Progress.ensure_instance(progress, num_steps=images.height)
        output_shape = (images.num_sinograms, images.width, images.width)
        output_images: Images = Images.create_empty_images(
            output_shape, images.dtype, images.metadata)
        output_images.record_operation('AstraRecon.full', 'Reconstruction',
                                       **recon_params.to_dict())

        # FIXME multiple GPU support - just starting up a Pool doesn't seem to work
        # the GPUs can't initialise the memory properly. Not sure why
        # num_gpus = AstraRecon._count_gpus()
        # LOG.info(f"Running with {num_gpus} GPUs")
        # partial = ptsm.create_partial(AstraRecon.single, ptsm.fwd_gpu_recon,
        #                               num_gpus=num_gpus, cors=cors,
        #                               proj_angles=proj_angles, recon_params=recon_params)
        # ptsm.execute(images.sinograms, output_images.data, partial, num_gpus, progress=progress)

        proj_angles = images.projection_angles()
        for i in range(images.height):
            output_images.data[i] = AstraRecon.single_sino(
                images.sino(i), cors[i], proj_angles, recon_params)
            progress.update(1, "Reconstructed slice")

        return output_images
Exemplo n.º 12
0
    def filter_func(images: Images, air_region: SensibleROI = None, cores=None, chunksize=None, progress=None):
        """
        Normalise by beam intensity.

        This does NOT do any checks if the Air Region is out of bounds!
        If the Air Region is out of bounds, the crop will fail at runtime.
        If the Air Region is in bounds, but has overlapping coordinates
        the crop give back a 0 shape of the coordinates that were wrong.

        :param images: Sample data which is to be processed. Expected in radiograms

        :param air_region: The order is - Left Top Right Bottom. The air region
                           from which sums will be calculated and all images will
                           be normalised.

        :param cores: The number of cores that will be used to process the data.

        :param chunksize: The number of chunks that each worker will receive.
        :param progress: Reference to a progress bar object

        :returns: Filtered data (stack of images)
        """
        h.check_data_stack(images)

        # just get data reference
        if air_region:
            progress = Progress.ensure_instance(progress, task_name='ROI Normalisation')
            _execute(images.data, air_region, cores, chunksize, progress)
        h.check_data_stack(images)
        return images
Exemplo n.º 13
0
    def filter_func(images, wf=None, ti=None, sf=None, cores=None, chunksize=None, progress=None):
        """
        Execute stripe removal operations.

        Multiple operations can be executed, if they are specified on the command
        line.

        The order for that execution will always be: wavelett-fourier, titarenko,
        smoothing-filter.

        :param images: Sample data which is to be processed. Expected in radiograms

        :param wf: Specify parameters for the wavelett-fourier filter.
                   Acceptable keywords are:

                        level (default None, type int, optional parameter)
                                Number of discrete wavelet transform levels.

                        wname (default 'db5', type str, optional parameter)
                                Type of the wavelet filter. 'haar', 'db5', 'sym5'.

                        sigma (default 2, type float, optional parameter)
                                Damping parameter in Fourier space.

                        pad (default True, type bool, optional parameter)
                                If True, extend the size of the sinogram by
                                padding with zeros.

        :param ti: Specify parameters for the titarenko filter.
                   Acceptable keywords are:

                        nblock (default:0, int, optional) Number of blocks.

                        alpha (default: 1.5, int, optional) Damping factor.

        :param sf: Specify parameters for the smoothing-filter.
                   Acceptable keywords are:

                        size (default: 5, int, optional)
                            Size of the smoothing filter.

        :return: Processed data
        """
        progress = Progress.ensure_instance(progress, task_name='Stripe Removal')

        # get the first one, the rest will be processed
        msg = "Starting removal of stripes/ring artifacts using method '{0}'..."

        with progress:
            if wf:
                progress.update(msg=msg.format('Fourier-wavelet'))
                func = partial(_wf, images.data, wf, cores, chunksize)
            elif sf:
                progress.update(msg=msg.format('Smoothing-Filter'))
                func = partial(_sf, images.data, sf, cores, chunksize)

            images.data = func()

        return images
Exemplo n.º 14
0
def _execute(data: np.ndarray, angle: float, cores: int, chunksize: int, progress: Progress):
    progress = Progress.ensure_instance(progress, task_name='Rotate Stack')

    with progress:
        f = ps.create_partial(_rotate_image_inplace, ps.inplace1, angle=angle)
        ps.shared_list = [data]
        ps.execute(f, data.shape[0], progress, msg=f"Rotating by {angle} degrees", cores=cores)

    return data
Exemplo n.º 15
0
def start_async_task_view(parent: QMainWindow,
                          task: Callable,
                          on_complete: Callable,
                          kwargs: Optional[Dict] = None,
                          tracker: Optional[Set[Any]] = None):
    atd = AsyncTaskDialogView(parent, auto_close=True)
    if not kwargs:
        kwargs = {'progress': Progress()}
    else:
        kwargs['progress'] = Progress()
    kwargs['progress'].add_progress_handler(atd.presenter)

    atd.presenter.set_task(task)
    atd.presenter.set_on_complete(on_complete)
    atd.presenter.set_parameters(**kwargs)
    if tracker is not None:
        atd.presenter.set_tracker(tracker)
    atd.presenter.do_start_processing()
Exemplo n.º 16
0
    def filter_func(data: Images,
                    flat_before: Images = None,
                    flat_after: Images = None,
                    dark_before: Images = None,
                    dark_after: Images = None,
                    selected_flat_fielding: str = None,
                    cores=None,
                    chunksize=None,
                    progress=None) -> Images:
        """Do background correction with flat and dark images.

        :param data: Sample data which is to be processed. Expected in radiograms
        :param flat_before: Flat (open beam) image to use in normalization, for before the sample is imaged
        :param flat_after: Flat (open beam) image to use in normalization, for after the sample is imaged
        :param dark_before: Dark image to use in normalization, for before the sample is imaged
        :param dark_after: Dark image to use in normalization, for before the sample is imaged
        :param selected_flat_fielding: Select which of the flat fielding methods to use, just Before stacks, just After
                                       stacks or combined.
        :param cores: The number of cores that will be used to process the data.
        :param chunksize: The number of chunks that each worker will receive.
        :return: Filtered data (stack of images)
        """
        h.check_data_stack(data)

        if selected_flat_fielding is not None:
            if selected_flat_fielding == "Both, concatenated" and flat_after is not None and flat_before is not None \
                    and dark_after is not None and dark_before is not None:
                flat_avg = (flat_before.data.mean(axis=0) + flat_after.data.mean(axis=0)) / 2.0
                dark_avg = (dark_before.data.mean(axis=0) + dark_after.data.mean(axis=0)) / 2.0
            elif selected_flat_fielding == "Only Before" and flat_before is not None and dark_before is not None:
                flat_avg = flat_before.data.mean(axis=0)
                dark_avg = dark_before.data.mean(axis=0)
            elif selected_flat_fielding == "Only After" and flat_after is not None and dark_after is not None:
                flat_avg = flat_after.data.mean(axis=0)
                dark_avg = dark_after.data.mean(axis=0)
            else:
                flat_avg = None
                dark_avg = None

            if flat_avg is not None and dark_avg is not None:
                if 2 != flat_avg.ndim or 2 != dark_avg.ndim:
                    raise ValueError(
                        f"Incorrect shape of the flat image ({flat_avg.shape}) or dark image ({dark_avg.shape}) \
                        which should match the shape of the sample images ({data.data.shape})")

                if not data.data.shape[1:] == flat_avg.shape == dark_avg.shape:
                    raise ValueError(f"Not all images are the expected shape: {data.data.shape[1:]}, instead "
                                     f"flat had shape: {flat_avg.shape}, and dark had shape: {dark_avg.shape}")

                progress = Progress.ensure_instance(progress,
                                                    num_steps=data.data.shape[0],
                                                    task_name='Background Correction')
                _execute(data.data, flat_avg, dark_avg, cores, chunksize, progress)

        h.check_data_stack(data)
        return data
Exemplo n.º 17
0
    def test_calculate_mean_time(self):
        progress_history = []

        progress_history.append(ProgressHistory(100, 0, ""))
        self.assertEqual(Progress.calculate_mean_time(progress_history), 0)

        # first step 5 seconds
        progress_history.append(ProgressHistory(105, 1, ""))
        self.assertEqual(Progress.calculate_mean_time(progress_history), 5)

        # second step 10 seconds
        progress_history.append(ProgressHistory(115, 2, ""))
        self.assertEqual(Progress.calculate_mean_time(progress_history), 7.5)

        for i in range(1, 50):
            # add many 2 second steps
            progress_history.append(
                ProgressHistory(115 + (i * 2), 2 + (i * 2), ""))
        self.assertEqual(Progress.calculate_mean_time(progress_history), 2)
Exemplo n.º 18
0
    def filter_func(data,
                    clip_min=None,
                    clip_max=None,
                    clip_min_new_value=None,
                    clip_max_new_value=None,
                    progress=None) -> Images:
        """Clip values below the min and above the max pixels.

        :param data: Input data as a 3D numpy.ndarray.
        :param clip_min: The minimum value to be clipped from the data.
                         If None is provided then no lower threshold is used.
        :param clip_max: The maximum value to be clipped from the data.
                         If None is provided then no upper threshold is used.

        :param clip_min_new_value: The value to use when replacing values less than
                                   clip_min.
                                   If None is provided then the value of clip_min
                                   is used.

        :param clip_max_new_value: The value to use when replacing values greater
                                   than clip_max.
                                   If None is provided then the value of clip_max
                                   is used.

        :return: The processed 3D numpy.ndarray.
        """
        progress = Progress.ensure_instance(progress,
                                            num_steps=2,
                                            task_name='Clipping Values.')

        # we're using is not None because if the value specified is 0.0 that
        # evaluates to false
        if clip_min is not None or clip_max is not None:
            with progress:
                sample = data.data
                progress.update(msg="Determining clip min and clip max")
                clip_min = clip_min if clip_min is not None else sample.min()
                clip_max = clip_max if clip_max is not None else sample.max()

                clip_min_new_value = clip_min_new_value if clip_min_new_value is not None else clip_min

                clip_max_new_value = clip_max_new_value if clip_max_new_value is not None else clip_max

                progress.update(
                    msg=
                    f"Clipping data with values min {clip_min} and max {clip_max}"
                )

                # this is the fastest way to clip the values, np.clip does not do
                # the clipping in place and ends up copying the data
                sample[sample < clip_min] = clip_min_new_value
                sample[sample > clip_max] = clip_max_new_value

        return data
Exemplo n.º 19
0
    def filter_func(images: Images,
                    run_ring_removal=False,
                    center_x=None,
                    center_y=None,
                    thresh=300.0,
                    thresh_max=300.0,
                    thresh_min=-100.0,
                    theta_min=30,
                    rwidth=30,
                    cores=None,
                    chunksize=None,
                    progress=None):
        """
        Removal of ring artifacts in reconstructed volume.

        :param images: Sample data which is to be processed. Expected in radiograms
        :param run_ring_removal: Uses Wavelet-Fourier based ring removal
        :param center_x: (float, optional) abscissa location of center of rotation
        :param center_y: (float, optional) ordinate location of center of rotation
        :param thresh: (float, optional)
                       maximum value of an offset due to a ring artifact
        :param thresh_max: (float, optional)
                       max value for portion of image to filter
        :param thresh_min: (float, optional)
                       min value for portion of image to filer
        :param theta_min: (int, optional)
                          minimum angle in degrees to be considered ring artifact
        :param rwidth: (int, optional)
                       Maximum width of the rings to be filtered in pixels
        :returns: Filtered data
        """
        progress = Progress.ensure_instance(progress, task_name='Ring Removal')

        tp = safe_import('tomopy.misc.corr')

        if run_ring_removal:
            h.check_data_stack(images)

            with progress:
                progress.update(msg="Ring Removal")
                sample = images.data
                tp.remove_ring(sample,
                               center_x=center_x,
                               center_y=center_y,
                               thresh=thresh,
                               thresh_max=thresh_max,
                               thresh_min=thresh_min,
                               theta_min=theta_min,
                               rwidth=rwidth,
                               ncore=cores,
                               nchunk=chunksize,
                               out=sample)

        return images
Exemplo n.º 20
0
 def test_set_steps_resets_current_step(self):
     p = Progress(num_steps=2)
     p.update(steps=1)
     self.assertEqual(p.current_step, 1)
     p.set_estimated_steps(10)
     self.assertEqual(p.current_step, 0)
     self.assertEqual(p.end_step, 10)
Exemplo n.º 21
0
def execute(data, cores=None, chunksize=None, progress=None):
    getLogger(__name__).warn("This only implement gap filling code. "
                             "NO CODE FOR SHIFTING THE CHIPS IS CURRENTLY "
                             "IMPLEMENTED!")

    progress = Progress.ensure_instance(progress, task_name='MCP Corrections')

    fool_my_own_sanity_check(data)

    # regions to mask, in order [left, top, right, bottom],
    # the order for the coordinates is also left, top, right, bottom
    # filter_width = 0 could use this for arbitrary filter value
    x1 = 254
    x2 = 258
    left_chip_region = [1, x1, 255, x2]
    right_chip_region = [257, x1, 511, x2]
    top_chip_region = [x1, 1, x2, 255]
    bottom_chip_region = [x1, 257, x2, 511]

    vertical_chip_regions = [top_chip_region, bottom_chip_region]
    horizontal_chip_regions = [left_chip_region, right_chip_region]

    with progress:
        progress.update(msg="MCP corrections")
        # 1st way -> set all of the coordinates to 0 in a for loop per region
        for region in vertical_chip_regions:
            left = region[0]
            top = region[1]
            right = region[2]
            bottom = region[3]
            if data.ndim == 3:
                for image in data:
                    do_vertical_magic(image, left, top, right, bottom)
            else:
                do_vertical_magic(data, left, top, right, bottom)

        for region in horizontal_chip_regions:
            left = region[0]
            top = region[1]
            right = region[2]
            bottom = region[3]
            if data.ndim == 3:
                for image in data:
                    do_horizontal_magic(image, left, top, right, bottom)
            else:
                do_horizontal_magic(data, left, top, right, bottom)

    # 2nd way -> create a mask of 512, 512 filled with 1, set the coordinates
    # to 1e-9 and then multiply all images by that mask!
    fool_my_own_sanity_check(data)

    return data
Exemplo n.º 22
0
def _execute_gpu(data, size, mode, progress=None):
    log = getLogger(__name__)
    progress = Progress.ensure_instance(progress,
                                        num_steps=data.shape[0],
                                        task_name="Median filter GPU")
    cuda = gpu.CudaExecuter(data.dtype)

    with progress:
        log.info("GPU median filter, with pixel data type: {0}, filter "
                 "size/width: {1}.".format(data.dtype, size))

        data = cuda.median_filter(data, size, mode, progress)

    return data
Exemplo n.º 23
0
def _execute(data, angle: float, cores: int, chunksize: int, progress: Progress):
    progress = Progress.ensure_instance(progress, task_name='Rotate Stack')

    with progress:
        f = psm.create_partial(_rotate_image_inplace, fwd_func=psm.inplace, angle=angle)

        data = psm.execute(data,
                           f,
                           cores=cores,
                           chunksize=chunksize,
                           progress=progress,
                           msg=f"Rotating by {angle} degrees")

    return data
Exemplo n.º 24
0
def execute_impl(img_num: int, partial_func: partial, cores: int, chunksize: int, progress: Progress, msg: str):
    task_name = f"{msg} {cores}c {chunksize}chs"
    progress = Progress.ensure_instance(progress, num_steps=img_num, task_name=task_name)
    indices_list = generate_indices(img_num)
    if multiprocessing_necessary(img_num, cores):
        with Pool(cores) as pool:
            for _ in pool.imap(partial_func, indices_list, chunksize=chunksize):
                progress.update(1, msg)
    else:
        for ind in indices_list:
            partial_func(ind)
            progress.update(1, msg)
    progress.mark_complete()
Exemplo n.º 25
0
def execute_single(data, roi, progress=None, out=None):
    progress = Progress.ensure_instance(progress, task_name='Crop Coords')

    if roi:
        progress.add_estimated_steps(1)

        with progress:
            assert all(isinstance(region, int) for
                       region in roi), \
                "The region of interest coordinates are not integers!"

            progress.update(msg="Cropping with coordinates: {0}".format(roi))

            output = out[:] if out is not None else data[:]
            output[:] = data[:, roi.top:roi.bottom, roi.left:roi.right]
        return output
Exemplo n.º 26
0
def apply_factor(data: np.ndarray, scale_factors, cores=None, chunksize=None, progress=None):
    """
    This will apply the scale factors to the data stack.

    :param data: the data stack to which the scale factors will be applied.
    :param scale_factors: The scale factors to be applied
    """
    # scale up the data
    progress = Progress.ensure_instance(progress, num_steps=data.shape[0])
    with progress:
        scale_up_partial = ptsm.create_partial(_scale_inplace, fwd_function=ptsm.inplace_second_2d)

        # scale up all images by the mean sum of all of them, this will keep the
        # contrast the same as from the region of interest
        data, scale_factors = ptsm.execute(data, [scale_factors.mean()], scale_up_partial, cores, chunksize, progress)

    return data
Exemplo n.º 27
0
    def _do_files_load_seq(self, data, files, name):
        progress = Progress.ensure_instance(self.progress, num_steps=len(files), task_name=f'Load {name}')

        with progress:
            for idx, in_file in enumerate(files):
                try:
                    data[idx, :] = self.load_func(in_file)
                    progress.update(msg='Image')
                except ValueError as exc:
                    raise ValueError("An image has different width and/or height "
                                     "dimensions! All images must have the same "
                                     "dimensions. Expected dimensions: {0} Error "
                                     "message: {1}".format(self.img_shape, exc))
                except IOError as exc:
                    raise RuntimeError("Could not load file {0}. Error details: " "{1}".format(in_file, exc))

        return data
Exemplo n.º 28
0
    def full(images: Images,
             cors: List[ScalarCoR],
             recon_params: ReconstructionParameters,
             progress: Optional[Progress] = None) -> Images:
        progress = Progress.ensure_instance(progress, num_steps=images.height)
        output_shape = (images.num_sinograms, images.width, images.width)
        output_images: Images = Images.create_empty_images(
            output_shape, images.dtype, images.metadata)
        output_images.record_operation('AstraRecon.full', 'Reconstruction',
                                       **recon_params.to_dict())

        proj_angles = images.projection_angles(
            recon_params.max_projection_angle)
        for i in range(images.height):
            output_images.data[i] = AstraRecon.single_sino(
                images.sino(i), cors[i], proj_angles, recon_params)
            progress.update(1, "Reconstructed slice")

        return output_images
Exemplo n.º 29
0
def _execute(data, size, edgemode, cores=None, chunksize=None, progress=None):
    log = getLogger(__name__)
    progress = Progress.ensure_instance(progress, task_name='NaN Removal')

    # create the partial function to forward the parameters
    f = ps.create_partial(_nan_to_median,
                          ps.return_to_self,
                          size=size,
                          edgemode=edgemode)

    with progress:
        log.info(
            "PARALLEL NaN Removal filter, with pixel data type: {0}".format(
                data.dtype))

        ps.shared_list = [data]
        ps.execute(f, data.shape[0], progress, msg="NaN Removal", cores=cores)

    return data
Exemplo n.º 30
0
def _execute(data: np.ndarray, size, mode, order, cores=None, progress=None):
    log = getLogger(__name__)
    progress = Progress.ensure_instance(progress, task_name='Gaussian filter')

    f = ps.create_partial(scipy_ndimage.gaussian_filter,
                          ps.return_to_self,
                          sigma=size,
                          mode=mode,
                          order=order)

    log.info("Starting PARALLEL gaussian filter, with pixel data type: {0}, "
             "filter size/width: {1}.".format(data.dtype, size))

    progress.update()
    ps.shared_list = [data]
    ps.execute(f, data.shape[0], progress, msg="Gaussian filter", cores=cores)

    progress.mark_complete()
    log.info("Finished  gaussian filter, with pixel data type: {0}, "
             "filter size/width: {1}.".format(data.dtype, size))