Source code for mantidimaging.core.operations.monitor_normalisation.monitor_normalisation
# Copyright (C) 2023 ISIS Rutherford Appleton Laboratory UKRI
# SPDX - License - Identifier: GPL-3.0-or-later
from __future__ import annotations
from functools import partial
from typing import Callable, Dict, Any, TYPE_CHECKING
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