# 1D plugins

## Adding 1D plugins

### Overview

A 1D plugin is a module that can be added to the PyMca 1D window in order to perform user defined operations of the plotted 1D data.

Plugins can be automatically installed provided they are in the appropriate place:

> - In the user home directory (POSIX systems): ${HOME}/.pymca/plugins or ${HOME}/PyMca/plugins (older PyMca installation)

> - In “My Documents\PyMca\plugins” (Windows)

Plugins inherit the `Plugin1DBase` class and implement the methods:

> - `Plugin1DBase.getMethods()`

> - `Plugin1DBase.getMethodToolTip()` (optional but convenient)

> - `Plugin1DBase.getMethodPixmap()` (optional)

> - `Plugin1DBase.applyMethod()`

and modify the static module variable `MENU_TEXT` and the static module function `getPlugin1DInstance()` according to the defined plugin.

Optionally, plugins may also implement `Plugin1DBase.activeCurveChanged()` to react to data selection in the plot.

These plugins will be compatible with any 1D-plot window that implements the Plot1D interface. The plot window interface is described in the Plot1DBase class.

The main items are reproduced here and can be directly accessed as plugin methods.

> - `Plugin1DBase.addCurve()`

> - `Plugin1DBase.getActiveCurve()`

> - `Plugin1DBase.getAllCurves()`

> - `Plugin1DBase.getGraphXLimits()`

> - `Plugin1DBase.getGraphYLimits()`

> - `Plugin1DBase.getGraphTitle()`

> - `Plugin1DBase.getGraphXLabel()`

> - `Plugin1DBase.getGraphYLabel()`

> - `Plugin1DBase.removeCurve()`

> - `Plugin1DBase.setActiveCurve()`

> - `Plugin1DBase.setGraphTitle()`

> - `Plugin1DBase.setGraphXLimits()`

> - `Plugin1DBase.setGraphYLimits()`

> - `Plugin1DBase.setGraphXLabel()`

> - `Plugin1DBase.setGraphYLabel()`

A simple plugin example, normalizing each curve to its maximum and vertically shifting the curves.

    from PyMca5 import Plugin1DBase

    class Shifting(Plugin1DBase.Plugin1DBase):
        def getMethods(self, plottype=None):
            return ["Shift"]

        def getMethodToolTip(self, methodName):
            if methodName != "Shift":
                raise InvalidArgument("Method %s not valid" % methodName)
            return "Subtract minimum, normalize to maximum, and shift up by 0.1"

        def applyMethod(self, methodName):
            if methodName != "Shift":
                raise ValueError("Method %s not valid" % methodName)
            allCurves = self.getAllCurves()
            increment = 0.1
            for i in range(len(allCurves)):
                x, y, legend, info = allCurves[i][:4]
                delta = float(y.max() - y.min())
                if delta < 1.0e-15:
                    delta = 1.0
                y = (y - y.min())/delta + i * increment
                if i == (len(allCurves) - 1):
                    replot = True
                else:
                    replot = False
                if i == 0:
                    replace = True
                else:
                    replace = False
                self.addCurve(x, y, legend=legend + " %.2f" % (i * increment),
                                    info=info, replace=replace, replot=replot)

    MENU_TEXT="Simple Shift Example"
    def getPlugin1DInstance(plotWindow, **kw):
        ob = Shifting(plotWindow)
        return ob

### 1D plugin API

