Source code for mantidimaging.core.operations.monitor_normalisation.monitor_normalisation

# Copyright (C) 2024 ISIS Rutherford Appleton Laboratory UKRI
# SPDX - License - Identifier: GPL-3.0-or-later
from __future__ import annotations
from functools import partial
from typing import Any, TYPE_CHECKING
from collections.abc import Callable

import numpy as np

from mantidimaging.core.operations.base_filter import BaseFilter
from mantidimaging.core.parallel import shared as ps
from mantidimaging.core.parallel import utility as pu

if TYPE_CHECKING:
    from mantidimaging.core.data import ImageStack
    from mantidimaging.gui.mvp_base import BaseMainWindowView
    from PyQt5.QtWidgets import QFormLayout, QWidget


def _divide_by_counts(data=None, counts=None):
    data[:] = np.true_divide(data, counts)


[docs] class MonitorNormalisation(BaseFilter): """Normalises the image data using the average count of a beam monitor from the experiment log file. This scaling operation is an alternative to ROI normalisation and allows to account for beam fluctuations and different exposure times of projections. Intended to be used on: Projections When: As a pre-processing step to normalise the grey value ranges of the data. """ filter_name = "Monitor Normalisation" link_histograms = True
[docs] @staticmethod def filter_func(images: ImageStack, progress=None) -> ImageStack: """ :return: The ImageStack object which has been normalised. """ if images.num_projections == 1: # we can't really compute the preview as the image stack copy # passed in doesn't have the logfile in it raise RuntimeError("No logfile available for this stack.") counts = images.counts() if counts is None: raise RuntimeError("No loaded log values for this stack.") counts_val = pu.copy_into_shared_memory(counts.value / counts.value[0]) do_division = ps.create_partial(_divide_by_counts, fwd_function=ps.inplace2) arrays = [images.shared_array, counts_val] ps.execute(do_division, arrays, images.num_projections, progress) return images
[docs] @staticmethod def register_gui(form: QFormLayout, on_change: Callable, view: BaseMainWindowView) -> dict[str, QWidget]: return {}
[docs] @staticmethod def execute_wrapper(*args) -> partial: return partial(MonitorNormalisation.filter_func)
[docs] @staticmethod def validate_execute_kwargs(kwargs: dict[str, Any]) -> bool: return True