## How to access and save individual wave from TraceNameToWaveRef("", traceName)

supra
Posts: 57
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 ?

```String list = TraceNameList("", ";", 1)
String traceName
Variable index = 0

do
traceName = StringFromList(index, list)
if (strlen(traceName) == 0)
break // No more traces.
endif

wave yw = TraceNameToWaveRef("", traceName)
wave xw = XWaveRefFromTrace("", traceName)
------------------
?? need to save in a array yw1 and yw2
---------------

index += 1
while(1)
end

// Want to do the subtraction
yw=yw2-yw1 ```

[ last edited June 18, 2012 - 12:02 ]
Posts: 836
Joined: 2007-06-29
Location: United States

The obvious straightforward method:

```Function test()

String list = TraceNameList("", ";", 1)
String traceName
Variable index = 0

traceName = StringFromList(0, list)
if (strlen(traceName) == 0)
return -1
endif
wave yw1 = TraceNameToWaveRef("", traceName)
wave xw1 = XWaveRefFromTrace("", traceName)

traceName = StringFromList(1, list)
if (strlen(traceName) == 0)
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
WaveMetrics, Inc.
support@wavemetrics.com

supra
Posts: 57
Joined: 2011-08-10
Location: United States

Thank you so much JohnWeeks...that exactly what I was looking for....thanks a lot.
Yes I corrected the tag..thanks

proland
Posts: 120
Joined: 2011-03-14
Location: United States

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
Posts: 57
Joined: 2011-08-10
Location: United States

Sorry for writing you late. Thanks Proland for your clear explanation. Incidentally this time my "x" axis are equal ...but soon I will have situation whether the "x"s are different and I would need your method.

supra
Posts: 57
Joined: 2011-08-10
Location: United States

Hi
I wanted to show on a panel the name of the wave subtracted : i,e

`WaveSubtracated = StringFromList(1, list)- StringFromList(0, list) `

with what control I can show it, ValueDispaly is only for numeric value not for string, I tried listbox ...also didnt work.

jtigor
Posts: 180
Joined: 2007-09-04
Location: United States

Try a SetVariable control.

proland
Posts: 120
Joined: 2011-03-14
Location: United States

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```

Posts: 836
Joined: 2007-06-29
Location: United States

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
WaveMetrics, Inc.
support@wavemetrics.com

supra
Posts: 57
Joined: 2011-08-10
Location: United States

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=
` 2(wave0)- wave1 ` where ` setvar1=wave0 ` and ` setvar1=wave1 `which I say typed in the servar box. Now in present condition it is always hardcoded as ` wave2-wave1 `or ` wave1-wave2 `(if checkbox 1 is checked) .

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 ```
...but it always gives error..
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.

"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)
return -1
endif
wave yw1 = TraceNameToWaveRef("", traceName)
wave xw1 = XWaveRefFromTrace("", traceName)

traceName = StringFromList(1, list)
if (strlen(traceName) == 0)
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```

AttachmentSize
Mod-SumRay1.pxp62.11 KB

[ last edited June 23, 2012 - 19:10 ]
Posts: 910
Joined: 2007-06-21
Location: United States

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
Posts: 57
Joined: 2011-08-10
Location: United States

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
Posts: 57
Joined: 2011-08-10
Location: United States

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
coeff* wave0-wave1..... is there any builtin parsar in Igor.

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
Posts: 120
Joined: 2011-03-14
Location: United States

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.

```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
Posts: 57
Joined: 2011-08-10
Location: United States

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)