peak-o-mat

Author: Christian Kristukat
Contact: ckkart@users.sf.net
Revision: 1.1.1
Date: 2008-9-7
Copyright: This software has been placed under the GNU public license.

peak-o-mat is a data analysis and curve fitting program written in Python. It is especially designed to fit spectroscopic data but should be suited for any other fitting task. It allows for clearing, transforming, fitting, calibrating, etc. of spectra with few mouse clicks. peak-o-mat can easily be extended by writing own modules. It is being developed on linux and windows but should run on any other platform for which python and the extension modules listed below are available.

Getting the software

peak-o-mat is available on the sourceforge download page at:

https://sourceforge.net/project/showfiles.php?group_id=67624

See the change log for the list of changes.

Requirements

Optional:

Installation from source

Download the source tarball and unpack it somewhere. It is not necessary to install peak-o-mat. Just enter:

python peak-o-mat.py

In case you want to build the extension module which allows for reading OPJ files, you need SWIG >= 1.3.31 and a c++ compiler. Change to the liborigin sub directory and enter:

python setup.py build_ext --inplace

If you want to install liborigin in python's site-packages, enter:

python setup.py build
sudo python setup.py install

Installation from binary package

Windows binary packages of peak-o-mat are available. Everything needed to run peak-o-mat is included in there. You do not need to install any other software.

Basic Concepts

Data

The data is stored in a tree-like structure. There is one top-level element, the project. The next lower level is that of the plots, each of which can hold an arbitrary number of sets. A set is a 2d array containing the x-y data, where the x-data is ordered (typical for spectroscopic data). This data structure is represented by the tree view on the right side of the main frame. In addition to the plain x-y data, a set can have various objects attached, such as transformations (trafo), a fit model and weights.

Unlike some other data analysis programs, peak-o-mat allows for data manipulation/transformation on a higher level than operating on the raw data through a spreadsheet like interface. As peak-o-mat is especially designed to work with spectroscopic data, arithmetics on sets will do what you would expect intuitively, e.g. adding two sets will only add the y-data, while interpolating the x-axes in case they differ. Those kind of manipulations can be done using the 'Set operations' module. If you need to do more complicate operations, you can still copy the data to a data grid and manipulate the data there through a python shell.

Models

A model is an analytical function to which the set data is fitted. It can be described by

  • a valid python expression, where x stands for the set's x-values. You can use arbitrary variable names containing alphanumeric characters, e.g. "a*exp(-b0*x**2)", and all functions/symbols defined in the top level namespace of the numpy package.
  • a space separated list of pre-defined symbols, here called tokens, which represent common backgrounds and peak shapes. The function values represented by the tokens are finally added, e.g. "CB LO GA LO" represents a model with a constant background, one gaussian peak and two lorenzian peak shapes. You can append a number to any token to be able to distinguish them later, e.g. "CB LO1 GA LO2". Instead of the whitespace between the tokens, the '+' operator can be used. In some rare cases you might want to multiply the function represented by the tokens. This can be achieved by using the '*' operator. The model is evaluated from left to right and the usual sign rules do not apply!

Transformations

A trafo denotes any transformation of the x- or y-data of a set. Instead of changing the original data, all trafos are attached to a set and evaluated on demand whenever the set data is accessed. Like this, the original data can be restored by simply removing all trafos. Furthermore, if you remove bad data points from a set, a mask is applied to the data so that all points can be restored at any time.

Weights

to be written ...

GUI elements

The tree

The tree control on the right side of the main window reflects the structure of the project. All sets in one plot are shown together in the plot area left of the tree. The currently selected set is displayed in red, the others in black. You can select all sets of a plot by selecting the corresponding plot item or (only on wxGTK) a subset of sets within one plot by pressing SHIFT/CTRL-keys while selecting. Sets can be hidden and will thus show up in the plot area only if they are part of the current selection. The tree supports drag&drop of plot and set items. Press twice on any tree item to rename its label.

The toolbar

zoom Zoom mode: draw a rectangle around the desired to zoom in, click right button to zoom out.

auto Autoscale

