GetLastUserMenuInfo

I have created a menu using the operation of GetLastUserMenuInfo to tag certain wave.
When I have multiple waves from the same folder, It can identify the waves.
However, when I have multiple waves showing in the same graph from different folders, the operation failed.

I read the ihf and it states
The GetLastUserMenuInfo operation sets variables in the local scope to indicate the value of the last selected user-defined menu item.

Is there an operation like GetLastUserMenuInfo but can identify the waves from different folders? if not, is there a code for advancing such function?

Thanks.
Do you use the graph's trace contextual menu?
Documentation of GetLastUserMenuInfo indicates that S_traceName is set in that case. A graph and trace name uniquely identifies the concerned wave.
thomas_braun wrote:
Do you use the graph's trace contextual menu?
Documentation of GetLastUserMenuInfo indicates that S_traceName is set in that case. A graph and trace name uniquely identifies the concerned wave.


I am sorry that I don't understand the meaning of graph's trace contextual menu.

Here is the code which I tried to create a menu called "Show_Tag_All_info" to Tag waves in a graph.
I believe the graph's traces works only if there are all in the same folder.
If I create a graph macro with many waves from different folders, the following code failed to recognize the waves from other folders. (The waves would not show up in the menu)
Menu "Show_Tag_All_info", dynamic
    WaveList("*",";","Win:"), DoItem()
End
Function DoItem()
    GetLastUserMenuInfo     // sets S_value, V_value, etc.
    WAVE/Z w= $S_value
    wavestats/Q $S_value
    variable xPeak = V_maxloc
    variable xSdev = V_sdev
    variable Vskew=V_skew
    variable Vavg =V_avg
    variable Vsum =V_sum
    variable Vpoint = V_npnts
    variable Vmin=V_min
    Variable Vmax=V_max
    Variable Vminloc =V_minloc
   
    //Variable VendRow= V_endRow

        if( WaveExists(w) )
        //Tag /F=2/S=3/A=MT/X=6.42857/Y=14.346 $S_value,xPeak, "\\Z09\\ON The Xpeak \\OX"
        Print NameOfWave(w),"", xPeak,"and the SD is", xSdev, "skew value", Vskew
        String TextIt
        sprintf TextIt, "\\Z09 \\K(0,65280,0)\\ON \rresults: \rxPeak=%g, \rAvg=%g, \rSum=%g, \rVminloc=%g, \rVpoint=%g, \rSD=%g, \rVskew=%g", xPeak,Vavg,Vsum, Vminloc ,Vpoint, xSdev,Vskew
        Tag /F=2/S=3/A=MT/B=(0,0,0) /X=6.42857/Y=14.346 $S_value,xPeak, TextIt
         // TextBox/C/N=FitResults TextIt
            endif
End
Use TraceNameList instead of WaveList. Then use TraceNameToWaveRef and XWaveRefFromTrace functions to get wave references to the waves. The wave references don't care if the waves are in different data folders, and the trace names are unique on the graph. WaveList, as you have found, only returns names of waves in the current data folder, and a simple name isn't sufficient to connect to a wave outside the current data folder.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
Use TraceNameList instead of WaveList. Then use TraceNameToWaveRef and XWaveRefFromTrace functions to get wave references to the waves. The wave references don't care if the waves are in different data folders, and the trace names are unique on the graph. WaveList, as you have found, only returns names of waves in the current data folder, and a simple name isn't sufficient to connect to a wave outside the current data folder.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com



Thanks for the tip! I did some searches in the forum and found similar code, and it worked.
However, I have one minor issue. In my previous function, I can click on a wave to create a tag for the wave.
With the following code, it just tags all the waves in macro graph. How do I make a code for the tagging selective wave?
I believe it is because of index +=1
But I dont't know how to modify it.
Menu "TagAll", dynamic
     TraceNameList ("",";",1), TagAll()
End

Function TagAll()

    String list = TraceNameList("", ";", 1)
    String traceName
    Variable index = 0
    do
        traceName = StringFromList(index, list)
        if (strlen(traceName) == 0)
        break // No more traces.
    endif
        WAVE w = TraceNameToWaveRef("", traceName)
         wavestats/Q w
        variable xPeak = V_maxloc
       
    Print NameOfWave(w),"", xPeak
    GetLastUserMenuInfo
        String TextIt
        sprintf TextIt, "\\Z09 \\K(0,65280,0)\\ON\rxPeak=%g", xPeak
        Tag /F=2/S=3/A=MT/B=(0,0,0) /X=6.42857/Y=14.346 $s_value,xPeak, TextIt
    //  Smooth 5, w
        index += 1
    while(1)

End
Yes, you've written a loop that tags all the traces in the top graph. But you just need to use the technique you used previously, but for trace names instead of wave names. Factor out the code inside the loop that works on a single trace and make it a function by itself, taking a string input containing the trace name. You actually did the hard part yourself! Like this:
Menu "TagAll", dynamic
    TraceNameList ("",";",1), DoItem()
End

Function DoItem()
    GetLastUserMenuInfo     // sets S_value, V_value, etc.
    TagATrace(S_value)
end
 
Function TagATrace(tracename)
    String tracename
   
    WAVE w = TraceNameToWaveRef("", traceName)
    wavestats/Q w
    variable xPeak = V_maxloc
 
    Print NameOfWave(w),"", xPeak
    String TextIt
    sprintf TextIt, "\\Z09 \\K(0,65280,0)\\ON\rxPeak=%g", xPeak
    Tag /F=2/S=3/A=MT/B=(0,0,0) /X=6.42857/Y=14.346 $s_value,xPeak, TextIt
    //  Smooth 5, w
end

Function TagAll()
    String list = TraceNameList("", ";", 1)
    String traceName
    Variable index = 0
    do
        traceName = StringFromList(index, list)
        if (strlen(traceName) == 0)
            break // No more traces.
        endif
        TagATrace(traceName)
        index += 1
    while(1)
end

I've included a new TagAll function just to show how it would work with the re-factored code. But you don't really need it.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com

NOTE in edit: I just noticed that I left a useless GetLastUserMenuInfo in the TagATrace function.
johnweeks wrote:
Yes, you've written a loop that tags all the traces in the top graph. But you just need to use the technique you used previously, but for trace names instead of wave names. Factor out the code inside the loop that works on a single trace and make it a function by itself, taking a string input containing the trace name. You actually did the hard part yourself! Like this:
Menu "TagAll", dynamic
    TraceNameList ("",";",1), DoItem()
End

Function DoItem()
    GetLastUserMenuInfo     // sets S_value, V_value, etc.
    TagATrace(S_value)
end
 
Function TagATrace(tracename)
    String tracename
   
    WAVE w = TraceNameToWaveRef("", traceName)
    wavestats/Q w
    variable xPeak = V_maxloc
 
    Print NameOfWave(w),"", xPeak
    GetLastUserMenuInfo
    String TextIt
    sprintf TextIt, "\\Z09 \\K(0,65280,0)\\ON\rxPeak=%g", xPeak
    Tag /F=2/S=3/A=MT/B=(0,0,0) /X=6.42857/Y=14.346 $s_value,xPeak, TextIt
    //  Smooth 5, w
end

Function TagAll()
    String list = TraceNameList("", ";", 1)
    String traceName
    Variable index = 0
    do
        traceName = StringFromList(index, list)
        if (strlen(traceName) == 0)
            break // No more traces.
        endif
        TagATrace(traceName)
        index += 1
    while(1)
end

I've included a new TagAll function just to show how it would work with the re-factored code. But you don't really need it.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com


Great! Thank you for being so patient with me!