Overhaul the MultiPeakFit package

It is really nice how Igor Pro has come along lately, and got more and more user-friendly. I still have to try out Igor Pro 8 (My current version is 7.08 on Win8), so apologies if some things mentioned below are already implemented or worked on. I should mention first that I use Igor for analysis and graphing of spectroscopy data, and mainly use the powerful graphing features and write mostly my own programs. But one built-in feature I use often is the MultiPeakFit2 package, which however continues to give me some headaches. I have written a huge suggestion list some years back in the forum, of which almost all points were implemented thanks to the hard work of John Weeks.

Still, I feel that this package is really, really in need of a general overhaul. Below points may read like a rant, but that’s not my intention. I really love to use Igor and all of its features, and MultiPeakFit works when taking care of its quirks. I just would love to see MPF finally getting a brush-up like the other features of Igor. To be honest, for fitting of multiple peaks in a data set I cannot fully recommend to use Igor to others, who might be less patient. MPF2 is not really what I would call user friendly in its current state.

- It is difficult to resume fits after you close the graph window:

If the fit is done then one may want to clean up the graphs from fitting many sets. Bad idea. If the graph is gone, there is almost no way to resume the same set and adjust the fit. I only way I know of is to save the graph macro upon closing (make sure to close the panel first or error messages will appear out of nowhere), note down which fit set is which data. For resuming the fit open the correct graph again and select the right data and the right settings it the ‘Start MultiPeakFit’ panel. If you mess up one step it does not work. Why not just a ‘resume set xx’ option?

- It is difficult to extract the fit results for other purposes:

While you can create a graph, see the fit parameters in a table, or report everything in a notebook, it is not obvious how to access this data on your own. It is not possible (as far as I know) to just copy the values from the table in the result window. To access the values, or the fit/peak waves for that matter, you have to dive into the packages folder and have to know what to look for. The result table is not even in an easy-to-understand format (which value is which). I just wrote a script which extracts the values for my own purposes. But how many users will do that? This goes together with the next point.

- Data clutter builds up easily:

Besides that it is very easy to ‘accidentally’ create new MPF sets which you cannot delete easily, the fit folders itself contain so much stuff that it is difficult to navigate (which you currently have to). This is multiplied with the use of checkpoints or the ‘Initialization’ function in the ‘Start MultiPeakFit’ panel which creates copies of data waves, coefficient waves and so on.

- If the fit failed badly, there is often no way back:

Sometimes the fit goes wrong and peaks end up all over the place. Then you have a problem. There is the ‘revert guesses’ button which seems to restore the peaks sometimes, but not the values in the menu. So the only hope is to manually adjust the values in the menu afterwards and pray that the fit fixes itself. Or you managed to save a checkpoint, or you save the experiment (which I do almost every minute when working with fits). It is often best to just revert the experiment and start over.

- The menu is clunky:

This starts with too small panels to show all relevant information, options ‘hidden’ at various places (I often have to explain people how to generate a graph with the result for example), almost unusable constrains options, and a less-than optimal placement of controls. Also, the fit proceeds only so far on its own. For slowly converging fits I (and other users I talk to) end up slapping the ‘Do Fit’ button many times while looking for changes in the parameters.

- Still many bugs (I only name a few off the top of my head):

The ‘current folder’ often ends up placed deeply hidden in the package substructure (especially annoying when you run your own scripts alongside), window hooks which break easily and generate error messages if you do not follow the exact right steps, the fit failing badly if something is not set up correctly with the cursors (or the constrains or the initial guess), or the possibility to select impossible combinations of settings in the ‘Start MultiPeakFit’ panel.

Thank you for reading all this. I hope my suggestions are useful to work one the code. I know you are working hard on a ton of features, so this might not be on the top of the list. I offer to give a more detailed description or prepare working examples if necessary.

I will not dispute that the package has its quirks. Thank you for your detailed criticisms.

The problem is difficult- there is potentially a huge amount of data that needs to be displayed and managed in limited space. And many different ways people want to use the results.

>>>- It is difficult to resume fits after you close the graph window:

In the Start Multi-peak Fit panel, if you choose the original data waves, you should be able to choose a set number from the Initialization menu. Perhaps not completely evident or transparent, but it seems to work.

I suppose an improvement would be a menu that allows you to choose any existing sets and simply re-open it. The naming convention for the sets makes it somewhat opaque, I admit.

