Programatically calculating average

So I have many waves, aptly named wave1, wave 2, so on and so on. I created a panel that has a button I can press to calculate the average of many waves that I want to, based on what files I want. Here is how I am trying to do this:

Function ButtonProc_average(ba2) : ButtonControl
    Struct WMButtonAction &ba2
    NVAR npoints1=root:npoints1

    variable startindex,endindex
    Switch( ba2.eventcode )
        Case 2:
        Prompt startindex, "First File Number"
        Prompt endindex, "Last File Number"
        KillWaves averagewave
        Make/N=(npoints1) averagewave
        Variable i
        SVAR wavei
        Wave testwave
        For (i=startindex; i<=endindex; i+=1)
            sprintf datai, "%s%d", "wave", i
            averagewave = averagewave + datai
        Endfor
        Break
case -1:
break
EndSwitch
Return 0


When I hit the button, I get **a wave read gave error: Attempt to operate on a null (missing) wave
I would suggest to debug your procedure this way.

* Create a function that does what you want without a UI panel.
* Test and debug that function completely.
* Build a UI action call to that function.

So, you should code your function this way ...

Function DoMyAveraging()

    NVAR npoints1=root:npoints1
   
    variable startindex, endindex, ic
    string wavei
   
    Prompt startindex, "First File Number"
    Prompt endindex, "Last File Number"
   
    Make/O/N=(npoints1) averagewave=0
   
    // possible method to average a set of waves
   
    for (ic=startindex;ic<(endindex+1);ic+=1)
        sprintf wavei, "wave%d", ic
        wave thiswave = $wavei
        WaveStats/Q/M=0 thiswave
        averagewave[startindex-ic] = V_avg
    endfor
   
    return 0
end

Function ButtonProc_average(ba2) : ButtonControl
    Struct WMButtonAction &ba2
 
    switch( ba2.eventcode )
        case 2:
            DoMyAveraging()
            break
        case -1:
            break
    endswitch
    return 0
end


Once you have written the function for DoMyAveraging and get it to work from the command line (type "DoMyAveraging()" on the command line), then your button call will work.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
I believe there are many errors with your original code; however, I'm not that familiar with panels so don't want to dive in too deep. JJ's code is probably a better starting point.

Just wanted to point out that there's already a pretty full-featured panel to average waves under the menu Analysis - Packages - Average Wave.
@jjweimer

When I run something like what you say with the commands
wave thiswave = $wavei
WaveStats/Q/M=0 thiswave

I get an error that WaveStats gave error: expected wave name, even though I clearly declare it a line before.
Additionally, I am not looking for the average of a wave, I want to view the average wave of multiple waves (wave1+wave2+.../N), so the average wave panel is nice, but I want it to be so that I can create a running average eventually.
You might need to check whether the string name "waveN" actually refers to an existing wave in the current data folder. Check the help for the command WaveExists. Are you running the function in the folder where your waves are stored?

The commands to average waves as you propose might be as such

// assumes wave0 exists in the current folder

duplicate/O wave0 waveave
waveave = 0
for (ic ...)
    ...
    waveave += thiswave
endfor
waveave /= (endindex - startindex + 1)


Faster but less explicitly-intuitive versions of the code you want could eventually be designed with MatrixOp.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
jmas340 wrote:
Additionally, I am not looking for the average of a wave, I want to view the average wave of multiple waves (wave1+wave2+.../N), so the average wave panel is nice, but I want it to be so that I can create a running average eventually.


I think you misunderstand the function of the "average waves" panel (sorry, I left off the "s" in my above comment). It does a point-by-point average of multiple waves, returning an averaged wave. What's more, you can programmatically call the underlying code by including the package and using the function fWaveAverage():
#include <Waves Average>

function easyAverage()
    wave wave1,wave2,wave3
    fWaveAverage("wave1;wave2;wave3", "", 0,0,"AveWave","")
end


You could programmatically make the list "wave1;wave2;wave3" to make the running average of whatever # suffixes you want. There's more detail on how to use all of this on the "Help" button in the Waves Average panel.
jmas340 wrote:
Additionally, I am not looking for the average of a wave, I want to view the average wave of multiple waves (wave1+wave2+.../N), so the average wave panel is nice, but I want it to be so that I can create a running average eventually.


You can use the Average Waves code to do this. If you include the panel in your procedure you can make a call to it from your code. You can do this as many times as you need. The advantage is that this is one line and the WaveMetrics code is bomb proof compared to something you will write yourself.