autox Autoscale in x-direction only.

autoy Autoscale in y-direction only.

auto2fit Zoom to the extension of the fit model.

hand Drag mode: drag the visible plot area.

eraser Erase mode: draw a rectangle around points to be erased. This applies to the current selection and can be undone.

log Toggles the y-scale between linear and log10.

peak Shows each peak of the current model in addition to the sum.

linestyle Toggles the style of the set data between line and points.

The data grid

To open a data grid, which allows for direct data manipulation using a python shell, choose 'Data->New data grid' in the menu. To copy a set's x/y-data to a new data grid, select 'copy to data grid' from the popup menu in the project tree. The data grid named the grid is of particular interest as it is the target when exporting the fitted parameters. In contrast to the normal data grid pages one row label is always painted in red. This is the target row for the new parameters. It will move downwards automatically after having recieved a new set of parameters, extending the datagrid when necessary. The target row can be placed manually by double-clicking on a row label.

Each data grid page contains a python shell window which can be used like an ordinary python shell. In addition, the following global attributes are available which allow for accessing and manipulating the data of the data grid:

data        : the 2d array data
selection   : the selected area of the data grid, applicable as index for
              data, i.e. data[selection]
colN/rowN   : the N-th column/row vector
x/y         : row/column vectors containing the column/row indices
cstack(col) : append col as column to the current data
rstack(row) : append row as row to the current data

