I cannot figure out some problem in my code. Need help

Dear all,
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


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
You're off to a good start as far as Igor programming goes!

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:
Variable y_new = vcsr(A,win_name)

instead of this:
Variable y_new = vcsr(A)


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:
String outputName = trace+"_scale2cursor"
Wave output
Duplicate $trace, output

like this:
String outputName = trace+"_scale2cursor"
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.


It worked perfectly fine and the way I wanted. It was good to get some programming tips which can save lot of my time in future. I am not very much aware of the details of programming techniques, so such things happen to me.


Thank you for your time and efforts.
Abhinav