I cannot figure out some problem in my code. Need help
abhi2005singh
This is the first time I am using Igor Pro. I was a origin pro user and shifted to Igor Pro as the former is very difficult (at least for me) to automate the routine tasks. Given my very less experience with any sort of programming you may find the code not very elegant, but somehow I manage my work.
I need to do the following task.
Task: There are several traces on a graph. Select a point using cursor. Write a procedure so that all the traces in the graph are scaled to that point. This procedure should also return a table of the new waves and a new graph showing the scaled graphs along with the original graph.
I have tried to do this task in various ways and have been able to do it. But, for this I had to create the table (although table is not required) of the new waves first and create the necessary graph later. Whenever I tried to graph the traces in the loop where I was creating the new waves, I was unsuccessful. Following is one of the examples of the various unsuccessful procedures I wrote to achieve the task.
Function scale2cursor()
//Get a list of waves before the execusion of the function
//This will help to know how many new waves are created after execusion
//while plotting later
//Also get the x-axis which will be treated later as a "common" axis for plotting
String ListOfWaves = wavelist("*", ";", "")
String x_axis_wave = CsrXWave(A)
//Get the name of the graph on which cursor is present
String win_name=WinName(0,1)
//This creates a name for the new table and graph that will be created by appending
//"_scale2cursor" to the name of graph on which cursor is present
String NewName=win_name+"_scale2cursor"
//Get the X- and Y-coordinates of the cursor
Variable x_val, y_val
x_val = xcsr(A)
y_val = vcsr(A)
//Get a list of traces on the graph and the total number of traces
String trace_names = TraceNameList (win_name,";",1)
Variable numbers_of_traces = ItemsInList (trace_names, ";")
//This loop will scan all the traces. Taking one trace at a time, it will scale the trace to
//the desired y-value (i. e. y_val). It will create new Y-waves also with the original wave
//appended with "_scale2cursor"
Variable index=0
Do
//Take one trace at a time and store its name in the string "trace"
String trace = StringFromList(index,trace_names,";")
//This loop will end the "Do" loop as soon as the traces are finished
if (strlen(trace)==0)
Break
endif
//Get the X wave on which cursor is present
String x_wave = XWaveName(win_name,trace)
//Creating a new wave and naming it
String outputName = trace+"_scale2cursor"
Wave output
Duplicate $trace, output
Cursor /W=$win_name A $trace x_val
Variable y_new = vcsr(A)
output=output*y_val/y_new
Rename output $outputName
if (index==0)
Edit $x_wave, $outputName as NewName
String /G table_name=WinName(0,2)
Display $outputName vs $x_wave as NewName
String /G graph_name=WinName(0,1)
else
AppendToTable /W=$table_name $outputName
AppendToGraph /W=$graph_name $outputName vs $x_wave
endif
index+=1
While (1)
KillVariables /A
End
//Get a list of waves before the execusion of the function
//This will help to know how many new waves are created after execusion
//while plotting later
//Also get the x-axis which will be treated later as a "common" axis for plotting
String ListOfWaves = wavelist("*", ";", "")
String x_axis_wave = CsrXWave(A)
//Get the name of the graph on which cursor is present
String win_name=WinName(0,1)
//This creates a name for the new table and graph that will be created by appending
//"_scale2cursor" to the name of graph on which cursor is present
String NewName=win_name+"_scale2cursor"
//Get the X- and Y-coordinates of the cursor
Variable x_val, y_val
x_val = xcsr(A)
y_val = vcsr(A)
//Get a list of traces on the graph and the total number of traces
String trace_names = TraceNameList (win_name,";",1)
Variable numbers_of_traces = ItemsInList (trace_names, ";")
//This loop will scan all the traces. Taking one trace at a time, it will scale the trace to
//the desired y-value (i. e. y_val). It will create new Y-waves also with the original wave
//appended with "_scale2cursor"
Variable index=0
Do
//Take one trace at a time and store its name in the string "trace"
String trace = StringFromList(index,trace_names,";")
//This loop will end the "Do" loop as soon as the traces are finished
if (strlen(trace)==0)
Break
endif
//Get the X wave on which cursor is present
String x_wave = XWaveName(win_name,trace)
//Creating a new wave and naming it
String outputName = trace+"_scale2cursor"
Wave output
Duplicate $trace, output
Cursor /W=$win_name A $trace x_val
Variable y_new = vcsr(A)
output=output*y_val/y_new
Rename output $outputName
if (index==0)
Edit $x_wave, $outputName as NewName
String /G table_name=WinName(0,2)
Display $outputName vs $x_wave as NewName
String /G graph_name=WinName(0,1)
else
AppendToTable /W=$table_name $outputName
AppendToGraph /W=$graph_name $outputName vs $x_wave
endif
index+=1
While (1)
KillVariables /A
End
Whenever I comment out the
Display
, part, the code runs fine (of course without the graph).I tried to find where the problem lies by running it without the loop. I found that first time the loop runs fine. But in the second loop, I get the value of y_new as
y_new=1.#QNAN
. When I send the command print y_new
, the output is NaN
. Why the command vcsr(A)
is not working is not clear to me. I have checked, the cursor A moves on the intended curve after the command Cursor /W=$win_name A $trace x_val
.I would again like to mention here that the code works fine as long as I do not try to create the new graph. Why does the creation of a new graph is affecting the readout of the cursor in spite of the fact that the cursor has moved to the right curve and in the pane below the graph the X and Y values are correct?
Few more small things I wanted to know. Please let me know how to get the X-value of the cursor in a XY plot. I wrote the above code thinking that
x_val = xcsr(A)
will return the X-coordinate. I know it doesn't work as the command is not meant for this purpose. Although it is serving the present purpose, still I want to know for future uses. And in a trace, if we know the value on the x-wave for a particular point, then how to find the y-value for that point.Any help is greatly appreciated.
Thank you
Abhinav
vcsr works on the top graph unless you specify the graph name using the optional second parameter. If the top graph does not contain the specified cursor, vcsr returns NaN (not-a-number - blank).
Use this:
instead of this:
To get the x value of an XY trace, use hcsr.
You are using String/G in two places. This creates a global variable. Unless there is some reason why the variable should be global, use String to create a local variable instead of String/G. Then you won't need KillVariables/A at the end.
Without your data I can't test it but I think I would rewrite this:
Wave output
Duplicate $trace, output
like this:
Duplicate /O $trace, $outputName
Wave output = $outputName
Then get rid of the Rename.
Your "Wave output" statement is declaring a reference to a wave named output in the current data folder. This wave will not exist at that point and if you turned on "Wave,NVAR,SVAR Checking" in the Procedure menu (after enabling debugging), the debugger would tell you that you are declaring a non-existent wave. You are saved by the fact that the Duplicate operation sets the wave reference to refer to the output wave.
You really don't want a wave named output. My version creates a wave with the correct name and then declares a wave reference to refer to it for use in subsequent commands.
I used /O after Duplicate because I don't want to get an error if I run the function twice in a row - I just want to overwrite the previously-created waves.
December 6, 2010 at 10:32 pm - Permalink
Thank you for your time and efforts.
Abhinav
December 6, 2010 at 11:02 pm - Permalink