>>>- It is difficult to extract the fit results for other purposes:

Good point. It is certainly something that comes up regularly. My principal difficulty with this is that I'm not sure what sort of export is desired. Would you like to share your script? Would it help to have the option to make a table with all the peak coefficient waves in it?

>>>- Data clutter builds up easily:

I'm not sure what the alternative is. I tend to keep everything because trashing anything risks throwing away something that is valuable.

>>>- If the fit failed badly, there is often no way back:

Huh. I presume that by "menu" you mean the list with peak coefficient info that can be opened and closed to reveal/hide the coefficients for the peaks. I see that clicking Revert to Guesses doesn't change the values the list. That is a bug.

Saving a checkpoint was intended as a way to return to a known good point. Does that not work for you? Of course, you have to anticipate the need. I don't know how to get around that.

>>>This starts with too small panels to show all relevant information, options ‘hidden’ at various places (I often have to explain people how to generate a graph with the result for example),

The panel can be resized to show more information in the list. The graph can also be resized. The hidden options are a compromise between presenting a bewildering number of options in a huge panel (that might not fit on small laptops) and having nothing available. I have tried to make the important controls readily available on the main panel. When you click the Results button you get a panel that has a Graph button. It's indirect, but I didn't think it was too difficult to discover. Maybe the Results button needs a better title?

>>>almost unusable constrains options

Could you elaborate on that? Designing a good interface for constraints is difficult, but I thought our solution was reasonable. It is common (I think) to want to constrain, for instance, the widths of all the peaks to some range. You can enter the lower and upper bounds in the boxes for one peak, then right-click to get the opportunity to copy that constraint to all peaks. It's hard to find that option, but it's also hard to figure out a better way to present it.

>>>and a less-than optimal placement of controls.

Please make specific suggestions.

>>>Also, the fit proceeds only so far on its own. For slowly converging fits I (and other users I talk to) end up slapping the ‘Do Fit’ button many times while looking for changes in the parameters.

A fit the fails to converge within 40 iterations is probably in trouble anyway. DisplayHelpTopic "Identifiability Problems".

I am aware of the tendency to leave the current data folder in the wrong place. I have tracked down many of those. If you can help me by identifying steps that cause it, or any other problems, I will gratefully accept your reports.


First, let me thank you for your detailed response John. I hope you do not feel offended or annoyed by my somewhat unspecific complaints. I am willing to help with the best of my abilities and as my time allows to improve MPF2. For now, I choose one or two points at a time to elaborate further and come back to others (which need more time to formulate an useful answer) later, if this is OK.

>>>- It is difficult to resume fits after you close the graph window:

My feeling is that the difficulties originate in part from the interlinking of the 3 necessary, let's call them, 'entities': the data wave(s), the associated graph and the fit set (within the packages folder). From my perspective, there should be 3 things possible: Start a new fit (set), resume a already existing fit set, or start a fit which is initialized with the peaks of another set. All three workflows only involve the selection of one or two data waves and optionally a previous fit set from a list of existing ones. Data waves could be selected automatically when resuming a previous fit set.

I feel what is too much here is the option of what to do with the graph (new graph, previous graph, this or that graph). This makes it not only necessary to have the right graph at hand (for example, to resume the desired set) it also increases the difficulty to select the right options,  which may lead to undesired behavior (e.g., 'initialization with set no. xx' creates a new fit set and copies the peak data over, when the intention was to continue an existing set). In short, the graph is too important for in the workflow. Maybe I overlook some cool possibilities here, but wouldn't it be much more straight-forward to just open a new graph every time just for the fit, do everything needed in there, and, after the result is generated, then getting rid of the whole thing? This minimizes the possibility to select an undesired option or breaking something in the workflow.

That's just a proposal from my way of doing things. Maybe leaving the current approach as is and just adding a 'resume set xx' with any graph selected (or the option 'new graph'), which let's one just continue with the same old fit set as many times as one wishes, is already the solution.

>>>- If the fit failed badly, there is often no way back:

Yes, I meant the side panel, where the values are not updated. OK, this was a bug then. Also, the button should probably be named 'revert one step' or 'revert to last input' or something along these lines. Initially I thought this button reverts to the initial guesses before any fit was done. If working as intended, this could already solve most of the problematic behavior.

