Spectra Image Profile - Create profiles from, normalize and edit 2D spectral data

This project provides tools for working on 2D spectral data, and was inspired by the WaveMetrics Image Line Profile procedure (now replaced by the internal Line Profile tool). The basic functionality is similar to the official tool at first glance, but this project has many convenient features tailored for spectroscopic data such as detector images, two-dimensional scans or intensity maps. The main functionality is the horizontal or vertical data integration between two region-of-interest (ROI) lines to create a profile, which can be saved, compared or even used to modify the 2D data itself. Other functions (such as normalization) are applied directly to the 2D data. The tool works directly on the input data, but a backup is saved upon start. Several quick-tools to work on 1D-3D data are included as well.

I tried my best to test everything thoroughly, but you should verify the correct behavior yourself to be sure. Bug reports and suggestions for new features are always welcome.

User Interface controls

To start, select a 2D wave in the Data Browser and then go to ‘Spectra Tools’ -> ‘Image Profile …’ in the top menu. Or use the command line:


A quick overview of all controls can be found below:

  • The profile can be calculated in horizontal (h key) or vertical (v key) direction. Diagonal or free-form modes (like in the Line Profile tool) are not available.
  • The Region-of-Interest (ROI) lines can be modified via the control variables, by dragging the lines directly with the mouse on the image or by using the cursor keys on the keyboard (holding the shift key speeds up movements by 4x and the ctrl / command key slows down movement by 1/2).
  • To instantly go to the full (minimal) ROI width use the respective check boxes or use the page up / page down key.
  • Normalize Profile: The profile (not the image) will be normalized to fall between 0 and 1.
  • Mouse Csr Profile: An additional profile appears for comparison, which shows the current row or column under the mouse cursor (toggle with the m key). This profile is not saved.
  • Snap Lines to Grid: The ROI line positions are constrained to include only full rows / columns.
  • Keep average Int.: This will preserve the average intensity when normalizing the 2D data. Normalization involves division by some normalization term, which reduces the intensity. This checkbox will rescale the data back to the intensity level before normalization.
  • Undo All Changes: Resets all changes made to the 2D data.
  • Undo Last Change: Undoes the last change made to the 2D data (will not undo multiple steps).

Normalization buttons

Currently, three normalization functions are implemented:

  • Div. by Profile: This divides the 2D image by the current profile (each column in horizontal mode and each row in vertical mode, respectively). The profile is slightly smoothed before the division to avoid amplifying noise. Holding the ctrl / command key while pressing the button prevents this smoothing step. See further below how to modify the smoothing parameter.
  • Each Maximum: Finds the maximum of each row (horizontal mode) or each column (vertical mode) and divides the row / column by this value. This is useful, for example, to equalize the data in one direction (use the Keep avg. Int. checkbox to prevent downscaling of the data to 1)
  • A user-defined button (here labeled ‘Ring Currrent’): Normalize by user provided information. This can be any data parameter or wave saved in the current experiment. Examples are normalization by a secondary readout, time, concentration etc. See the last section on how to define your own functionality here.

The Save Profile and Snapshot buttons

The Save profile button saves the current profile next to the input data using a name ending which depends on the selected range. The ending is of the format “_H(xxx-xxx)” (horizontal mode) or “_V(xxx-xxx)” (vertical mode), where xxx give the start and end of the current range, e.g., “mydata_H(16.7-19.3)”. If the full image is selected the ending will be just “_prH” or “_prV”, respectively. Holding the shift key while pressing the button will lock the ending to “_prH” / “_prV” regardless of the selected range. The range and width is always saved inside the output wave’s note.

The Snapshot button will instead create and display a backup of the current profile for comparison. Each button press updates this snapshot to the current one. This profile will not be saved.

The Delete ROI Section button

