12-11-2015 07:10 AM
As part of our analysis system, we're writing a programme to combine multiple selection criteria on our datasets - that is, you can make up several different conditions, and then combine them together to filter out the values that don't comply and put the rest into a results channel.
What we need to do now is take two channels and compare them, and put all the data that are in both into a third channel. They're all timestamps, so numerical stuff should work fine on them.
I can think of a slow way of doing this that involves crawling through each channel, incrementing the lower value, and if the two are equal dumping them into the third channel, but I was wondering if there's a command that will do all that for us in a more efficient way.
Thanks.
12-11-2015 08:16 AM
Hi PGribble,
This task is best handled by the Channel Calculator, which you can run programmatically like this. The function to use in it is the IIF() functions, which is just like the IF function in Excel.
Set Group = Data.Root.ChannelGroups(2) Set Time1Channel = Group.Channels("Time1") Set Time2Channel = Group.Channels("Time2") Set TimeBChannel = Group.Channels("Time Both") Symbols = Array("TimeB", "Time1", "Time2") Channels = Array(TimeBChannel, Time1Channel, Time2Channel) Call Calculate("TimeB = IIF(Time1=Time2, Time1, Null)", Symbols, Channels) Call ChnNovHandle(TimeBChannel, "", "Delete", "X", 1, 1)
If you want to leave the matching values on their original rows, then omit the last function, which deletes all the rows that didn't match.
Brad Turpin
DIAdem Product Support Engineer
National Instruments
12-11-2015 08:31 AM
You want the CTNV function. Check out this page for more info: http://zone.ni.com/reference/en-XX/help/370859J-01/procmaths/procmaths/mathsproc_novalue_limit/
Basically, when the comparison sent to the CTNV function is TRUE, it returns a NoValue, if it's FALSE, it returns 0. Combine this with the ChnCalculate function, and you can have it work through an entire channel. This code below should work, but I don't have any appropriate data to try it out on.
T1="[1]/Input1 Channel"
T2="[1]/Input2 Channel"
T3="[1]/Output Channel"
Call ChnCalculate("Ch(T3)=Ch(T2)+CTNV(Ch(T2)<>Ch(T1))")
So the Channel specified in the T3 variable will be equal to the channel in the T2 variable when T1 and T2 are equal, and NoValue when they are not. It's a bit backward in that you get a NoValue when the condition is true, seems like it should be the other way around, but that's how it works.
If you don't want the NoValues in the output channel, you can process them manually, ANALYSIS->Basic Match->Channel Functions->Process NoValues. Or, you can use the ChnNovHandle command.
12-14-2015 05:37 AM
Thanks Brad!
On an initial read-through, this looks like it only works if the values match on the same rows - is that correct? We need to keep them if they appear *anywhere* in the list (although they're going to be sets of increasing timestamp values, so working through them sequentially is fine).
So we'd have something like this:
A B
1 3
4 5
5 6
8 8
12 9
15 11
17 12
And we'd be looking to extract 5, 8 and 12 from that list, and the impression I get is that using that function we'd only get 8. Is that right?
12-16-2015 07:43 AM
Hi PGribble,
Your impression is correct, the Calculate() command works entirely row-based across all the channels involved. Based on your latest information, you'll need to instead loop through the values of the shorter channel and use the ChnFind() function to check if that value is in the other channel.
Brad Turpin
DIAdem Product Support Engineer
National Instruments
12-16-2015 03:31 PM
Hi Brad,
In the end, we've built a function that crawls through the values on each side - because we know they're in ascending numerical order we can take advantage of that and process them like this:
If the left value is higher, increment the right index,
if the right value is higher, increment the left index,
if both values are the same, increment both indices and copy the value into the new channel.
That saves us having to search the whole channel each time, which should save slowdown when our results sets are big - so far it looks to be working well.
Thanks for the support!
12-17-2015 10:58 PM
Hi PGribble,
The ChnFind() function has a parameter to specify the row to start looking on, so if you use it you will not be searching the whole channel each time. Also, the ChnFind() command runs WAY faster than loops in VBScript, which is interpreted code.
If performance ever gets slow for you with your current method, you could consider switching to my suggestion.
Brad Turpin
DIAdem Product Support Engineer
National Instruments