And yes, there is the checkpoint option. I use this sometimes, but there were occasions when reverting to a checkpoint gave me unexpected behavior or made error messages appear (I have no examples or recent memory). I may try to play around a bit and see if I get any problems, if time allows. Actually, I have no good suggestion here how to handle this nor do I know if there is any good solution in other programs or at all. I brought it up in the list anyway.


Not annoyed- we always believe (and have for thirty years!) that listening to our customers is the best way to make Igor work the way it should. Part of my problem in regard to Multipeak Fit is that even when I was a practicing scientist (23 years ago!) I didn't do this kind of analysis. It's possible that I haven't really implemented it in the best possible way.


>>- If the fit failed badly, there is often no way back:

I have fixed the bug where clicking Revert to Guesses button fails to update the coefficient list. The fix should be in the next update to Igor 7 and 8. I think we are going to release an update to Igor 8 shortly. If you want the fix now, please contact support@wavemetrics.com.

You are right that the package views the graph as the center of workflow. Whether that is the best approach is, of course, open to debate, but it is now a fact of life. Eliminating that dependence would be a big job, requiring a major re-write of the package.

But I hear you that you would like to be able to close the graph and not suffer big consequences. If I added a way to resume a fitting session (a "fit set") what sort of UI would be desirable? Right now, the only way to look up an existing set is by the set name, which is a number, and that isn't very descriptive. The design was driven largely by the need to be able to allow the same data set to be fit in different ways. That is, a data set can be the focus of more than one set. Perhaps now that long names are allowed, I should change this to use something like "MPF2_<y wave name>_nn" where nn is a number. Or allow you to name the set? Or use a listbox of fit sets and the list would include a way to get information about a given set in the list.

Dear John, thank you for your reply and already working on MPF. I do not need updates quickly, but would appreciate if the new version would be included in a future update of Igor 7, too (as you have mentioned), as my migration to Igor 8 might take a bit. Regarding the possibility of resuming a fit, I tried to come up with a solution without (hopefully) too many changes to the program. Yes, a way to come back to a fit without leaving the MPF graph open forever would be really nice.

I tried to design a startup panel with this idea implemented (see the attachments) as a suggestion. My idea would be to add a selectable 'resume previous fit' option. Selecting this check box would make a pop-up menu visible to select one of the existing sets (and, I guess, should hide the 'From Target', 'Use Graph' and 'Initialization' options). Upon selecting a set the associated x or y waves are selected as well (if this gets too convoluted, maybe just displaying the data name for the waves used in the set within the pop-up menu would be OK). Pressing continue would then:

- bring an existing MPF graph with this set to the front, if the graph was actually open in the first place

- or create a new graph with the selected set and last fit/peaks/parameters in place

This is similar to the Initialization feature 'Previous Set for This Graph', but without have a graph at hand.

The 'resume previous fit' option could alternatively also be placed after the data selection, which would then only reveal the fit sets which include the selected x and y waves.

Regarding Still many bugs, I found a few more:

- MPF really gets many hiccups when the wave's delta scaling is negative (as is unfortunately the case for data of some commercial spectrometers). The 'BLStruct.xStart' and 'BLStruct.xEnd' get reversed at several places, for example. Actually, I am not sure if it is better to give up on that and instead display a warning message. I get a lot of headaches covering this case in my programs.

- There might actually be a bug in the graph macro saving algorithm: Closing and saving an MPF graph with the side panel still open does not work properly. When executing the graph macro the window- (and panel-) names will get jumbled up upon building the graph: The main graph window will inevitably be named MultiPeak2Panel every time. This might be caused by a wrong hierarchy of 'SetActiveSubwindow' and 'RenameWindow' in the graph macro. Of course, this will cause MPF to spit out error messages left and right.

- If there are already several peaks and a fit in the graph, then placing a cursor afterwards to constrain the region may cause erroneous behavior: The graph cursor may end up placed on the fit data or one of the peaks (without the user noticing), which makes the cursor move away with the proceeding fit. It might be safer to force the cursor on the user data all the time by some checking routine.


I do not need updates quickly, but would appreciate if the new version would be included in a future update of Igor 7, too (as you have mentioned), as my migration to Igor 8 might take a bit.

