Wave keeps overwriting itself in do loop.

Hi, fairly new to IGOR programming. This has been bugging me for days. I am loading multiple similar files, plotting, then doing a simple calculation on each wave to create a new wave, all within a do loop. All the loaded waves behave sensibly. However the wave that I create to do the calculations on (wave w3 = $wnameEACF) keeps overwriting rather than generating a new wave for each file. I can't work out why this wave is different to the loaded waves.

Any help much appreciated. thanks Gary

 

 

--


 

 

Loaded waves are fine waves that I have done calculations on are overwritten Procedure file (3.7 KB) Example data files (25.96 KB)
function load_DLS_ALV_New()
    variable i=0

 
    variable /G points
    string wnameIACF, fname, wnameTau, wnameEACF, wStr, wnameParam, mystring
    string Tau = "_Tau", EACF="_EACF", IACF="_IACF", Param="_Param"    //wave names
    getfilefolderinfo/D
    newpath/O cgms S_path
    string filelist= indexedfile(cgms,-1,".asc")
    Display/W=(0,0,340,280);
    Display/W=(440,0,780,280);

 
    do
        fname = stringfromlist(i,filelist)
        wnameTau = fname[0,strlen(fname)-5]+Tau
        wnameIACF = fname[0,strlen(fname)-5]+IACF
        wnameParam = fname[0,strlen(fname)-5]+Param
        wnameEACF = fname[0,strlen(fname)-5]+EACF

 
        wave w0 = $wnameTau
        wave w1 = $wnameIACF
        wave w2 = $wnameParam
        wave w3 = $wnameEACF

 
            //print num2str(round(10*w2[4])/10)

 

 
        if (!waveexists(w))
            LoadWave/J/D/A=wave/P=cgms/K=0 /L={0,27,231,0,1} stringfromlist(i,filelist)
            LoadWave/J/D/A=wave/P=cgms/K=0 /L={0,27,231,1,1} stringfromlist(i,filelist)
            LoadWave/J/D/A=wave/P=cgms/K=0 /L={0,14,10,1,1} stringfromlist(i,filelist)

 
            //Calculate EACFs
            Duplicate/O wave1 wave3
            wave3/=mean(wave1,20,40) //Do calculation

 
            //print wave3

 
            rename wave0 $wnameTau
            rename wave1 $wnameIACF
            rename wave2 $wnameParam
            rename wave3 $wnameEACF

 
            AppendToGraph/W=Graph0 $wnameIACF vs $wnameTau
            AppendToGraph/W=Graph1 $wnameEACF vs $wnameTau

 
        else
            print   fname+" was previously loaded. Its corresponding wave exists."
        endif

 

 
        i += 1          //move to next file
        print i

 
    while(i<itemsinlist(filelist))          //end when all files are processed.
        ModifyGraph/W=Graph0 log(bottom)=1
        ModifyGraph/W=Graph0 width=340,height=280
        ModifyGraph/W=Graph0/Z lSize=2
        ModifyGraph/W=Graph0/Z rgb[0]=(3,52428,1),rgb[1]=(0,0,0),rgb[2]=(1,16019,65535),rgb[4]=(65535,49157,16385)
        ModifyGraph/W=Graph0/Z rgb[5]=(0,43690,65535),rgb[6]=(65535,16385,55749),rgb[7]=(1,39321,39321)
        ModifyGraph/W=Graph0/Z rgb[8]=(39321,26208,1),rgb[9]=(2,39321,1),rgb[10]=(65535,65532,16385)
        ModifyGraph/W=Graph0/Z rgb[11]=(36873,14755,58982)
        ModifyGraph/W=Graph0/Z tick=2
        ModifyGraph/W=Graph0/Z zero(left)=0
        ModifyGraph/W=Graph0/Z mirror=1
        ModifyGraph/W=Graph0/Z minor=1
        ModifyGraph/W=Graph0/Z sep=10
        ModifyGraph/W=Graph0/Z fSize=14
        ModifyGraph/W=Graph0/Z lblMargin(left)=18
        ModifyGraph/W=Graph0/Z axThick=1.5
        ModifyGraph/W=Graph0/Z gridRGB(left)=(21845,21845,21845)
        ModifyGraph/W=Graph0/Z notation(left)=1
        ModifyGraph/W=Graph0/Z gridHair(left)=1
        ModifyGraph/W=Graph0/Z lblLatPos(left)=-12
        Label/W=Graph0/Z left "\\Z16 IACF"
        Label/W=Graph0/Z bottom "\\Z16 Delay time [ms]"
        Legend/W=Graph0/C/N=text0/F=0/A=MC     
        ModifyGraph/W=Graph0 btLen=4

 
        ModifyGraph/W=Graph1 log(bottom)=1
        ModifyGraph/W=Graph1 width=340,height=280
        ModifyGraph/W=Graph1/Z lSize=2
        ModifyGraph/W=Graph1/Z rgb[0]=(3,52428,1),rgb[1]=(0,0,0),rgb[2]=(1,16019,65535),rgb[4]=(65535,49157,16385)
        ModifyGraph/W=Graph1/Z rgb[5]=(0,43690,65535),rgb[6]=(65535,16385,55749),rgb[7]=(1,39321,39321)
        ModifyGraph/W=Graph1/Z rgb[8]=(39321,26208,1),rgb[9]=(2,39321,1),rgb[10]=(65535,65532,16385)
        ModifyGraph/W=Graph1/Z rgb[11]=(36873,14755,58982)
        ModifyGraph/W=Graph1/Z tick=2
        ModifyGraph/W=Graph1/Z zero(left)=0
        ModifyGraph/W=Graph1/Z mirror=1
        ModifyGraph/W=Graph1/Z minor=1
        ModifyGraph/W=Graph1/Z sep=10
        ModifyGraph/W=Graph1/Z fSize=14
        ModifyGraph/W=Graph1/Z lblMargin(left)=18
        ModifyGraph/W=Graph1/Z axThick=1.5
        ModifyGraph/W=Graph1/Z gridRGB(left)=(21845,21845,21845)
        ModifyGraph/W=Graph1/Z notation(left)=1
        ModifyGraph/W=Graph1/Z gridHair(left)=1
        ModifyGraph/W=Graph1/Z lblLatPos(left)=-12
        Label/W=Graph1/Z left "\\Z16 ISF"
        Label/W=Graph1/Z bottom "\\Z16 Delay time [ms]"
        Legend/C/N=text0/F=0/A=MC      
        ModifyGraph/W=Graph1 btLen=4                   