This button removes the columns (horizontal) or rows (vertical) inside the Region Of Interest. If the data at the beginning of the wave is removed, the scaling is adjusted to account for the deleted points. However, if data in the center is removed the scaling cannot be adjusted, since a waves scaling must be always linear and continuous. Be aware that this may lead to a mismatch between the image data and the scaling. If the scaling is important (e.g., a continuous energy scale), either refrain from using this feature or take care to only remove sections at the edges.

The Subtract Profile button

The current profile will be subtracted from each column (horizontal mode) or row (vertical mode). This can be used, for example, to remove constant features from a measurement which appear undisturbed in part of the data and thus can be selected with the ROI lines.

This button has an additional functionality only in horizontal mode: The spectrum can be shifted each column step according to the Y-axis delta. In other words, each increasing column the Y-scale delta value is added to (or subtracted from) the profile’s x scaling, which subtracts the profile in diagonal direction. This is useful to subtract features which change with the parameter on the Y scale like, for example, spectral features moving with increasing photon energy.

  • Hold ctrl / command to subtract the profile along increasing Y delta values.
  • Hold alt / option to subtract the profile along decreasing Y delta values.

Below example shows the diagonal subtraction result:

The Shift +/- buttons

These two buttons only work horizontally (regardless of the selected mode) and are used to add or subtract the Y-axis scale from the X-axis. In other words, the X-scaling of each column is adjusted by its respective Y-scaling value; the data is recalculated into a parallelogram. This will straighten features in the data which were changing with increasing Y values. An example would be a photon-energy (Y) scan of a spectrum where certain spectral features increase in their (X) emission energy. Subtracting the photon energy scale from a photoelectron spectrum in a kinetic energy scale would give binding energy, while adding the photon energy scale reverts back to kinetic energy. The effect is illustrated again with above example data:

Hold ctrl / command to cut partial data after the shift has been applied (the parallelogram is cut back into a rectangle). Note that this might fail if there is not even one complete row of data left (the skew of the parallelogram is too large to fit a rectangle inside).

Align Features functionality

This algorithm looks for similar features of each column (horizontal mode) or row (vertical mode) and tries to align these features for maximum overlap by shifting each column / row by a certain amount. The algorithm uses wave correlation and shifts the data in whole point steps (no interpolation). This can be used, for example, to correct slight shifts of peaks in a spectrum or to estimate the shift of a peak versus some other parameter like time or position:

The algorithm uses the first column (bottom to top in horizontal mode) or row (left to right in vertical mode) of the data as reference and tries to align all other columns / rows to this reference. Hold shift to use the last row / column instead (top to bottom in horizontal mode and right to left in vertical mode).

Often, it is not desired to align to the full data with lots of different features. Setting the A and/or B cursors onto the image will limit the range from which the reference is selected to maximize overlap with only one selected feature. This might still fail if many similar features are present.

Activate Smooth to smooth the data before aligning. This can improve the results for noisy data.

Activate Output Shift Result to write the shift values into a wave with the name ending "_shft". The output is scaled by the 2D data’s wave scaling.

Note that the algorithm is ‘dumb’ in a sense that it only looks for the maximum correlation and not if peak features really match etc. In the worst case this just aligns artifacts such as noise.

Quick access functions in the menu

Some useful functions are available in the Spectra Tools menu:

  • Append 1D,2D Datasets into 2D Data: Combines the columns (Y dimension) of multiple datasets (e.g., multiple measurements) into one consecutive 2D data wave. The X dimension is extended to cover the full X range of all datasets if needed.
  • Stack 2D Datasets into 3D Data: Stacks multiple 2D spectra (e.g., MCP images) on top of each other to produce a 3D array.
  • Profile of 2D\3D Data: Same as creating a profile over the full data in horizontal or vertical mode using the profile panel. This will give 1D data for a 2D input, or 2D data or a 3D input.
  • 2D Image from 3D Data: Sums 3D data in the layer (array) direction to give a 2D image (e.g., gives a sum of all MCP images of a 3D array).
  • Split Up 2D\3D Data: Separates 2D / 3D data into individual waves holding columns, rows or layers. The individual waves are saved in a folder with the name of the input.

