Basic Help on Code

Hello all,

I am trying to automate my data analysis and am fairly new to programming in general. What I am looking to do is create a prompt to select several waves that I can do analysis on, Function CreatePrompt() below does that. Then I want to run Function DoWaveStats() and extract the ratio of two peaks from the calculated wavestats and display that on a Table. It doesn't like my code for appending the point onto a wave, I know I am missing some syntax. Any help would be appreciated!

________________________________________________
Function DoWaveStats(wave1,wave2,wave3,wave4)
String wave1,wave2,wave3,wave4
Variable/G C1, C2, C3, C4, I1, I2, I3, I4, R1, R2, R3, R4
WaveStats/R=[32,215] $wave1
I1=V_max-V_min
WaveStats/R=[330,590] $wave1
C1=V_max-V_min
R1=C1/I1
'Ratio'[0]=R1

End


Function CreatePrompt()
String wave1,wave2,wave3,wave4

Prompt wave1,"Select Wave1",popup WaveList("*",";","")
Prompt wave2,"Select Wave2",popup WaveList("*",";","")
Prompt wave3,"Select Wave3",popup WaveList("*",";","")
Prompt wave4,"Select Wave4",popup WaveList("*",";","")
DoPrompt "DoWaveStats", wave1, wave2, wave3, wave4 //Name of prompt
if (V_flag != 0)
return -1; // User canceled.
endif
DoWaveStats(wave1,wave2,wave3,wave4)
End
______________________________________________________________________
First, use Variable, not Variable/G. Variable creates local variables. Variable/G creates global variables. Global variables should be avoided and not used for temporary variables. To read about this, execute:
DisplayHelpTopic "Local Versus Global Variables"


From running your function before, you will have all of those global variables in your current data folder. You can kill them using the Data Browser (Data->Data Browser) as they are just clutter.

Second, use WaveMin and WaveMax instead of WaveStats. WaveStats calculates a large number of statistics that you don't need.

Third, Ratio is not declared in the function. If Ratio is a global wave in the current data folder then you need to declare it with:
Wave Ratio

You must declare any globals (waves or variables) before accessing them in a user-defined function. To read about this, execute:
DisplayHelpTopic "Accessing Global Variables And Waves"


If you want to append a point to Ratio:
    Wave Ratio
    Variable numPoints = numpnts(Ratio)
    Ratio[numPoints] = {R1}     // Append value

where R1 is a local variable or other numeric expression. To read about this method of appending data, execute:
DisplayHelpTopic "Lists of Values"


You could also append using InsertPoints followed by an assignment statement but the method shown above is simpler.

Having a low-level routine (DoWaveStats) access a global (the Ratio wave) is not great style as it means that the function is not self-contained. You will wind up with a whole bunch of functions that have a whole bunch on non-obvious assumptions (such as that a wave named Ratio exists in the current data folder). It would be cleaner to pass the output wave (Ratio in this case) to the DoWaveStats function as a parameter. You will still need an assumption (that Ratio exists in the current data folder) somewhere in your code but this pushes it up to a higher level and prevents the assumptions from spreading. The fewer functions that make such assumptions, the more robust the code.

Awesome, thanks a lot hrodstein for the advice. I got that bit of code to work well for me.

One more question for today. Right now I have that setup to do four waves, is there a way that if I only input two waves the other two are completely ignored? For example, if any of the waves are set as _calculated_ in the popup then they are ignored. It seems like I am going to need if, else, conditions but I fear that my code is too clunky as is.

Once again, any help is appreciated!

You are passing wave names as strings to the function. So you can pass "" and test for an empty string:
if (strlen(wave1) > 0)
 . . . Do something with wave1
endif
if (strlen(wave2) > 0)
 . . . Do something with wave2
endif


When you are dealing with waves that must already exist, as in this case, it is better to write the function to take wave references rather than wave names in strings:
Function DoWaveStats(wave1,wave2,wave3,wave4)
    Wave wave1,wave2,wave3,wave4
    if (WaveExists(wave1))
        . . . Do something with wave1
    endif
    if (WaveExists(wave2))
        . . . Do something with wave2
    endif
End


Then you can call the function like this:
DoWaveStats(wave1, wave2, $"", $"")


$"" passes a null wave reference.