
Spectra Wave Arithmetic - Match 1D/2D waves to calculate differences, sums etc.

This package provides a user interface and programming environment for aligning and comparing two 1D / 2D waves and calculate for each overlapping point: output = f(modified input data, reference data). The input is modified using the UI controls and compared against a reference wave. Available Modes are:
- Subtraction (-)
- Addition (+)
- Multiplication (*)
- Division (/)
- Average
- Percent difference (difference normalized by the average in %, i.e., (A-B)/(A+B) * 200)
- Custom user equation
The input wave can be shifted, offset and scaled. The original purpose was to calculate differences, hence the name Difference Generator. Latre versions added support for addition, multiplication, division, percent difference and arbitrary equations.
The source waves of both the data to be modified and the reference is never altered. The calculation is done on temporary data, and any modification (named with ending "_mod") and the result of the arithmetic operation are exported as separate output waves. The default ending for naming the output is "_dif" for subtraction, "_sum" for addition, "_mul" for multiplication, "_div" for division, "_pdif" for % difference and "_calc" for custom formulas. Settings are saved within the output wave's notes and will be reloaded automatically upon resuming with the same input. The UI is folder aware.
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.
Graphical User Interface (UI) controls - 1D data
Select one or two waves in the Data Browser and then navigate to 'Spectra Tools' → 'Compare and Modify Data....' in the main menu or use the command line:
WaveArithmeticUI(WaveToEdit)
or alternatively:
WaveArithmeticUI(WaveToEdit,refwave=ReferenceWave)
The second wave selected in the Data Browser or provided via the optional 'refwave' parameter is pre-selected as reference. This is an overview of the controls (here, for modifying 1D data):
The modified wave and the reference wave can be selected via the drop-down menu and their role switched via the ] button. If Extend to Full Overlap is active the reference data is extended by repeating the averaged endpoints to the range of the modified data (no effect if the data overlaps already fully). This is most useful when the edge values of the reference are close to zero so that the error is small. This feature is only available for calculations involving 1D data.
Operation Mode:
- Choose a preset from the (▼) drop-down menu: M - R subtraction (- key), M + R addition (+ key), M * R multiplication (* key) or M / R division (/ key), (M + R) / 2 average or (M - R) / (M + R) * 200 percent difference.
- Any custom equation may be entered directly using M (modified input data) and R (reference data).
- The result can be inverted (flipped along the Y or Z axis) with the Invert checkbox (i key).
When you are done:
- Export & Exit will export the result and modification as separate waves and then closes the UI.
The exported waves are plotted in a graph when the Plot Exported checkbox is active. All previous graphs with the same data are updated as well to reflect the new settings. All settings are saved with the output and will be reapplied upon reloading. See further below for an explanation how the data is saved including the purpose of the 'Use Ref. Name' setting. - Exit will close the UI without saving anything.
- Use the Add drop-down menu to select the type of post-processing: smoothing, integration or derivation of the result. Activating the Incl. Additional item will export this post-processed data as well (name ending '_smt', '_int' or '_der').
Applying Changes to the Input Data:
- Shift in X / horizontal and Y / vertical directions using the arrow buttons (cursor keys on the keyboard).
- Scale using the stretch (page up key) and shrink (page down key) controls.
- The delta step of each modification can be set using the controls to the left.
- Absolute Changes in the lower section of the UI can be used to dial in the desired values directly.
- Use the Reset buttons for All modifications or individual changes of the X / Y shift or (*) scaling to undo modifications.
Smoothing:
- Both waves can be Gaussian broadened by setting the respective control. Smoothing of the reference data is only temporary and not applied to the input reference data. This setting is saved with the output and will be reapplied upon reloading. Use the home / end keyboard shortcuts to increase / decrease the smoothing value (holding alt/option will change the value for the reference data).
Further keyboard shortcuts:
- Hold Cmd (Mac) / Ctrl (Win) for changes in steps of 0.5 times the current delta value.
- Hold Shift for changes in steps of 10 times the current delta value.
- Hold both Shift + Command / Ctrl for changes in steps of 0.1 times the current delta value.
- r key to ‘Reset All'
- p key to toggle ‘Pin Background’
- Hold Cmd (Mac)/ Ctrl (Win) while pressing ‘Reset All’ and the reference wave will be set to none.
- Hold Cmd (Mac)/ Ctrl (Win) while pressing ‘Export & Exit’ to export without closing the UI. This is useful to process many waves in quick succession by selecting the next one from the drop-down menu.
- Hold Option (Mac) / Alt (Win) while pressing ‘Export & Exit’ to force the 'Use Ref. Name' setting (this has the same effect as activating the check box).
Graphical UI controls - 2D data
2D data is loaded and processed in the same way. The data is now displayed as two overlapping images, with the reference data plotted as a semi-transparent layer on top of the input data. There are additional controls specific to 2D data (see below), such as additional controls to modify the third (Z) dimension:
At the very bottom are additional controls to modify the image appearance:
- Ref. Alpha: The transparency (alpha value) of the reference data. Choose between fully transparent (slider to the left) and fully visible (slider to the right).
- Show (reference): Toggles the visibility of the reference image. Uncheck to hide. Can also be toggled with the s key on the keyboard.
- Image color and Range controls: Choose the color mapping for each image and adjust the displayed z-range via sliders.
Showing Profiles and Setting Region-Of-Interest (ROI):
To aid with alignment, the intensity profiles (i.e., sum) in X / Y directions can be displayed via the Show Profiles button. A side-panel will appear with two graphs, one for X and one for Y. Profiles will update automatically, you can immediately see the effect of each modification.
To limit the range from which the profiles and displayed min. / max. values are calculate, drag a marquee across the image over the region of interest you want to work with. Then, use the Set / Clear ROI button. Pressing the button again without a marquee on the graph will clear the ROI. You can alternatively use the right-click menu after dragging a marquee to set / clear the ROI. Limiting the range makes it easier to align / match a specific sub-region of the data.
How the result is saved
The result is exported to the folder of the input as 'wavename' + "_mod"' for the modified data and 'wavename' + mode-specific extension for the result of the calculation. The mode-specific extensions are:
- "_dif"' (subtraction)
- "_sum" (addition)
- "_mul" (multiplication)
- "_div" (division)
- "_avg" (average)
- "_pdif" (percent difference)
- "_calc" (custom formula)
All settings are saved inside the wave note of both of these output waves. Below is an example output, where 'first spectrum' was modified and 'second spectrum' was the reference:
Loading the UI with the same initial data ('first spectrum' in this case) will reload the last session from the '_mod' (or '_dif' wave, if '_mod' does not exist). Note that loading a '_dif' or '_mod' wave directly will just start a new session (this makes it possible to create differences of differences etc.). The input and reference data can be in different folders, but the '_mod' or '_dif' wave should stay with the respective input in the same folder.
If neither a 'dif' (or 'sum', 'mul', 'div') or 'mod' wave with the same name is found in the input wave's folder, then the default settings are loaded. It is thus recommended to keep the result and modified waves together with the input in the same folder to be able to reload the settings later. What will be reloaded if you have mixed result waves from different modes? The loading hierarchy is 'mod' > 'dif' > 'sum' > 'mul' > 'div' > 'pdif'. For example, without the '_mod' and '_dif' waves present in the folder will load the settings from the '_sum' wave if present.
What is the purpose of the 'Use Ref. Name' setting?
Imagine the following scenario: You have measured 'baseline' data and then several data sets in succession like this:
- baseline
- measurement1
- measurement2
- measurement3
- ...
Let's assume you want to remove the baseline from all measurements but each measurement data itself should not be altered (e.g., to preserve their relative shift or intensity). You instead can modify (shift, scale etc.) the baseline while comparing to each measurement and then save the result next to each data set using the Use Ref. Name setting.
Load the baseline as Modify and one measurement as Reference, then apply modifications as necessary (to the baseline). Since the role of the modified and reference data is reversed, this usually means you need to activate 'Invert'. Before exporting, activate 'Use Ref. Name' to save the result next to each measurement set. This will create a unique output for each measurement:
- baseline
- baseline_mod
- measurement1
- measurement1_dif
- measurement2
- measurement2_dif
- measurement3
- measurement3_dif
- ...
What if you reload measurement1 but have conflicting settings in waves measurement1_mod and measurement1_dif? In this case, measurement1_mod is loaded according to the hierarchy 'mod' > 'dif' > 'sum' > 'mul' > 'div' > 'avg' > 'pdif'.
Running your own code:
You can generate comparisons of two waves using the function:
doWaveArithmetic(WaveArithmeticStruct s)
The WaveArithmeticStruct structure looks like this:
Structure WaveArithmeticStruct variable mode // 1: Subtr. (M-R) 2: Add (M+R) 3: Multiply (M*R) 4: Divide (M/R) 5: Avg 6: %Diff => (default 1) char formula[100] // free-form arithmetic expression: M & R as stand-in for orgWave & refWave; use instead of mode Wave orgWave // [mandatory] wave to compare 1 - will NOT be modified in any way Wave refWave // [mandatory] wave to compare 2 - will NOT be modified in any way Wave cmpWave // [optional] result of comparison between orgWave and refWave will be written here Wave modWave // [optional] modified wave - saves the scaled and shifted version of orgWave Wave modRefWave // [optional] modified reference wave - saves the smoothed version of refWave (if refSmooth > 0) // all below parameters are optional variable orgSmooth // amount of smoothing for wave 1 (default 0) variable refSmooth // amount of smoothing for wave 2 (default 0) variable baselineXval // x position of baseline (default NaN) variable baselineYval // y value (1D) or position (2D)of baseline (default 0) variable baselineZval // for 2D: z value of baseline (default 0) variable baselineFixed // baseline is omitted from Y scaling if set to 1 (default 0) variable invert // invert the output in Y (default 0) variable xShift // modify wave 1: x displacement (in wave's units) (default 0) variable yShift // modify wave 1: y displacement (in wave's units) (default 0) variable valShift // modify wave 1: intesity displacement (offset) (default 0) variable xScale // modify wave 1: x scale (default 1) variable yScale // modify wave 1: y scale (default 1) variable valScale // modify wave 1: y / z scaling (default 1) variable UIpinToggle // options related to user interface; don't use (default 0) variable UIoptions // bit options related to user interface; don't use (default 0) EndStructure
In your code, use the structure to pass the input waves and desired parameters to the function. You need to pass at least the two input (orgWave and refWave) and one output wave (cmpWave; this one will be overwritten). A simple example could look like this:
Function CompareTest(Wave wave1, Wave wave2) STRUCT WaveArithmeticStruct s WaveArithmeticInitialize(s) // initialize structure parameters with defaults Duplicate/O wave1, $(NameOfWave(wave1)+"_dif") Wave s.cmpWave = $(NameOfWave(wave1)+"_dif") Wave s.orgWave = wave1 Wave s.refWave = wave2 s.refSmooth = 0.5 // smooth wave2 (optional; data will not be altered) s.xshift = -0.02 // shift wave1 (optional; data will not be altered) String statusmsg = WaveArithmeticErrorMsg(doWaveArithmetic(s)) Print statusmsg End
WaveArithmeticErrorMsg() generates a human-readable error message in case there is a problem. If official name-end tags (e.g., "_dif") are used then the output is fully compatible with the UI, i.e., settings are parsed when using the UI with the generated waves.
Settings inside the procedure header
The header contains settings as static constants which are used by the UI, and can be edited here if needed (rather not mess with these settings unless really necessary). For example, the name-end tags ('_dif', '_mod' etc.) can be altered here, should there be a conflict with other names in your work-flow (in fact, Igor's own Differentiate function also uses '_dif'):
static StrConstant kModEnd = "_mod" // label for modified data static StrConstant kAuxEnd = "_smt;_int;_der;" // label for additional data static StrConstant kOutEnd = "_calc;_dif;_sum;_mul;_div;_avg;_pdif;" // label for output data static StrConstant kModePresets = "M - R;M + R;M * R;M / R;(M-R)/(M+R) * 200;" // presets for the modes
Project Details
Current Project Release
Release File: | Difference Generator_v5.22.zip (27.84 KB) |
Version: | IGOR.8.00.x-5.21 |
Version Date: | |
Version Major: | 5 |
Version Patch Level: | 22 |
OS Compatibility: | Windows Mac-Intel |
Release Notes: |
|

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
Nice looking, chozo! It has a lot of features that aren't in the Wave Arithmetic panel.
February 4, 2021 at 09:58 am - Permalink
Thank you John! As the name suggests, this project started to make it possible to create differences with manual control and instant feedback for extracting even minute differences between measurements. But now that you mention it, it has indeed some things in common with the Wave Arithmetic package. This actually gives me the idea to add division and multiplication to the package for completeness.
EDIT: I have now updated the project to include four modes: Difference, sum, multiplication, and division.
February 4, 2021 at 06:14 pm - Permalink
I am seeing a pattern here: it seems that spectroscopists keep toolbags of useful packages that do similar things. I have a procedure ("wave scale and subtract") that does some of the things your panel can do, but as usual your panel is more sophisticated and does a lot more.
I will attach my little procedure here, just in case you are curious, but it doesn't do anything other than a small subset of what you do here.
March 17, 2021 at 05:17 am - Permalink
At one point in the mid- to late 90's (Igor 3 to 4), the toolbox was collected under the package SpXZeigR. I had an entire suite of features, help files, and tutorials. You won't find the original anymore (I have it somewhere on an archived CD). You will find a scattering of references to it, including a doi article that I did not even know about until just now.
I always wished to have had the time (and/or co-developers) to sustain the package.
March 17, 2021 at 06:08 am - Permalink
Yes, I remember SpXZeigR, and I had that and other packages in mind when I wrote the comment. I had already developed a set of tools more specific to the techniques I was using at that time, so SpXZeigR never really entered my workflow.
March 17, 2021 at 06:25 am - Permalink
RE SpXZeigR ... Sad as I am to see the package fade into the historical records, I am also glad to see a plethora of well-designed packages being provided to take its place.
March 17, 2021 at 06:38 am - Permalink
I remember SpXZeigR. If tech support queries reflects popularity, it was fairly popular :)
March 17, 2021 at 10:43 am - Permalink
John: The support that WaveMetrics provided to sustain SpXZeigR was greatly appreciated.
March 17, 2021 at 12:08 pm - Permalink
I didn't mean that it had lots of problems! No matter how well designed your package is, people will get into trouble. So any package that gets used a lot will generate some number of queries, regardless of its quality.
March 17, 2021 at 04:12 pm - Permalink
Tony, thank you for sharing your solution for this problem. It looks very nice and sufficient for the task (I would miss the shift in x, though). I hope the DiffGen project will be of use for you (and others) then. Yes, the problems and solutions of people in the community seem to be similar. Good thing, that there is a place to share. I am happy that I didn't have to come up with the ~10 projects I am using from the site (mostly your stuff, Tony). :)
By the way, I didn't know or use SpXZeigR. Must have been before my time. ;)
March 17, 2021 at 08:08 pm - Permalink
And before SpXZeigR there was technical note 020...
March 18, 2021 at 12:34 am - Permalink
Tech Note 20 still exists in all its variants. And it still works!!! But the tools you folks have been making available are far superior.
March 18, 2021 at 10:32 am - Permalink
My packages supports menu keyboard shortcuts which are loaded from a settings file. If you want to add keyboard shortcuts to common menu entries, place the content (Spectra Tools settings.dat) of the attached zip file in the same folder as the package procedure and edit as necessary.
July 27, 2023 at 11:56 pm - Permalink