I feel compelled to let you know that we are now working on Igor 9 for potential release in a couple years... Bug fixes for Igor 7 are still being made, but it is not clear when or if we might release an update to 7. So to get the latest MPF2 for Igor 7 you should probably send a request to support@wavemetrics.com. In the past, I've often posted such updates as attachments to forum posts but I find that such attachments become magnets for people to download. After a couple of months they are out of date, but still downloaded frequently. Thus, my request to ask for it from support. Thanks!

Thanks for your suggestions for the re-start feature! I have just finished up a project to create incredible new bugs, uh, features for Igor 9; perhaps I can take some time to grant this request for MPF2. I will also be looking into your bug reports.

I'm working through the MPF2 procedure file checking all the SetDataFolder instances... there are over 130 of them. Hopefully soon I will come out the other side with procedures that don't leave you stranded in some corner of data folder space!

Awesome! I hope you do not have to do night shifts for that. :) And yes, I might send an email to the support at some point.

Regarding 'It is difficult to extract the fit results for other purposes', I have attached my little script to output a text wave from the MPF results and dumping it in the root folder. I haven't found another way to copy-paste or otherwise easily extract the values from the fit, for example, to plot the widths of all peaks (short of directly referencing the values inside the MPF folder).

It seems there is no way to copy anything from the 'Peak Results ...' table. There is the option to have a tab delimited output as notebook, which however does not seem to give me all parameters (e.g. from custom peak shapes). Also, I would have to copy the text again either in a wave or in excel to do something useful with it. My approach of generating a table gives me exactly that: A quick way to check the results without the need to have the MPF graph and panels open as well as a way to work further with the data.

By the way, this script outputs the latest results only after I have clicked 'Peak Results ...' once. I guess the values are not updated before that. I think adding a button within this panel to get a table saved somewhere will go a long way for making things easier (I already have my script, but other users may struggle). A text wave will do, since Igor is very good at working and converting text even by just copy-pasting into a numerical wave.

Regarding, almost unusable constrains options: 

I am sorry, that was a really sloppy comment. The 'Apply Constrains' and 'Hold' options are fine. What I meant was the 'Inter-Peak Constrains' option to link peak parameters. In the analysis of spectroscopy data it is very common to link, for example, the distance or height of peaks. While this is currently possible, in principle, by carefully crafting a list of parameter comparisons, in its current state it is so impractical that residing to other options (like actually writing a new peak shape with linked peaks or giving up and using other programs) is almost always better.

To make this more usable, I would suggest:

- make the use of the equal sign possible, e.g., to write 'P1K0 = P2K0 + 0.5'. Maybe a parser can run in the background to convert this to 'P1K0 > P2K0 + 0.5; P1K0 < P2K0 + 0.5;'? Actually, the equal sign is the only constrain I would ever need. Maybe other users have use cases where '>' or '<' is useful. I don't know of any.

- Have an input box next to every peak parameter (similar to the 'Min' and 'Max' boxes) for inserting commands for linking with other parameters. For example, writing '=P2K0+1' in the box for the position of peak 1 would constrain the distance between these to be always 1.

An alternative approach would be a kind of link matrix (which is shown, for example, with the press of a button), where all parameters are both listed on the row and column axes. Inserting a value other than 0 would create a link between the parameters for that specific row and column. The problem would be how to handle the distinction between *, / and +,-. Either there are two such tables (one for '*' and one for '+'), or it is handled as text and the user can write something like '+0.7' or '*2'.

I don't know how hard it is to implement, but I do know that this is a crucial feature in my field to have. I usually write a new peak shape (which also has its limits, though), but I do not know many people who are able to pull that off easily.

In reply to by chozo

Are you fitting doublets? That ability was lost in the upgrade from Multipeak Fit 1.4 to 2. Perhaps a button to add constraints for that exact purpose is called for. Are the offsets constant, or do different peak pairs have different offsets?

This is an example of my lack of actual peak fitting experience.

I will also think about what you have to say about access to the results after I have finished with re-starting a set, and reviewing the SetDataFolder commands.

Thank you so much for your effort. I am looking forward to the new shiny MPF.