end

 

 

Hello, thanks for uploading the code and files. It made this easier to troubleshoot.

The problem is that when you Duplicate wave1 to give wave3, a reference is made to wave3 so that although you rename the wave, you get the strange behaviour you are seeing. If you add

WaveClear wave3

Immediately after you rename all three waves, you get what is I think the desired graph.

I would do this a bit differently and use the desired name string for the Duplicate step and then declare that name as wave3, then do your calculation, and don't rename wave3 i.e.

            //Calculate EACFs
            Duplicate/O wave1 $wnameEACF
            Wave wave3 = $wnameEACF
            wave3/=mean(wave1,20,40) //Do calculation
           
            //print wave3
           
            rename wave0 $wnameTau
            rename wave1 $wnameIACF
            rename wave2 $wnameParam
           
            AppendToGraph/W=Graph0 $wnameIACF vs $wnameTau
            AppendToGraph/W=Graph1 $wnameEACF vs $wnameTau

or just name the waves directly upon loading to get rid of rename altogether.

While I'm here, I'll also say that the if statement (if (!WaveExists(w)) doesn't seem to do anything because there is no wave w.

Thanks very much sjr51, that is a great help and also helps me to simplify my code. I have another couple of questions if I may:

1) Why do certain commands with waves work in the command line but not within a function? For example in the current example, I have the waves DLS0000_IACF, DLS0001_IACF, DLS0002_IACF loaded and I would like to average them. The following commands work on the command line, but not within a function:

