Skip to content
Snippets Groups Projects
FindReflectometryLines.py 4.57 KiB
Newer Older
#pylint: disable=no-init,invalid-name
from mantid.api import *
from mantid.kernel import *
import numpy as np

class PeakFindingException(Exception):

class FindReflectometryLines(PythonAlgorithm):

    # Determine if a given signal  identifies a peak or not.
    def __is_peak(self, before, current, after):
    	# A peak is defined to be any signal that is preceeded by a lower signal value and followed by a lower signal value.
        if before < current and current > after:
            return True
        return False

    # Find a list of spectra numbers corresponding to peaks in the data.
    def __find_peak_spectrum_numbers(self, y_data, ws):
        peak_index_list = []
        for index, current in enumerate(y_data.flat):
            if (index > 0) and (index < (y_data.size - 1)):
                before = y_data[index-1]
                after = y_data[index+1]
                if self.__is_peak(before, current, after):
                    spec_number = ws.getSpectrum(index).getSpectrumNo()
                    peak_index_list.append(spec_number)
        return peak_index_list

    # Zero-out any data considered to be background.
    def __remove_background(self, y_data):
        y_average = np.sum(y_data) / y_data.size
        y_max = np.max(y_data)
    	#The thresholding criteria is hard-coded to be above the average as follows.
        threshold =  (y_max - y_average)/10 + y_average
        y_data[y_data < threshold] = 0
        return y_data
        return "PythonAlgorithms;Reflectometry"
        return "FindReflectometryLines"
        return "Finds spectrum numbers corresponding to reflected and transmission lines in a line detector Reflectometry dataset."
        workspace_validator = CompositeValidator()
        workspace_validator.add(WorkspaceUnitValidator("Wavelength"))
        workspace_validator.add(SpectraAxisValidator())
        self.declareProperty(MatrixWorkspaceProperty("InputWorkspace", "", Direction.Input, workspace_validator),
                             "Input Reflectometry Workspace")
        self.declareProperty(ITableWorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output Spectrum Numbers")
        self.declareProperty(name="StartWavelength", defaultValue=0.0, validator=FloatBoundedValidator(lower=0.0),
                             doc="Start wavelength to use for x-axis cropping")
        self.declareProperty(name="KeepIntermediateWorkspaces", defaultValue=False,
                             doc="Keeps cropped and integrated workspaces in memory after usage.")
        import mantid.simpleapi as ms
        in_ws = self.getPropertyValue("InputWorkspace")
        min_wavelength = self.getPropertyValue("StartWavelength")
        keep_workspaces = self.getPropertyValue("KeepIntermediateWorkspaces")

    	# Crop off lower wavelengths where the signal is also lower.
        cropped_ws = ms.CropWorkspace(InputWorkspace=in_ws,XMin=float(min_wavelength))
    	# Integrate over the higher wavelengths after cropping.
        summed_ws = ms.Integration(InputWorkspace=cropped_ws)
    	# Loop through each histogram, and fetch out each intensity value from the single bin to generate a list of all values.
        n_histograms = summed_ws.getNumberHistograms()
        y_data = np.empty([n_histograms])
        for i in range(0, n_histograms):
            intensity = summed_ws.readY(i)[0]
            y_data[i] = intensity
        y_data = self.__remove_background(y_data)
        peak_index_list = self.__find_peak_spectrum_numbers(y_data, summed_ws)
        #Reverse the order so that it goes from high spec number to low spec number
        peak_index_list.reverse()
        n_peaks_found = len(peak_index_list)

        output_ws = WorkspaceFactory.createTable("TableWorkspace")
        output_ws.addColumn("int", "Reflected Spectrum Number")

        if n_peaks_found > 2:
            raise PeakFindingException("Found more than two peaks.")
        elif n_peaks_found == 0:
            raise PeakFindingException("No peaks found")
        elif n_peaks_found == 1:
            output_ws.addRow(peak_index_list)
        elif n_peaks_found == 2:
            output_ws.addColumn("int", "Transmission Spectrum Number")
            output_ws.addRow(peak_index_list)

        if int(keep_workspaces) == 0:
            ms.DeleteWorkspace(Workspace=cropped_ws)
            ms.DeleteWorkspace(Workspace=summed_ws)

        self.setProperty("OutputWorkspace", output_ws)
AlgorithmFactory.subscribe(FindReflectometryLines())