procedure to generate a wave that would be the mean of several waves

In my experiments, I have different waves, all of them called subsequently (e.g. 0__temp, 1__temp, ...).
If I want to make the average of these waves, I have to type in a console:
duplicate 0__temp, ave__temp
ave__temp = (0__temp+1__temp+...)/"number_of_waves"


I would like to make a procedure to do this more automatically and not to type every time these lines. It should be a smart way to do it.

Thanks in advance
Thanks for your advice. It was very helpful.

But if I want to call the procedure for example like this:

average(temp)


I would need that the procedure take all the wave ending with "temp" and make the average. should it be valid this procedure to do it?

Function average(whatever_I_choose)
Wave WaveList(*_waves_to_average)
string name_of_wave = nameofwave(waves_to_average)

do
fWaveAverage(WaveList("*_waves_to_average", ";", ""), 0, 3, "$name_of_wave_ave", "")

End


Thanks in advance
Here give this one a try. Copy the following two functions to a procedure file and compile it. Then select the desired source waves in the Igor Data Browser using the shift or control/command keys, and then with these highlighted enter AverageSelected() in the command window.

At the prompt, the "Include NAN points" option will average waves even if some are missing intermediary values (ie, those set to NAN). The "Generate error wave" option computes the standard error on a per point basis for the population of waves. The function will by default move the selected source waves to a folder called "Averaged", or you can use the drop-down menu to leave them alone, delete the source waves, or move them to a custom folder name specified in the "Custom Folder" field.


Function AverageSelected()
	string selected=SelectedWaveList()
	if(itemsinlist(selected)>1)
		variable option=3
		variable truncate=2
		variable generr=1
		string newFolder
		string keystr=getdatafolder(1)[0,strlen(getdatafolder(1))-1]
		string name="waveAverage"
		prompt option, "Manage source waves:", popup, "Do nothing;Delete waves;Move waves to \"Averaged\" folder;Move waves to custom folder..."
		prompt newFolder, "Custom Folder:"
		prompt name, "Base name for average wave"
		prompt truncate, "Include NAN points?",popup,"yes;no"
		prompt generr, "Generate error wave?",popup,"yes;no"
		DoPrompt "Average Waves", name, option,newFolder,truncate,generr
	
		if(!V_Flag && itemsinlist(selected)>1)
			string avgName=UniqueName(name,1,0)
			make/n=(numpnts($stringfromlist(0,selected))) $avgName=0
			make/o/n=0 indexnans
			WAVE indexnans=$nameofwave(indexnans)
	
			WAVE avg=$avgName
			SetScale/P x 0,deltax($stringfromlist(0,selected)), stringbykey("XUNITS",waveinfo($stringfromlist(0,selected),0)), avg
	
			variable i,j
			string avgnote
			Print "Waves averaged:"
			for(i=0;i<itemsinlist(selected);i+=1)
				WAVE wavenm=$stringfromlist(i,selected)
				if(truncate==1)
					for(j=0;j<numpnts(wavenm);j+=1)
						FindValue/V=(j) indexnans
						if(numtype(wavenm[j])==2 && V_value==-1)
							insertpoints 0,1,indexnans
							indexnans[0]=j
						endif
					endfor
				endif
				avg+=wavenm
				print "     "+nameofwave(wavenm)
				//manage options
				if(option==2)
					killwaves/z wavenm
				endif
				if(option==3)
					newdatafolder/o Averaged
					//execute "ModifyBrowser expand="+num2str(GetBrowserLine(":Averaged:"))
					MoveWave wavenm, :Averaged:
				endif
			endfor
			
			avg/=itemsinlist(selected)
			
			//generate std err wave here
			if(generr==1)
				make/n=(numpnts($stringfromlist(0,selected))) $(avgName+"_err")=0
				wave err=$(avgName+"_err")
				//perform error for full wave
				for(i=0;i<itemsinlist(selected);i+=1)
					WAVE wavenm=$stringfromlist(i,selected)
					err+=(wavenm-avg)^2
				endfor
				err=sqrt(err/(itemsinlist(selected)))/sqrt(itemsinlist(selected)-1)
			endif
			
			if(truncate==1)
				variable numnans
				for(i=0;i<numpnts(indexnans);i+=1)
					numnans=0
					avg[indexnans[i]]=0
					for(j=0;j<itemsinlist(selected);j+=1)
						WAVE wavenm=$stringfromlist(j,selected)
						if(numtype(wavenm[indexnans[i]])==0)
							numnans+=1
							avg[indexnans[i]]+=wavenm[indexnans[i]]
						endif
					endfor
					avg[indexnans[i]]/=numnans
					//perform per-point error for index wave
					
					if(generr==1)
						//zero error point
						err[indexnans[i]]=0
						for(j=0;j<itemsinlist(selected);j+=1)
							WAVE wavenm=$stringfromlist(j,selected)
							if(numtype(wavenm[indexnans[i]])==0)
								numnans+=1
								err[indexnans[i]]+=(wavenm[indexnans[i]]-avg[indexnans[i]])^2
							endif
						endfor
						err[indexnans[i]]=sqrt(err[indexnans[i]]/numnans)/sqrt(numnans-1)
					endif
					
				endfor
			endif
			
			killwaves indexnans
			Print "Average wave: "+nameofwave(avg)
		endif
	else
		Abort "Select more than one wave to average."
	endif
end

Function/S SelectedWaveList() //all selected waves...
	string SelectedWaves=""
	variable i
	do
		if(waveexists($(GetBrowserSelection(i))))
			SelectedWaves+=GetBrowserSelection(i)+";"
		endif
		i+=1
	while(strlen(GetBrowserSelection(i))>0)
	return SelectedWaves
end
If you want to average all the waves in the current data folder that end in "temp", using the fWaveAverage() function, you would use something like this:

#include <Waves Average>

Function averageTempWaves(NameforNewWave)
	String NameforNewWave

	String listofwaves = WaveList("*temp", ";", "")
	fWaveAverage(listofwaves, "", 3, 1, NameforNewWave, NameforNewWave+"_STE")
end

WaveList is a function that returns a string containing a semicolon-separated list of waves that match the input criteria. The way I have written it, it lists all waves whose names end in "temp", it puts a semicolon between names, and it doesn't apply any WaveList options (that's the final empty quotes). The function takes a string as input that is used to name the output waves. It creates an average wave and a standard error wave that has the same name with "_STE" appended to the name.

If you have waves data1, data2, data3, data1temp, data2temp, and data3temp, it will list average the last three of those waves. You might invoke it like this:

averageTempWaves("myAverage")


The output will be two waves: myAverage containing the averages, and myAverage_STE containing the standard error. Of course, three inputs isn't enough to make the standard error meaningful, but you get the idea.

Or you can use the Wave Average control panel as a GUI, select by Name in the top menu, and enter "*temp" in the Name Template box.

There is a demo experiment about this package: File->Example Experiments->Ave, Box Plot, Percentile.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com