DIAdem

cancel
Showing results for 
Search instead for 
Did you mean: 

Improving run time of multiple DataBlCopy calls.

Solved!
Go to solution

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.

0 Kudos
Message 1 of 3
(2,669 Views)
Solution
Accepted by topic author meatballosaurus

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

Message 2 of 3
(2,623 Views)

Thanks Brad, that definitely sped things up (about half the time)! Took some rework of the other code, but it was worth it.

0 Kudos
Message 3 of 3
(2,588 Views)