DIAdem

cancel
Showing results for 
Search instead for 
Did you mean: 

Calculating St. Dev. from Reducing Classification

My end goal here is to calculate the reduce a raw data channel of N cycles into a single cycle average and obtain the standard deviation at each point in the cycle. I'm currently able to efficiently reduce the N cycles into the cycle average but am not sure how to get the standard deviation. My current method is outlined below, it may not be the best solution and I'm open to other suggestions, especially if it leads to an elegant solution to getting the standard deviation.

 

I have a data channel from an engine test bed and is cyclic. The data's x-axis is in degrees crank angle and the resolution/frequency of the channel is generally either 0.25 or 0.5 degrees. The channel always starts at 0 and increases by the resolution up to (180-resolution) with the next step at -180 degrees and continuing up to (180-resolution) for N cycles. See RawChn_start.jpg in attached .zip for the a snippet (first 1.5 cycles) of the x and y channel. The channel generally has 300 cycles of data, but could be more or less, so let's just refer to it as N cycles.

 

 I'm currently using a call to ChnClassXRedXY to average the N cycles into one cycle average channel. I like this solution because it is very fast and elegant. See "Raw_vs_Avg.jpg" for an example of the result. The code I'm using is also included (CycleAvg.vbs). The only problem is that the reduction only allows for mean, min, max, or sum. What I want is another channel that calculates the standard deviation at each class (i.e. at each crank angle step, 0.5 degrees, 1 degree, etc).

 

I've thought of three other approaches, but don't really like either of them.

- The first is to separate the raw channel into N individual channels and then use the descriptive statistics tools to calculate both the mean and st. deviation using the row-wise functions. This seems like a lot of extra work and overhead to create all those additional channels, calling StatBlockCalc, and then deleting the individual channels.

- Second option I've used and the code is "EnsAvgLoop.vbs". The idea here is to loop through each crank angle step, for each step, determine the row in the raw channel for each cycle (i.e. crank angle 1 occurs in row 2, 722, 1442, etc.) and build a string, feed that to the StatBlockCalc, then put the result in an Average channel at the appropriate crank angle. I could easily add standard deviation to this code as well, but this solution also has a lot of overhead as it could mean 720 to 1440 calls to StatBlockCalc.

- The last option I could think of is to create an array for each crank angle step in the script, store the individual cycle data in the arrays, then calculate the average and standard deviation of each array. Again, this would work, but seems more cumbersome than required.

0 Kudos
Message 1 of 2
(3,316 Views)

Calculation of the standard deviation at each point in the cycle for the data can be done using DIAdem. I approached this for another project by analyzing periodic data to identify the valleys and peaks for each cycle. Then I determined the minimum number of rows between each cycle's zero to full scale, and full scale to zero span. Then each cycle was divided up by this minimum span (of rows), and then linearity, hysteresis, and repeatability was then calculated. I also calculated the standard deviation for each, as appropriate.  You can read more about my approach by following this link:  http://www.savvydiademsolutions.com/blog.php?topic=accuracy-repeatability-hysteresis-linearity

 

I was able to write a script to simulate your data, but I was not able to apply the script snippets you provided to evaluate the data as you described.  Please contact me through the website link previously provided if you are still interested in pursuing a solution to your data analysis task.  

 

Dim oElementList
Call Data.Root.Clear()
Set oElementList = oCreateEngCycData("EngCycData")

Function oCreateEngCycData(ByVal sGrp)
Set oCreateEngCycData = Data.CreateElementList()
Dim oChn, oGrp
Dim sFormula, arrSymbols, arrValues, dValStart, dValEnd, oElementList
If Data.Root.ChannelGroups.Exists(sGrp) Then Call Data.Root.ChannelGroups.Remove(sGrp)
Set oGrp = Data.Root.ChannelGroups.Add(sGrp)

'y = a sin (bx + c)
'a = amplitude; b = period; c = phase
'Create the time channel for the SIN curve
Set oChn = oGrp.Channels.Add("x",DataTypeChnFloat64)
dValStart = 0.0
dValEnd = 4*pi()
Call ChnLinGen(oChn,dValStart,dValEnd,100,"Rad")

'Create the SIN curve
Set oChn = oGrp.Channels.Add("y",DataTypeChnFloat64)
ReDim arrSymbols(4): ReDim arrValues(4)
sFormula = "y = a*SIN(b*x+c)"
arrSymbols(0) = "y"
arrSymbols(1) = "a" 'amplitude
arrSymbols(2) = "b" 'period
arrSymbols(3) = "x"
arrSymbols(4) = "c" 'phase
Set arrValues(0) = oGrp.Channels("y")
arrValues(1) = 0.5 'amplitude
arrValues(2) = 2.5 'period
Set arrValues(3) = oGrp.Channels("x")
arrValues(4) = Pi()/2 'phase
Call Calculate(sFormula, arrSymbols, arrValues)
'Offset the channel
Call ChnOffset(oChn, oChn, oChn.Minimum, "free offset")
Call oCreateEngCycData.Add(oGrp.Channels("x"))
Call oCreateEngCycData.Add(oGrp.Channels("y"))

'Create Crank Angle channel
Set oChn = oGrp.Channels.Add("CrankAngle",DataTypeChnFloat64)
dValStart = 0.0
dValEnd = 180
Call ChnLinGen(oChn,dValStart,dValEnd,35,"°")
Call oCreateEngCycData.Add(oChn)

'Create cycles for -180 to +180 deg crank angle
'Call ChnGenVal(oChn,iRowFirst,iRows,dValStart,dValStep)
Call ChnGenVal(oChn,oChn.Size+1,65,-180,(180*2)/65,True)

Set oGrp = Nothing: Set oChn = Nothing
If IsArray(arrSymbols) Then Call Erase(arrSymbols)
If IsArray(arrValues) Then Call Erase(arrValues)
End Function 'oCreateEngCycData()

0 Kudos
Message 2 of 2
(2,789 Views)