How to make a pop-up menu list graph
awash
Hello! I am a new user to Igor and I am currently trying to code a program that will create a pop-up menu that will graph a selected wave from a loaded Excel file. I need help graphing what is selected in the pop-up menu. I do not know how to make the pop-up menu control select the desired wave. Also, I need to reference the wave through order of being loaded in or by the number in the wave name (the number is at the end of the wave name). Some assistance would be appreciated!
function PopMenuProc(pa) : PopupMenuControl
STRUCT WMPopupAction &pa
switch(pa.eventCode)
case 2:
Variable popNum = pa.popNum // 1 - based item number
String popStr = pa.popStr // text of selected item
if (!cmpstr(popStr,"1_txt")) // if wave names include 1, then the following will happen
wave /z Time__seconds_ // time_seconds wave is always referenced
wave /z AKAP_yfp_Orai11_mcherry_untagSTIM1_rest_1_txt
Display AKAP_yfp_Orai11_mcherry_untagSTIM1_rest_1_txt vs Time__seconds_
CurveFit/M=2/W=0 dblexp_XOffset, AKAP_yfp_Orai11_mcherry_untagSTIM1_rest_1_txt/X=Time__seconds_/D
endif
break
case -1:
break //control being killed
endswitch
return 0
end
STRUCT WMPopupAction &pa
switch(pa.eventCode)
case 2:
Variable popNum = pa.popNum // 1 - based item number
String popStr = pa.popStr // text of selected item
if (!cmpstr(popStr,"1_txt")) // if wave names include 1, then the following will happen
wave /z Time__seconds_ // time_seconds wave is always referenced
wave /z AKAP_yfp_Orai11_mcherry_untagSTIM1_rest_1_txt
Display AKAP_yfp_Orai11_mcherry_untagSTIM1_rest_1_txt vs Time__seconds_
CurveFit/M=2/W=0 dblexp_XOffset, AKAP_yfp_Orai11_mcherry_untagSTIM1_rest_1_txt/X=Time__seconds_/D
endif
break
case -1:
break //control being killed
endswitch
return 0
end
First, it is important to know what will be the contents you select with your popup? Is it a wave from a list in the current folder (i.e., something you would get from WaveList())? Then the first part is very easy: Just use
Wave selection = $pa.popStr
This will convert the selected item (text) into a wave reference. If the selection is something else, then you need to explain first how your data is organized, what the popup selection should do and how one could possibly know about the wave from the selection (e.g., if your popup selects numbers which will be part of the wave name then one just needs to construct the name from the number).
Second part of your question:
June 15, 2022 at 06:40 pm - Permalink
Thank you so much for your help! The suggested code worked great. However, I have another issue.
If the user selects No, indicating they want to change the start/stop point, I want them to be able to use ShowInfo to manipulate the points. I also wanted to prompt the user to select their desired start/stop point (Start will always be 50 but stop can change). This desired stop point is B_value. My problem is that when the prompt shows up after the graph, the graph window can no longer be selected. I want the user to be able to interact with both the graph window and the prompt so that once they play around with different stop points, they can enter their desired stop point and it will be curve fitted.
DoAlert /T="Start/Stop Point", 1, "Are you satisfied with this start/stop point?"
if(V_Flag==1)
CurveFit/M=2/W=0 dblexp_XOffset, selection [50,389]/X=Time__seconds_[50,389]/D
DoUpdate
endif
if(V_Flag==2)
ShowInfo
PauseforUser/C Graph0
Prompt B_value, "Enter the desired stop point"
DoPrompt "Enter_Stop_Point", B_value
CurveFit/M=2/W=0 dblexp_XOffset, selection [50,B_value]/X=Time__seconds_[50,B_value]/D
DoUpdate
endif
June 17, 2022 at 01:15 pm - Permalink
You need a panel as the "main" window for PauseForUser, such that when your user clicks the Done button in the panel, the panel commits suicide and that releases the PauseForUser. Having your graph as the second target of PauseForUser will leave the graph's UI still working. See the example in DisplayHelpTopic "PauseForUser Simple Cursor Example". It is almost exactly what you are trying to put together.
June 17, 2022 at 03:16 pm - Permalink
Here is an example for inspiration if you are looking for browsing through a series of waves instead of creating permanent graphs for each wave. Rolling your mouse wheel over the popup menu will scroll through the list of waves and display them in the graph.
// Creates a graph with a popup menu used to display the waves in the active datafolder
// Sets root: as the active datafolder
SetDataFolder root:
// Creates three waves to chose from
Make/O/N=100 root:Peter=sin(2*pi*p/100), root:Paul=cos(2*pi*p/100), root:Mary=2*sin(2*pi*p/20)
// Creates the wave to display in the graph. It is created in a different datafolder to avoid having it show up as a selection in the popup menu
NewDataFolder/O root:MyFolder
DFREF MyFolder=root:MyFolder
Make/O/N=0 MyFolder:DisplayedWave/WAVE=DisplayedWave
// Creates the graph window
DoWindow/K MyGraph
Display/K=1/N=MyGraph DisplayedWave
// Creates a bit of white empty space at the top of the graph for the popup menu
ModifyGraph /W=MyGraph margin(top)=30
// Creates the popup menu with the list of waves to display
// The WaveList call returns a semi-colon seperated list of all one-dimensional numeric waves in the active datafolder
PopupMenu MyPopUp bodyWidth=100, pos={80, 5}, mode=1, proc=MyPopUpProc, value=WaveList("*", ";", "DIMS:1,DF:0,CMPLX:0,TEXT:0,WAVE:0"), win=MyGraph
// Updates the graph with the selected wave
MyUpdateFunction()
end
Function MyPopUpProc(PU_Struct) : PopupMenuControl
// Updates the graph with the selected wave
STRUCT WMPopupAction &PU_Struct
// If the selection was changed
if (PU_Struct.eventCode==2)
// Updates the graph with the selected wave
MyUpdateFunction()
endif
end
Function MyUpdateFunction()
// Updates the graph with the wave selected in the popup menu
// The location of the displayed wave
DFREF MyFolder=root:MyFolder
// Finds the selected text in the popup menu
ControlInfo /W=MyGraph MyPopUp
String SelectedStr=S_Value
// Finds the name of the wave to display
Wave/Z SelectedWave=$SelectedStr
// Checks if the selection is valid
if (WaveExists(SelectedWave))
// Overwrites the displayed wave with the selected wave
Duplicate/O SelectedWave MyFolder:DisplayedWave
else
// Clear the display if the selected wave does not exist
Make/O/N=0 MyFolder:DisplayedWave
endif
end
June 18, 2022 at 07:30 am - Permalink
In reply to You need a panel as the … by johnweeks
Thanks for your suggestion! The example was exactly what I needed. The very last part of my code involves using FindRoots and I have been having some issues with it. Using the dlbexp equation from CurveFit, I was trying to solve for x. In order to do that I tried using FindRoots. Before using the actual command, I followed the "Function Format for Systems of Multivariate Functions" example under "FindRoots" in Igor Reference and keep running into the same error that says "While executing a wave read, the following error occurred: Index out of range for wave "coefs". The code compiles but it does not run correctly.
I'd really appreciate some assistance with this because FindRoots is a very confusing command for me.
wave /z w_coef
variable y0 // define variables from w_coef wave
y0 = W_coef[0]
variable A1
A1 = W_coef[1]
variable tau1
tau1 = W_coef[2]
variable A2
A2 = W_coef[3]
variable tau2
tau2 = W_coef[4]
variable x0
x0 = 13.215
function Y_half_calc(w_coef,x)
wave /z w_coef
variable x
return W_coef[0] + W_coef[1]*exp(-(x-13.215)/W_coef[2]) + W_coef[3]*exp(-(x-13.215)/W_coef[4])
Make/D/O Y_half_coefs={0, 1, 2, .5} // an offset by 0.5
Make/D/O Y_half_wave // a wave with 128 points // give it an X range of (-10, 10)??
SetScale/I x -100,100,Y_half_wave
Y_half_wave = Y_half_calc(Y_half_coefs, x) // fill it with function values
Display Y_half_wave // and make a graph of it
ModifyGraph zero(left)=1 // add a zero line to show the roots
ModifyGraph minor(bottom)=1 // add minor ticks to the graph
end
June 22, 2022 at 01:49 pm - Permalink
In reply to Thanks for your suggestion!… by awash
Also, I wanted to find a way to graph the curve fit of the selected wave in the pop-up menu. I feel like it involves something with $ but I wanted assistance figuring it out
June 23, 2022 at 08:29 am - Permalink
That piece of code is very strange. You have a function Y_half_calc that's calling itself over and over again for every point in Y_half_wave, and for every call a new graph is created. I have no idea what you are trying to accomplish with the code to be honest.
June 23, 2022 at 09:45 am - Permalink
PS
Never use "x" as a variable. Igor uses x as the x-value of point p in a wave
June 23, 2022 at 09:47 am - Permalink
In reply to That piece of code is very… by olelytken
I was trying to find solve for x in the double exponential offset equation. When I searched for a way to do this, I was directed to FindRoots. Under Command Help, FindRoots has an example called "Function Format for Systems of Multivariate Functions". I loosely followed that example and what is shown above is from that example, including using x as a variable.
What I am trying to use the code for is finding the halfway point between the end of my curve-fitted graph and the end of it. I found that solving the double exp offset equation would give me this value.
Update:
I am no longer trying to use FindRoots for this equation. I am nearing the last part of my code but need assistance. I used CTRL+I to ShowInfo on my graph. There are number points, and an x and y value for each point. I want to be able to reference these points and have the graph find the number point that is closest to a specific Y value I want. I also want it to print the shown x value for the number point. I just don't know how to reference them.
June 23, 2022 at 10:15 am - Permalink
To your last Update question, to find values for cursors on a trace, look to functions such as xcsr and pcsr. The CsrWave function, which returns the name of the wave the cursor is on, may be of use as well.
June 25, 2022 at 02:58 pm - Permalink
I looked into using these commands so I'm glad to know my thoughts were in the right place. I have another question. Is it possible to accurately use BinarySearch to search for a wave that has a value with $ in it?
June 27, 2022 at 06:52 am - Permalink
What do you mean? BinarySearch() looks for numerical expressions in numerical waves. It is not possible for such a wave to contain the '$' character.
June 27, 2022 at 08:32 am - Permalink
In reply to What do you mean?… by chozo
I just figured it out a few minutes ago but I was referring to a wave that has a value that has the $ character. For example " wave selection = $pa.popStr ". I wanted to know if the wave "selection" could be used with BinarySearch() to search for the wave for a numerical expression. I was able to get it to work.
Now that I have done this, I need to reference a _calculated_ wave. Is this possible?
June 27, 2022 at 08:41 am - Permalink
In reply to I just figured it out a few… by awash
If I understand it correctly, _calculated_ is simply x scaling of the original wave.
June 27, 2022 at 09:16 am - Permalink
In reply to If I understand it correctly… by ilavsky
I tried using the x scaling for my original wave but the values are off. The x scaling for the curve is Time__seconds_[50, b_value] and the x for the original wave is Time__seconds_. The variable b_value is the end-point of the x-scaling. Is there a way to put the x-scaling in the wave reference to Time__seconds?
Update:
I ended up just using pnt2x since I had my desired point number for the curve fit graph. Much thanks to everyone that's helped me with me code. I really appreciate the assistance and patience while I've been learning Igor.
June 27, 2022 at 10:02 am - Permalink