How to access and save individual wave from TraceNameToWaveRef("", traceName)
| June 18, 2012 - 08:18 | |||
|---|---|---|---|
|
The obvious straightforward method: Function test() String list = TraceNameList("", ";", 1) String traceName Variable index = 0 traceName = StringFromList(0, list) if (strlen(traceName) == 0) DoAlert 0, "No YW1" return -1 endif wave yw1 = TraceNameToWaveRef("", traceName) wave xw1 = XWaveRefFromTrace("", traceName) traceName = StringFromList(1, list) if (strlen(traceName) == 0) DoAlert 0, "No YW2" return -1 endif wave yw2 = TraceNameToWaveRef("", traceName) wave xw2 = XWaveRefFromTrace("", traceName) index += 1 // probably need to make this more general... Duplicate/O yw1, MyNewWave // Want to do the subtraction MyNewWave=yw2-yw1 end If you *really* want a loop, you will need to make a wave wave (look up the Make command and read about Make/WAVE). In the loop, fill in the wave wave with references to the waves you want. By the way, the second igor tag needed to be slash-igor to close the code segment. John Weeks |
|||
| supra | June 18, 2012 - 12:03 | ||
|---|---|---|---|
|
|
|||
| proland | June 18, 2012 - 12:56 | ||
|---|---|---|---|
|
For the case of when the x-waves are different, you need to take the maximum and minimum values into consideration. For instance if xw1 goes from 1-40 and xw2 goes from 10-50, you cant subtract the y values which correspond to x values 1-9, or 41-50 (you can only subtract two numbers if they exist). This can be accomplished by only subtracting from max(xw1[0],xw2[0]) to min(xw1[inf],xw2[inf]). That is, largest of the small values to the smallest of the large values (excluding the outside ranges which do not match). Next, choose one wave as the basis for your for loop (assuming they have different intervals). For example, I am going to choose xw1. For each value of xw1 in this range (10-40 for the above example numbers), you will need to use interp on yw2. If you always have the case where the intervals of xw1 and xw2 are scalar multiples of eachother, you can avoid using interp but always having the result wave have the same interval spacing as the wave with the fewest datapoints (lowest resolution) and just ignoring the extra data points in the other wave. yw[i] = yw1[i] - interp(xw1[i], xw2, yw2) where i is the current iteration in your for loop covering the range from 10-40 (again for my example numbers). I'm vaguely aware of a notation involving the ? symbol that applies a math operation to only a section of a wave, but I'm not sure if that can be used in here place of a for loop (considering interp is required). |
|||
| supra | June 20, 2012 - 14:36 | ||
|---|---|---|---|
|
|
|||
| supra | June 20, 2012 - 15:10 | ||
|---|---|---|---|
|
|
|||
| proland | June 21, 2012 - 07:11 | ||
|---|---|---|---|
|
If you want it for display purposes (read-only) you can use a titlebox. Just change the title of the titlebox to be the new wave name. Fundamentally, this isn't very different than using a SetVariable control, where you change the string that is linked to the control. string NewTitleStr titlebox box1 title=NewTitleStr |
|||
| June 21, 2012 - 09:01 | |||
|---|---|---|---|
|
Before you get too deep into this, you might want to check out the Wave Arithmetic package. To load it, select Analysis->Packages->Wave Arithmetic. You may wish to look at a demo first: File->Example Experiments->Analysis->Wave Arithmetic Panel Demo. It handles the cases of overlapping but not identical X ranges, as well as X values that are not coincident (it interpolates Y values to handle this). If you look at the code, you will see that it is fairly complex keeping track of all the cases that must be handled. John Weeks |
|||
| supra | June 23, 2012 - 18:05 | ||||||
|---|---|---|---|---|---|---|---|
|
Thanks to Proland...titlebox works great...Thanks to Johnweeks ..you are right....indeed I will not dive so deep...as I am aware of my limited knowledge in Igor..so I stayed with same xw ..and plotted with same xw....indeed Arithmetic Panel is great ...but as I had to work with many sets of graph, I thought wrote something tailor made would be easy to use for me…I checked codes for it…it seems extremely complex … I thought to so something simple....I need little help. The code beneath (part of my bigger program) does the subtraction and works on Graph with two trace...Mainly what I want to do is to have option in subtraction (arithmetic) so that using setvar0 and setvar1 control I can define MyNewWave…for example say MyNewWave= If tried to declare setvar as string ...and tried to access setvar value as MyNewWave ( say MyNewWave=2(setvar0)-setvar1..where I say handtyped setvar1=2(wave0) setvar2=wave1 How can I have this...Pl find atta..the ipf file and one Graph containing two trace #pragma rtGlobals=1 // Use modern global access method. Menu "Test Subtrac" "Test SubtractA/1", Panel10() End Variable/G Window Panel10() : Panel PauseUpdate; Silent 1 NewPanel /W=(80,40,358,280) titlebox box1, pos={52,70},size={130,20}, title= "wave1-wave2" Button button1, pos={52,100},size={130,20}, proc=iSubtractTraceButton, title="Subtract Traces" CheckBox Check1,pos={52,130},size={39,14},title="Reverse",value= 0 SetVariable setvar0 pos={52,150},size={130,20}, value= _STR:"wave0" SetVariable setvar1 pos={52,170},size={130,20}, value= _STR:"wave1" EndMacro Function iSubtractTraceButton(cntl) : ButtonControl String cntl Button $cntl itestsubtract() End Function itestsubtract() String list = TraceNameList("", ";", 1) String traceName Variable index = 0 NVAR setvar1 NVAR setvar1 Variable Conf1 ControlInfo /W=Panel10 Check1 Conf1= V_value traceName = StringFromList(0, list) if (strlen(traceName) == 0) DoAlert 0, "No YW1" return -1 endif wave yw1 = TraceNameToWaveRef("", traceName) wave xw1 = XWaveRefFromTrace("", traceName) traceName = StringFromList(1, list) if (strlen(traceName) == 0) DoAlert 0, "No YW2" return -1 endif wave yw2 = TraceNameToWaveRef("", traceName) wave xw2 = XWaveRefFromTrace("", traceName) index += 1 Duplicate/O yw1, MyNewWave string NewTitleStr if (Conf1) MyNewWave=yw2-yw1 // MyNewWave=setvar0 - setvar1 NewTitleStr =StringFromList(1, list) + " - " + StringFromList(0, list) // setvar0 = NewTitleStr // setvar1 = StringFromList(1, list) else MyNewWave=yw1-yw2 NewTitleStr =StringFromList(0, list) + " - " + StringFromList(1, list) endif titlebox box1, pos={52,70},size={130,20}, title= NewTitleStr AppendtoGraph MyNewWave vs xw1 display MyNewWave vs xw1 end
[ last edited June 23, 2012 - 19:10 ]
|
|||||||
| June 23, 2012 - 18:46 | |||
|---|---|---|---|
|
I downloaded the experiment that you attached. When I click the Subtract Traces button, I get an error message "Can't find the control's action procedure named 'SubtractTracesButton'". This makes sense because there is no SubtractTracesButton procedure in the experiment. I then copied the procedures that you posted thinking perhaps they contained the SubtractTracesButton procedure, but no, they don't. It would be much easier if you would provide a self-contained experiment including all necessary procedures. You can do this by either pasting the procedures in the built-in procedure window or adopting (File->Adopt Procedure) a standalone procedure file. To learn about adopting, execute: DisplayHelpFile "Adopting a Procedure File"I now see that the panel in the SumRay.pxp file is obsolete as it has only one SetVariable. If I run, Panel10 I get a new panel with two SetVariables. But still no SubtractTracesButton procedure. I also note that your Panel10 macro is missing the End statement. Finally, here is an implementation of the SubtractTracesButton function: Function SubtractTraces(panelName) String panelName ControlInfo /W=$panelName setVar0 String firstWaveName = S_Value // e.g., "wave0" Wave firstWave = $firstWaveName // Create wave reference ControlInfo /W=$panelName setVar1 String secondWaveName = S_Value // e.g., "wave1" Wave secondWave = $secondWaveName // Create wave reference Duplicate /O firstWave, MyNewWave MyNewWave -= secondWave End Function SubtractTracesButton(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up SubtractTraces(ba.win) break case -1: // control being killed break endswitch return 0 End This would be better named as SubtractWaves because it does not have anything to do with graphs or traces in graphs. But perhaps that is something you intend to implement later. |
|||
| supra | June 23, 2012 - 19:15 | ||
|---|---|---|---|
|
I am really sorry hrodstein..indeed it was my mistake as the same ipf file I had inside the igor procedure folder ..and when saving I did some mistake.......now I corrected (subtractTrace button) and I upload the proper ipf with data file....I still didnt include your addition..I have to include that...thank you so much...now I understand how to use the setvar. [ last edited June 23, 2012 - 20:32 ]
|
|||
| supra | June 23, 2012 - 20:25 | ||
|---|---|---|---|
|
Thanks hrodstein....thank you so much...I still have some problem ..can you give me clue.. 1) How can I "parse" the string typed in a setvar input box ...such that if I type 2*wave0 in setvar0 field...then after parsing it should set S_Value = wave0 i,e the true wavename ..not 2*wave0..while "2" will be set as coeff so that in next stage of subtraction it can do 2) I want to populate the setvar0 and setvar1 field by the "wave name" that exist in a current trace ( as then I dont have to type...) ..I tried to use traceName = StringFromList(0, list) ControlInfo /W=panel10 setVar0 S_Value= traceName but it does work.. [ last edited June 23, 2012 - 20:31 ]
|
|||
| proland | June 25, 2012 - 05:08 | ||
|---|---|---|---|
|
I would recommend a separate setvar for the scalar multiplier. This eliminates the need to parse the string. While splitting the string is possible, you would require the user to be consistent. Splitting "2*wave0" or "wave0*2" are two completely different things. In regards to setting the value of the setvariable, you do not use ControlInfo. Instead, use tracename = stringfromlist(0, list) Setvariable setVar0 value = _STR:tracename To update a control, use the same commands you used to make it. Note that you only need to include those which you wish to change (I didn't change the position or size above). |
|||
| supra | July 10, 2012 - 17:51 | ||
|---|---|---|---|
|
Thanks Proland...extremely sorry for writing so late...just took me some time to come back and again started coding in Igor... tracename = stringfromlist(0, list) Setvariable setVar0 value = _STR:tracename works for me very well..now I can list the waves .. Thank you so much. |
|||

Joined: 2011-08-10
Location: United States
I have two trace ( trace 1 and trace 2) in a graph that I want to subtract (y value ). Incidentally my x waves are different (actually x value are same but the name of the x wave is different so the traces are = trace1 = {yw1 vs xw1 } and trace 2= {yw2, xw2 } where actually xw1 = xw2 point by point.
Usually I drag one of the trace (trace 2 ) to the other and use the code of by "Rgerkin" and then I have two trace in a single graph.
Now when I use "tracename" and use TraceNameToWaveRef("", traceName) and generate y wave and x wave (yw and xw).
Since it is in a loop it access the traces trace1 and trace 2 sequentially and thereby the last yw and xw is always from trace 2.
How I can save the trace 1 in an another variable or use a array function to save the trace1 : xw and yw (say yw1 and xw1) and then can save the trace from the 2nd trace : xw2 and yw2 and then I can do the required subtraction yw=yw2-yw1.
Although in my case the x a values are same (although x waves names are different)..but in case I have a situation whether the x values are different ( point by point ) .., just curious to know ..is it possible to plot yw or I have to interpolate or have to choose either xw1 or xw2 to plot yw ?