Arrays and vectors refer to instances of the ndarray object provided by the python numpy extension (http://numpy.scipy.org). In order to manipulate them a basic understanding of numpy is necessary.

The data/colN/rowN attributes can be read and written. When assigning to colN and rowN, the new value has to have the correct shape. This is best illustrated in a small example:

>>> import numpy as N
>>> data=N.zeros((50,3))
>>> col0=y
>>> col1=y**2+2*x-2
>>> col2=1/col1
>>> cstack(N.linspace(0,34,50))
>>> rstack([1,4,5])
>>>

Inserting/deleting/appending rows or columns

To insert/delete/append rows/columns, select some rows/columns by clicking on the row/column labels and then choose insert/delete/append from the popup menu.

copy&paste

You can copy and paste data from other applications to the spreadsheet and vice versa using the context menu. When choosing paste&replace the spreadsheets content will be replaced with the content of the clipboard, paste will try to insert the clipboard's content to the selected region. Therefor the current selection area has to have the same shape as the data to be inserted.

insert/delete&shift

In a usual peak-o-mat session you will fit a series of spectra and export the fitted parameters to the spreadsheet. In case the number of peaks changes within the series, the parameter table might get misaligned in case the new or the missing feature is not the last feature in the model description. In that case, some parameters will be placed in the wrong column. Here the insert/delete&shift menu item comes in handy. You can choose an arbitrarily sized area and delete it followed by shifting either the data right to the area to the left or shifting the data below the area upwards. The same applies for inserting data, in that case zeros will be inserted. The other rows or columns remain unaffected by those operations, if necessary zeros will be padded.

The modules

A module is a small functional unit which adds a feature to peak-o-mat. The available modules appear as notebook tabs in the lower part of the main window. The only built-in module is the Fit module. All other modules consist of a python source (.py) and a XRC (.xrc) file, the latter describing the GUI of the module.

Fit

all about data fitting

Data operations

As mentioned before, manipulations of the set data can be done on a higher level than editing the x- and y-data directly.

Operations on the sets can be either an operation between the y-values of different sets (inter-set) or a transformation of either the x- or y-values of one set (intra-set). In the former case, a new set is created, in the latter case the transformation is attached to the current set and can be removed later thus restoring the original data. The sets can be referenced by the identifier 'sX', where X is the set number of the active plot shown in the tree view on the right side. Inter-set operations are only possible between sets of the same plot. The intra-set operations are applied to all selected sets. The identifiers appearing in the expression determine wether the expression is a inter-set or a intra-set operation.

examples of valid expressions are:

x+10              intra-set, x-axis
1/y               intra-set, y-axis
log10(y)          intra-set, y-axis
(s0+s1)/2         inter-set
sum([s1,s2,s3])   inter-set

Evaluate

This module allows you to create sets by evaluating a custom function or by drawing a spline on the plot canvas.

Set info

The set info module gives information about the number of total and masked points of a set and the list of transformations attached to it. The transformations can be deactivated temporarily by unchecking the corresponding checkbox, removed completely and their comments can be edited when double-clicking on the comment field.

Calibration

calibrate data using spectral lines of Ne,Ar,He,Me, etc.

Plot

export to xmgrace (linux only)

Shell

shell access to the internals of peak-o-mat (dangerous)

Background

guess the background of a set

Ruby calibration

pressure calibration using the R1 luminescence

Customizing peak-o-mat

Config file

Upon start peak-o-mat looks for a configuration file config.py in $HOME/./peak-o-mat. An example config.py file looks like the following:

# if fast_display is True, only fast_max_pts points of all sets but the
# active one are shown
fast_display = False
fast_max_pts = 500

# truncate the data when importing
truncate = False
truncate_max_pts = 2000
truncate_interpolate = False

# set to True if the floating point is ',' (e.g. german windows)
floating_point_is_comma = False

Adding custom peak shapes

On startup peak-o-mat is importing $HOME/.peak-o-mat/userfunc.py. Put your own function definitions there according to the following scheme:

from peak_o_mat import peaks

peaks.add('PAR',
          func='a*x**2+b*x+c',
          ptype=peaks.ptype.BACKGROUND)
peaks.add('PEAK',
          func='amp*exp(-(pow(x-pos,2)/(fwhm*fwhm/2.0)))',
          info='a gaussian',
          ptype=peaks.ptype.PEAK,
          picker=peaks.LOPicker)

peaks.add() is defined as follows:

def add(self, name, func=None, info='', ptype=None, picker=None):
    name:   uppercase model name, e.g. GA
    info:   an information text describing the model
    func:   the function string
    ptype:  one of ptype.{BACKGROUND,PEAK,EXP,MISC}
    picker: a picker object, e.g. LOPicker, which handles the collection
            of the function's parameters from mouse actions

You may use any numpy symbols as if you had imported numpy like from numpy import *.

If you do not specify a picker, the initial guess for that peak must be entered by hand. Common pickers are defined in the file peaks.py in the peak-o-mat source distribution.

Installing/Writing Modules

In order to use third-party or own modules move the module's files to $HOME/.peak-o-mat/modules. peak-o-mat will load them upon program start. The modules which are distributed with peak-o-mat reside in <site-packages>/peak_o_mat/modules. Those global modules have to be listed in __init__.py at the same location to be activated.

Writing own modules is easy. Use xrced (part of every wxPython installation) to create a GUI and save it as mod_XXX.xrc. The top-level GUI element of each module must be a wx.Panel having the module's filename as XML ID (in this case mod_XXX). Then add anything you like but remember to keep the overall height of the panel small since the taller the module's GUI, the fewer space will be availabe for the graphs. If you provide XML IDs for the controls, let the IDs begin with xrc_. This enables you to access the controls by referencing them as self.xrc_xxx in the program. Then create a python source file, named mod_XXX.py, which has the following minimal content:

from peak_o_mat import module

Module(module.Module):
    title = 'this modules title'
    def __init__(self, *args):
        module.Module.__init__(self, __file__, *args)

It is absolutely necessary to call the constructor of module.Module as described above, if not, peak-o-mat will not be able to find the module's XRC file. However do not add code to the constructor which accesses the GUI, instead define the method:

def init(self):
    ....

and use it like a constructor. When OnInit will be called, the GUI has already been loaded and can be accessed savely, e.g. to set up event bindings. The Module class does not derive from a wx control, however it provides the following instance variables/methods:

self.panel       - reference to the panel
self.controller  - reference to the main controller
self.project     - reference to the project data
self.Bind()      - self.panel.Bind()
self.Unbind()    - self.panel.Unbind()
self.xrc_xxx     - reference to the wx control with
                   the XML ID *xrc_xxx*

See the files template.py/template.xrc in the modules subdir for a working example.