02-02-2017 02:20 PM
I'm writing some code to ensemble average high speed data from an engine in a test cell. This data is generally cylinder and manifold pressures. In a given file there are a varying number of channel groups that each contain a given number of channels that are all the same length. These generally contain ~300 cycles of data recorded on a crank angle basis(1 cycle=360 degrees at 0.5 degree increments). What I'm trying to do is for each channel in each group, split each channel into it's seperate cycles and then average all of the cycles for the respective channel together.
I started by adapting some code from the "Analyzing and Displaying Channels Section by Section" example. For the most part I wanted to do the same thing (split a channel into sections, cycles) but then I also wanted to average them and save it as another channel.
The code I currently have works fine, but it requires a LOT of calls to DataBlCopy which ends up taking longer than I would like (currently almost 4 seconds per channel group, each group is currently at 13 channels) so I was hoping to get some suggestions on how to speed this up.
From the example, for a given channel I create a temporary channel group that has as many channels as cycles (300) in the original channel. In the code below uBound(iaSelectedRuns) is usually 300. Then I loop through all cycles in that channel and use DataBlCopy to copy each cycle to its respective temporary channel. After then (in a sperate function) I average all of the temporary channels and save that in a new channel. Then clear the data from the temporary channels and move on to the next data channel in the group.
If there are 300 cycles of data with 13 channels per group and 6 groups, that's over 23000 calls to DataBlCopy.
The code that calls the copy is below:
Private sub CopyCurrentRun(oTempGroup, oCurrChn, iaRunStart, iaRunStop, iRun, iaSelectedRuns) dim iLoop, iMaxLoop, iOffset, oTargetChns set oTargetChns = oTempGroup.Channels iLoop = 0 iMaxLoop = uBound(iaSelectedRuns) if iMaxRun >= iaSelectedRuns(iMaxLoop) + iRun - 1 then 'v1a| changed lower bound from 0 to 1, required also changing DataBlCopy 4th item to oTargetChns(iLoop + 1) from oTargetChns(iLoop + 2) for iLoop = 1 to iMaxLoop iOffset = iaSelectedRuns(iLoop) - 1 if CheckDataForCopy(oCurrChn, iaRunStart(iRun), iaRunStop(iRun)) then Call DataBlCopy(oCurrChn, iaRunStart(iRun + iOffset), iaRunStop(iRun + iOffset) - iaRunStart(iRun + iOffset), oTargetChns(iLoop + 1), 1) end if next end if end sub
Thanks in advance for any help!
P.S. This is my first time posting on here so let me know if I didn't follow any best practices for format of the post or inserting code.
Solved! Go to Solution.
02-03-2017 03:11 PM - edited 02-03-2017 03:12 PM
Hi meatballosaurus,
It doesn't sound from your description that you need to break out those cycle ranges (P1 ... P2) into separate channels, if all you want to do is calculate the mean or other statistical property of that cycle range. Here's how to calculate and assign to the nth value of a new channel (MeanChannel) the average value of cycle range (P1 ... P2) within a large channel (YChannel)
FOR i = 1 TO 23 StatSel(i) = "No" NEXT ' i StatSel(6) = "Yes" ' Mean StatResChn = FALSE StatClipCopy = FALSE StatClipValue = FALSE RowRange = P1 & "-" & P2 Call StatBlockCalc("Channel", RowRange, YChannel) MeanChannel.Values(n) = StatArithMean
Brad Turpin
DIAdem Product Support Engineer
National Instruments
02-07-2017 09:49 AM
Thanks Brad, that definitely sped things up (about half the time)! Took some rework of the other code, but it was worth it.