How to remove multiple instances of a wave without recursion

Hello All,

I regularly use Igor to plot a set of waves, as well as a set of fits to these wave. So, I've written a macro that uses TRACENAMELIST to get the waves on the top graph and then fit them (and update a textbox with the fit results, etc...). That way, I can add a new wave or two, and the textbox of results will contain all of the results.

In order to be simple about this, I strip all of the fits from the list and delete the textbox and basically start "from scratch" each time.

Usually, this is not a problem, but if there are 2 copies of a fit on the graph then only one gets removed. Then the macro tries to fit the fit. (Then the code crashes, and there might be another copy of a bad curve there, which just compounds the problem...)

It is easy to fix this problem by hand.
It is easy to fix this problem by writing a recursive routine.

Is there an easy way to remove all instances of a wave from a graph?

Thank you,

Sean
seanokeefe wrote:
Is there an easy way to remove all instances of a wave from a graph?


It depends on your definition of "easy" :)

Before Igor 6.20, trace names were based on the name of the underlying Y wave. So if you had a wave named myFitWave, and then displayed that several times, the traces would be named myFitWave, myFitWave#1, myFitWave#2, etc. Igor 6.20 (still in beta) introduced the possibility to give traces names that differed from the name of the underlying wave.

I think that the best way to do what you want is to use TraceNameList() to get a list of all trace names, then loop through that list and for each trace name use TraceNameToWaveRef() to get a wave reference to the wave associated with the trace. If you use XY wave pairs, you may also need to use XWaveRefFromTrace(). Then, assume that targetWave is a wave reference to the wave you are searching for on the graph, and that thisWaveRef is the wave reference returned by TraceNameToWaveRef(). You can either do
if(cmpstr(GetWavesDataFolder(targetWave, 2), GetWavesDataFolder(thisWave, 2)) == 0)
     // ... the wave references are to the same wave, so you
     // probably want to remove this trace from the graph
endif

or, if you're using the latest 6.20 beta version,
if (WaveRefsEqual(targetWave, thisWave))
     // remove the trace
endif
seanokeefe wrote:
Usually, this is not a problem, but if there are 2 copies of a fit on the graph then only one gets removed. Then the macro tries to fit the fit. (Then the code crashes, and there might be another copy of a bad curve there, which just compounds the problem...)

I forgot to mention this earlier, but if you really mean that Igor crashes, and you can reproduce it, please send us an Igor experiment with a recipe to reproduce the crash and assuming we can reproduce it we'll fix the crash if we're able to.
Hello ACLIGHT,
No, Igor doesn't crash, just the script.

Yes, the #1, #2, ... waves are the ones that I want to get rid of. If I delete one of them (by typing the name at prompt), then all of the rest are still there (reduced in index by 1).

I use the following to remove the fit waves from the wavelist. I don't really want to look at each wave, see if it is a fit wave, and then look to see if there are copies of it, and then remove them and then the original fit wave, which seemed to be your recursion approach.

    ber_names = tracenamelist("",";",1)
    ber_names = removefromlist( listmatch(ber_names,"fit_*"),ber_names)

I also use the following to remove the fit curves from the graph.

Remove_fits(listmatch(ber_names,"fit_*"))

Function Remove_fits(fit_names)
    String fit_names
    String fit
    Variable i, items
    items = itemsinlist(fit_names)
    for(i=0;i<items;i+=1)
        fit = stringfromlist(i,fit_names)
        removefromgraph $fit
        killwaves/Z $fit
    endfor
End


It seems to work now, but I kept on having problems earlier today.
The goal was to get the listmatch to give all of the matches, which should include the multiple instances, so the loop in the Remove_Fits function should pick them all off 1 by 1.
Again, now it seems to work, but earlier today it was only stripping one of each off the plot.

Sean
One of the things you might need to watch out for is that when you remove the first instance of a trace, the others change their names. So if you have

fit_wave0
fit_wave0#1
fit_wave0#2

and you remove fit_wave0, the result is that you now have

fit_wave0
fit_wave0#1

and the list of trace names is wrong- it contains a trace name "fit_wave0#2" that no longer exists, even though the one you removed was fit_wave0. My solution to problems like that is to iterate through the list backwards:

    for(i=items-1; i >= 0; i -= 1)
        fit = stringfromlist(i,fit_names)
        removefromgraph $fit
        killwaves/Z $fit
    endfor


John Weeks
WaveMetrics, Inc.
support@wavemetrics.com