class PyMca5.PyMcaCore.Plugin1DBase.Plugin1DBase(plotWindow, **kw)
  activeCurveChanged(prev, new)

    A plugin may implement this method which is called when the active curve changes in the plot.

    Parameters:

      - prev – Legend of the previous active curve, or None if no curve was active.

      - new – Legend of the new active curve, or None if no curve is currently active.

  addCurve(x, y, legend=None, info=None, replace=False, replot=True, **kw)

    Add the 1D curve given by x an y to the graph.

    Parameters:

      - x (list or numpy.ndarray) – The data corresponding to the x axis

      - y (list or numpy.ndarray) – The data corresponding to the y axis

      - legend (string or None) – The legend to be associated to the curve

      - info (dict or None) – Dictionary of information associated to the curve

      - replace (boolean default False) – Flag to indicate if already existing curves are to be deleted

      - replot (boolean default True) – Flag to indicate plot is to be immediately updated

      - kw – Additional keywords recognized by the plot window. Beware that the keywords recognized by silx and PyMca plot windows may differ.

  applyMethod(name)

    The plugin is asked to apply the method associated to name.

  getActiveCurve(just_legend=False)
    Parameters:

      just_legend (boolean) – Flag to specify the type of output required

    Returns:

      legend of the active curve or list `[x, y, legend, info]`

    Return type:

      string or list

    Function to access the graph currently active curve. It returns None in case of not having an active curve.

    Default output has the form:

        xvalues, yvalues, legend, dict

    where dict is a dictionary containing curve info. For the time being, only the plot labels associated to the curve are warranted to be present under the keys xlabel, ylabel.

    If just_legend is True:

    > The legend of the active curve (or None) is returned.

  getAllCurves(just_legend=False)
    Parameters:

      just_legend (boolean) – Flag to specify the type of output required

    Returns:

      legend of the curves or list `[[x, y, legend, info], ...]`

    Return type:

      list of strings or list of curves

    It returns an empty list in case of not having any curve.

    If just_legend is False, it returns a list of the form:

        [[xvalues0, yvalues0, legend0, dict0],
         [xvalues1, yvalues1, legend1, dict1],
         [...],
         [xvaluesn, yvaluesn, legendn, dictn]]

    If just_legend is True, it returns a list of the form:

        [legend0, legend1, ..., legendn]

  getGraphTitle()
    Returns:

      The graph title

    Return type:

      string

  getGraphXLabel()
    Returns:

      The graph X axis label

    Return type:

      string

  getGraphXLimits()

    Get the graph X limits.

    Returns:

      Two floats with the X axis limits

  getGraphYLabel()
    Returns:

      The graph Y axis label

    Return type:

      string

  getGraphYLimits()

    Get the graph Y (left) limits.

    Returns:

      Two floats with the Y (left) axis limits

  getMethodPixmap(name)
    Parameters:

      name – The method for which a pixmap is asked

    Return type:

      QPixmap or None

  getMethodToolTip(name)

    Returns the help associated to the particular method name or None.

    Parameters:

      name – The method for which a tooltip is asked

    Return type:

      string

  getMethods(plottype=None)
    Parameters:

      plottype – string or None for the case the plugin only support one type of plots. Implemented values “SCAN”, “MCA” or None

    Returns:

      A list with the NAMES associated to the callable methods that are applicable to the specified type plot. The list can be empty.

    Return type:

      list[string]

  getMonotonicCurves()

    Convenience method that calls `getAllCurves()` and makes sure that all of the X values are strictly increasing.

    It returns a list of the form:

        [[xvalues0, yvalues0, legend0, dict0],
         [xvalues1, yvalues1, legend1, dict1],
         [...],
         [xvaluesn, yvaluesn, legendn, dictn]]

  removeCurve(legend, replot=True)

    Remove the curve associated to the supplied legend from the graph. The graph will be updated if replot is true.

    Parameters:

      - legend (string or None) – The legend associated to the curve to be deleted

      - replot (boolean default True) – Flag to indicate plot is to be immediately updated

  setActiveCurve(legend)

    Funtion to request the plot window to set the curve with the specified legend as the active curve.

    Parameters:

      legend (string) – The legend associated to the curve

  setGraphTitle(title)
    Parameters:

      title (string) – The title to be set

  setGraphXLabel(title)
    Parameters:

      title (string) – The title to be associated to the X axis

  setGraphXLimits(xmin, xmax, replot=False)

    Set the graph X limits.

    Parameters:

      - xmin (float) – minimum value of the axis

      - xmax (float) – minimum value of the axis

      - replot (boolean default False) – Flag to indicate plot is to be immediately updated

  setGraphYLabel(title)
    Parameters:

      title (string) – The title to be associated to the X axis

  setGraphYLimits(ymin, ymax, replot=False)

    Set the graph Y (left) limits.

    Parameters:

      - ymin (float) – minimum value of the axis

      - ymax (float) – minimum value of the axis

      - replot (boolean default False) – Flag to indicate plot is to be immediately updated

PyMca5.PyMcaCore.Plugin1DBase.MENU_TEXT = 'Plugin1D Base'

  This is the name of the plugin, as it appears in the plugins menu.

PyMca5.PyMcaCore.Plugin1DBase.getPlugin1DInstance(plotWindow, **kw)

  This function will be called by the plot window instantiating and calling the plugins. It passes itself as first argument, but the default implementation of the base class only keeps a weak reference to prevent circular references.

## Built-in 1D plugins

### Background subtraction tools

This plugin provides 3 methods:

> - subtract a SNIP1D background from the active curve

> - apply a Savitsky-Golay filter on the active curve

> - smooth and replace current curve by its SNIP1D background (deglitch)

### Median filter average

This plugin provides methods to replace curves by their median filter average. 3-, 5-, 7- or 9-points filters are provided. The filter can be applied on the data in its original order, or in a randomized order.

### Simple vertical shift