Procedure settings and user button code

The procedure header has two global constants which control the smoothing factor of …

  • kNormProfileSmooth: Sets the smoothing factor as an integer for profile normalization. The profile is smoothed by this factor before used for division with the 2D data.
  • kAlignSmooth: The initial smoothing factor applied to each row / column before the correlation is calculated. Useful to suppress noise. The factor can be adjusted at any time inside the panel.

The user-defined (normalization) button

Two functions and one global variable are used to provide the functionality for the user button:

  • kUserInfoBtnName: Defines the button’s label and can be changed to reflect the purpose of the button. This name should be short to fit inside the button.
  • Profile_ActivateUserInfoButton(inputWave): A function for checking whether the conditions for using the button are fulfilled. A return value of 1 activates, any other value disables the button. One could for example check here if the required information is contained in the 2D data or loaded in the current experiment.
  • Profile_ExecuteUserInfoButton(inputWave): This function is called to do the normalization (or whatever you like to do here). Return a scaling factor for scaling the intensity to its average after the normalization step should the Keep average Int. checkbox be activated (returning 0 skips this step).

You can modify the constant and the two functions directly at the beginning of the procedure file, but it is more convenient to provide your own code in a separate file or inside the experiment environment. Use the Override keyword in front of the Function / StrConstant statement to override the standard definitions inside the package. Have a look at the example implementation inside the project’s procedure, which is used to normalize the ring current of synchrotron experiments saved inside the 2D data itself.

While the user button is intended for normalization, it is really a free-for-all button for any modification to the 2D data you may want. You could instead write a function which, for example, splits the image in half or applies an interpolation or does something completely different in each experiment file.

The following code shows the current implementation of the user-definable normalization button:

Static StrConstant kUserInfoBtnName = "Ring Current"    // the title of the user button

Static Function Profile_ActivateUserInfoButton(inwave)
    Wave inwave
    Variable activate = 0
    // +++ conditions for activation +++
    activate = StringMatch(GetDimLabel(inwave,1,0),"*mA*")  // check if dim-labels contain "mA" values
    activate = StringMatch(note(inwave),"*ring current normalized*")? 0 : activate  // already normalized?
    // +++
    return activate // return 1 to activate button

Static Function Profile_ExecuteUserInfoButton(inwave)
    Wave inwave
    Variable valAvg = 0
    // +++ ring current normalization procedure +++
    Variable i, value
    for (i = 0; i < DimSize(inwave,1); i += 1)
        String Currlabel = GetDimLabel(inwave,1,i)  // get the information from the column label
        sscanf Currlabel, "%s (%f mA)", Currlabel, value    // search for ring current info in the form "time (XXX mA)"
        if (value != 0)
            inwave[][i] /= value
        valAvg += value // add the values for intensity re-normalization later
    valAvg /= i+1
    Note inwave, "ring current normalized"  // write into note that the normalization has been done
    // +++
    return valAvg   // return the intensity normalization factor


Project Details

Current Project Release

Release File: Image Profile_v3.71.zip
Version: IGOR.6.30.x-3.71
Version Date: Fri, 07/23/2021 - 11:30 pm
Version Major: 3
Version Patch Level: 71
OS Compatibility: Windows Mac-Intel
Release Notes:
  • Improvements of matrix calculations thanks to suggestions by A.G. (WaveMetrics).
  • Added image contrast controls.
View All Releases

Wow. That single handily replaces 90% of the scripts I use every day with one convenient panel!

Thank you for sharing 😊

Great to hear. Thank you for your comment! I think this tool saves me the most time as well (others are graph-related tools which I haven't put up here yet ;). I guess the other 10 % are specialized scripts only related to your field? Please let me know if there is a feature which would make your (and others) life easier.




Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More