make/N=(numpnts(DLS0000_EACF)) wave9
wave9 = (DLS0000_EACF + DLS0001_EACF + DLS0002_EACF)/3

It gives an error "unknown/inappropriate name or symbol" for the wave name DLS0000_EACF. There must be some way of referencing these waves in memory but it eludes me.

2) How can I extract 1 parameter from a file, convert it to a string and then use it to name a wave?

num2str(wave6[4]) - I presume this will take the 4th element from wave6 and convert to a string.
How can I then rename an existing wave with this new string?

 

Thanks

Gary

 

1) Check the Data Browser. Where are the waves DSL... located? Are they in the folder where wave9 is located? Are you "pointing to" that folder (i.e. will your command line inputs operate on the folder where the waves are all located)?

2) With this approach

string wnstr
sprintf wnstr,"MyNewWave_%d", wave6[4]

 

You say the waves are DLS0000_IACF ... but you try with DLS0000_EACF. Is this a typo? Also, you want to do this ...

make/N=(numpnts(...))/D ...

The /D flag assures that you have double precision.

I also imagine that a MatrixOP command would do the average and avoid needing to create the wave explicitly.

MatrixOP/O wave9 = (DLS... + ... + ...)/3

 

 

If we see the relevant code section (or attach the full code in a file), then we can help more effectively. But regarding your point 1, I suspect that you did not declare the DLS000XX waves with a Wave statement before using them inside the function. The function code simply does not know what these 'names' are unless you explicitly declare things. The command line code just assumes you mean waves in the currently selected folder. But before you hardcode these names into your function you may want to learn about ways to source waves dynamically. A good start would be to look up the functions WaveList(), StringFromList() or alternatively CountObjectsDFR() and GetIndexedObjNameDFR().

Thanks

JJWeimer there are several waves with similar names all with the same problems. Could not get the Matrix command to work.

Chozo, Attached is the procedure as it currently stands and the data. I want to then be able to manipulate the named waves (DLS000_XXX) which are in memory but don't know how to give them names.

 

thanks

The way to do this is to make a string with the wave name. Make a wave reference. Use that reference to manipulate the wave.

In your original example, if the data is already loaded and named:

// an example to make the wave name
wnameTau = fname[0,strlen(fname)-5]+Tau

// make wave reference
wave w0 = $wnameTau

// manipulate wave
w0 *= 1000 //or whatever

Now if you have already loaded the data, you don't want to mess around with fname again, so chozo's suggestion of using WaveList is a good one.

// find all waves ending _IACF in the current data folder
String wList = WaveList("*_IACF",";","")

// write a loop to work on each one, doing something like
for(i = 0; i < ItemsInList(wList); i += 1)
    // find wave name
    wName = StringFromList(i, wList)
    // make wave reference
    Wave w = $wName
    // manipulation
    w *= 1000
endfor

As an example, since you would have one DLSXXX_IACF for each dataset, you can use this directly or use wList to find the related waves that you loaded from that dataset to do things with them too. Same principle applies, make a wave reference to manipulate them.

Attached is a modified and commented version of your code with a few simplifications and robustness improvements. You do not seem to use a few variables and strings => I have removed them for clarity. Also, the bulk of your code seems to be applying graph styles. I found the only difference for both graphs is the left axis label. It is better to have a general graph style which you can apply in your code to any graph. Also, it is a bit dangerous to use do-while loops, since in the worst case you PC hangs forever if you screw up the end condition. Rather use for-loops unless you get a real benefit from do-while loops (e.g., dynamic end condition). Other detailed comments are in the file. Just write again if something is unclear or you have further questions.

Test_procedure_new.ipf (3.52 KB)

Thanks all, finally had time to get back to this. Chozo the code is a fantastic help, thanks. sjr51 I will work through these and post follow up questions if anything is unclear.

 

Thanks again for your help.