This plugin replaces all curves with a normalized and shifted curve. The minimum is subtracted, than the data is normalized to the maximum, and finally it is shifted up by i*0.1 (i being the curve index).

### Alignment plugin

This plugin aligns all curves with the active curve, using the FFT.

### Advanced alignment plugin

Due to uncertainties in the experimental set-up, recorded data might be shifted unrelated to physical effects probed in the experiment. The present plug-in calculates this shift and corrects the data using a variety of different methods.

#### Usage and Description

Data that is subject to a shift must be loaded into the plot window of the main application. The plug-in offers two ways to treat the data:

> - A shortcut options, called Perform FFT Shift, calculates the shift and directly corrects the data.

> - The Show Alignment Window option, showing a window that allows for specification of the shift and alignment methods, as well as offering the possibility to save calculated shifts and load previously calculated shifts from a file. It is also possible to enter shift values by hand.

Once the Alignment Window is opened, the alignment method and the shift method must be specified. The alignment method specifies how the shift is calculated, while the shift method determines how the shift is applied to the data.

The table shows three columns:

> - The first one shows the plot legend of the data that will be corrected by the shift method.

> - The second column shows the plot legend from which the shift is calculated.

> - The third column shows the shift values calculated by the alignment method in units of the plot windows x-axis.

While columns one and two can not be edited, shift values can be entered by hand. Another way of setting the shift values is to load them from a existing .shift file using the Load button.

Once the shift values are set, they can either be directly applied to the data present in the plot window, using the Apply button, or the data can be stored in memory. The latter options allow to use a reference signal recorded during the experiment, to determine the shift and then apply the shift values to a different set of data.

Note

In order to match different sets of data to another, as necessary in the case of a reference signal, the order in which the data is added to the plot window is crucial. If one switches between two sets of data, where one set aligns the other one, it is highly encouraged to consult the table in the Alignment window to check if every element in the two different sets of data is assigned to its correct counterpart before applying the shift.

If the data in the plot window is zoomed-in to a distinct feature, only this range of the data is used to calculate the shift.

#### Methods used by the plug-in

Alignment methods are used to calculate the shift. Present methods include FFT, MAX, FIT and FIT DRV.

FFT:

> Uses the Fourier Transform of the curves to calculate their cross-correlation. The maximum of the correlation is determined, and yields the shift value. This method is the default option. Since it is not affected by the peak shape, it is fast and numerically robust.

> Note

> The shifts are given in real space values.

MAX:

> Determines the maximum of each curve. The shift is given by the differences in the x-position of the maxima. Note that this method is highly vulnerable to noise in the data and spikes.

FIT:

> This method subtracts a background from the data using the SNIP algorithm and searches for peaks in the data. For every curve, the single most pronounced feature is selected. The peak is fitted by a Gaussian model. The shifts are then given by differences in the x-offsets of the fitted Gaussians.

FIT DRV:

> Uses the same procedure as the FIT method. However the fit is applied to the first derivative of the data. This method is only recommended for X-ray absorption data.

Shift methods are used to apply the calculated shift to the data. Present methods include Shift x-range and Inverse FFT shift.

Shift x-range:

> This method adds the calculated shift value to every point.

Inverse FFT shift:

> Takes the Fourier Transform of a curve and multiplies the shift as a phase factor. The multiplication of a phase factor in Fourier space translates to a shift in the x-range in real space. The shifted data is given by the inverse Fourier transform.

> Note

> For this process, the data needs to have a equidistant x-range. If this is not the case, the data will be interpolated on a equidistant x-range. Due to the cyclic nature of the Fourier transform, this method is recommended for data that has linear background.

### Remove glitches from curves

This plugin uses a median filter smoothing to remove glitches from curves. A configuration widget can be used to configure the median filter (width and threshold), and the user can choose to apply it on the active curve or on all curves.

### Built-in Math

This plugin provide simple math functions, to derivate or invert the active curve.

### Normalization

This plugin provides methods to normalize all curves.

Following normalization methods are available:

> - Normalize to maximum y / max(y)

> - Subtract offset and normalize to new maximum (y-min(y))/(max(y)-min(y))

> - Subtract offset and normalize to integrated area (y-min(y))/trapz(max(y)-min(y),x)

> - Subtract offset and normalize to counts (y-min(y))/sum(max(y)-min(y))

> - Divide all curves by active curve

> - Take the negative of the log of the previous division

### Fit all curves

This plugin allows to perform a fit on all curves in the plot. A widget is provided to configure the fit parameters and to specify the output file. The fit results are saved as a NeXus HDF5 file, with one entry per fitted curve.

### Motor Info

This plugin opens a widget displaying values of various motors associated with each spectrum, if the curve originates from a file whose format provides this information.