I do not fit doublets (as in spin-orbit split peaks). There is a relatively large community analyzing data from standard XPS spectrometers, which however have their tools. There seems to be several add-ons for Igor specialized for this purpose, too (I know of the fitXPS, XPST and ExcentricXPS projects, which I haven't used, though). I rather want to fit spectra where some peaks should have the same height, a fixed distance (vibrational cascades), or some multiple of the width. So for me a toned down version of the constrains feature would be enough: Only +/- for positions and only * for width and height. But then the problem arises of how to to deal with custom peak shapes with unknown parameters. I guess, at least having doublets in there will make many people happy (not me). But I cannot say anything useful of how to handle this.

In reply to by chozo

Thank you for the clarification, Chozo. I will see what can be done about it. Unfortunately, right now I am sidetracked by trying to prevent Igor 8 from crashing if you try to use a Japanese input method to type into a table...

I have been working on this...

I finally got to thinking about your little script that makes a text wave that is really just a copy of the table in the Results panel. In fact, it looks exactly like the Results panel listbox.

Back when I wrote that, table subwindows didn't exist (I think). Perhaps I should just replace the present listbox with a table subwindow. That one thing that might worry me is that a table might make it too easy to alter the display of results by accident (we will assume that we aren't dealing to malicious faking of error bars :)

OK- I figured out the functionality provided by the listbox that would be lost with a table subwindow: you can click in any header in the listbox and re-sort the results based on the values in that column. By default the peaks are sorted from left to right (peak 0 to peak N-1) but you can re-sort in order of amplitude, or location uncertainty, or...

But maybe your script is the correct solution. A button in the Results panel, "Results in Table" or something like that.

I think it would be better to keep the current 'Results panel' as is and just add a button. For one, I wouldn't want to come back to this panel just for looking at/copying the results. Also, as you already mentioned, you will lose some functionality (not to mention you having more work redesigning that thing). I guess it would work Just like the Baseline-Subtracted Data button, i.e., just dumping the table (maybe with a choosable name with automatic numbering) in the folder next to the data.

Coming back to ...This starts with too small panels to show all relevant information, options ‘hidden’ at various places (I often have to explain people how to generate a graph with the result for example). What I meant by this is that the side panel is too small and not easy to navigate (in my personal opinion). I will try my best at explaining the details below.

  1. First, the panel in it's current size measures only 280 x 380 pixels or 280 x 530 pixels fully expanded (in Igor 7.08 on Win 8.1). I have attached a screenshot of the panel with some peaks added to the fit. Even though there are only 4 peaks here, and the parameters of only one peak is displayed, there is already not enough space in the list-box to fit in all peaks. Currently, the panel needs resizing every time you work with more than one peak. I understand the need to make everything fit into small laptop screens (I think there is still a bit more leeway even on a cheap 1366x768 display, though). Since high-res displays are becoming more common, wouldn't make sense to add screen size awareness or make the panel bigger by default (you could scale it down manually)?
  2. I think the help message as the bottom of the panel should be removed, as it interferes with the fitting workflow (OK, it can be switched off, but only for the current experiment). There is the Help button for that. If it is necessary to have a help like this for newcomers, maybe a short message with initial steps could be added to the startup panel.

    By the way, the Help button with its associated DisplayHelpTopic message did not work with my standard installation, since the 'Multi-peak Fitting 2 Help.ihf' apparently needs to be compiled first. Compilation is, however, prevented by the Windows Administrator settings (read-only access to the programs folder). I need to copy the help file to the user folder, compile it there and copy it back to work properly. Is there a way around this?
  3. I would pledge to have a button for generating a result graph in the main panel next to the 'Peak Results ...' button, as this makes the graphing option more obvious and quicker to access. I see no point in having this option buried inside the results table window. By the way, it seems that the 'Make Graph panel' is not multi-monitor aware. It appears always at the same position on my first monitor, even when I have Igor on the second monitor.
  4. The buttons and check-box options are a bit over the place and in cases far away from related controls. For example, do I often forget to check the 'Use Cursors' checkbox when placing cursors during the fit, since it is so far above and away from the fit button (I know, it is intended to be the first action in a fit, but in reality it is often not). Maybe the 'Use Cursors' checkbox should be automatically set when two cursors are placed on the graph and disabled when less than two cursors are present? Also, there was quite some head-scratching involved in finding out that the 'Apply Constraints' checkbox also switches the application of 'Inter-Peak Constraints' on and off. Then, I find it strange that the 'Display Peak's Full X Width' option is buried and switched of by default. Why would you not want to see the full peak? 

I tried to come up with a new layout for the MPF panel as a suggestion. Please have a look at the attachments. This may not be the optimal design, but I tried to group similar controls closer together, renamed some things, and made the overall layout more compact.