Common.StatisticalMetrics, FeatureVectorCalculator: changes, SignalChart added, temporarily disabled in IperlHead, ver. 2.26.1771
This commit is contained in:
parent
3f94318570
commit
e00e7556d6
@ -43,6 +43,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="BackgroundBeep.cs" />
|
<Compile Include="BackgroundBeep.cs" />
|
||||||
<Compile Include="Enums.cs" />
|
<Compile Include="Enums.cs" />
|
||||||
|
<Compile Include="StatisticalMetrics.cs" />
|
||||||
<Compile Include="Iperl\OptoTelegramRaw.cs" />
|
<Compile Include="Iperl\OptoTelegramRaw.cs" />
|
||||||
<Compile Include="SerializableDictionary.cs" />
|
<Compile Include="SerializableDictionary.cs" />
|
||||||
<Compile Include="UIControls\CoolButtonCtrl.cs">
|
<Compile Include="UIControls\CoolButtonCtrl.cs">
|
||||||
|
|||||||
@ -35,7 +35,7 @@ namespace Common.Iperl
|
|||||||
public float RefFlow; /// [m3/h]
|
public float RefFlow; /// [m3/h]
|
||||||
public int Counter;
|
public int Counter;
|
||||||
|
|
||||||
public UInt32 EmfRaw; /// From iPerl opto data
|
public Int32 EmfRaw; /// Signed EMF from iPerl opto data
|
||||||
public Int16 MagneticFieldRaw;
|
public Int16 MagneticFieldRaw;
|
||||||
public Int16 FlowRaw;
|
public Int16 FlowRaw;
|
||||||
public UInt32 VolumeRaw;
|
public UInt32 VolumeRaw;
|
||||||
@ -50,8 +50,7 @@ namespace Common.Iperl
|
|||||||
///
|
///
|
||||||
public double EMF()
|
public double EMF()
|
||||||
{
|
{
|
||||||
Int32 signedEmf = (EmfRaw > 0x7FFFFF) ? ((int)EmfRaw - 0x1000000) : (int)EmfRaw;
|
return 0.000000333 * (double)EmfRaw;
|
||||||
return 0.000000333 * (double)signedEmf;
|
|
||||||
}
|
}
|
||||||
public double MagneticField() { return (double)MagneticFieldRaw; }
|
public double MagneticField() { return (double)MagneticFieldRaw; }
|
||||||
public double Flow(double scalingFactor) { return 0.225 * scalingFactor * (double)FlowRaw; }
|
public double Flow(double scalingFactor) { return 0.225 * scalingFactor * (double)FlowRaw; }
|
||||||
@ -120,7 +119,10 @@ namespace Common.Iperl
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out EmfRaw);
|
UInt32 uEmfRaw;
|
||||||
|
bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uEmfRaw);
|
||||||
|
EmfRaw = (uEmfRaw > 0x7FFFFF) ? ((int)uEmfRaw - 0x1000000) : (int)uEmfRaw;
|
||||||
|
|
||||||
bool f2 = Int16.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out MagneticFieldRaw);
|
bool f2 = Int16.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out MagneticFieldRaw);
|
||||||
bool f3 = Int16.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out FlowRaw);
|
bool f3 = Int16.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out FlowRaw);
|
||||||
bool f4 = UInt32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
|
bool f4 = UInt32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
|
||||||
@ -243,7 +245,7 @@ namespace Common.Iperl
|
|||||||
DateTime.Second.ToString("D2"),
|
DateTime.Second.ToString("D2"),
|
||||||
DateTime.Millisecond.ToString("D4"),
|
DateTime.Millisecond.ToString("D4"),
|
||||||
Counter,
|
Counter,
|
||||||
EmfRaw.ToString("X6"),
|
(EmfRaw & 0x00FFFFFF).ToString("X6"),
|
||||||
MagneticFieldRaw.ToString("X4"),
|
MagneticFieldRaw.ToString("X4"),
|
||||||
FlowRaw.ToString("X4"),
|
FlowRaw.ToString("X4"),
|
||||||
VolumeRaw.ToString("X6"),
|
VolumeRaw.ToString("X6"),
|
||||||
|
|||||||
338
Common/StatisticalMetrics.cs
Normal file
338
Common/StatisticalMetrics.cs
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Common.Iperl;
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
public static float[] SubArray(this float[] array, int offset, int length)
|
||||||
|
{
|
||||||
|
float[] result = new float[length];
|
||||||
|
Array.Copy(array, offset, result, 0, length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StatisticalMetrics
|
||||||
|
{
|
||||||
|
const int VectorSize = 7;
|
||||||
|
const int MinLength = 100;
|
||||||
|
const float AdcBit = (float)57e-9;
|
||||||
|
const int NeighbourhoodSize = 30; /// To determine extended outliers
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates a 7-dimensional vector with these components:
|
||||||
|
/// x[0] = X1 = Number of outliers
|
||||||
|
/// x[1] = X2 = Relative cal-factor shift due to outliers
|
||||||
|
/// x[2] = X3 = Standard deviation of high-pass filteres ++++ demodulation of EMF (cut-off at Nyquist frequency)
|
||||||
|
/// x[3] = X4 = Robust standard deviation of high-pass filtered ++++ demodulation
|
||||||
|
/// x[4] = X5 = Peak-to-peak of low-pass filtered ++++ demodulation of EMF (cut-off TBD)
|
||||||
|
/// x[5] = X6 = Peak-to-peak of reference flow rate
|
||||||
|
/// x[6] = X7 = Mean impedance (++-- demodulation)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="optoData"></param>
|
||||||
|
/// <param name="optoDataCount"></param>
|
||||||
|
/// <param name="startIx"></param>
|
||||||
|
/// <param name="endIx"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static float[] Calculate(OptoTelegramRaw[] optoData, int optoDataCount, int startIx, int endIx, bool downsample,
|
||||||
|
out float[] offsetV, out float[] kOhmsR, out float[] kOhmsC, out float[] dutFlow,
|
||||||
|
out float[] refFlow, out float[] flowRatio, out float[] magField, out float[] emfV,
|
||||||
|
out PointF[] outliers, out PointF[] extendedOutliers)
|
||||||
|
{
|
||||||
|
offsetV = kOhmsR = kOhmsC = dutFlow = refFlow = flowRatio = magField = emfV = null;
|
||||||
|
outliers = extendedOutliers = null;
|
||||||
|
|
||||||
|
if (optoData == null || optoData.Length < optoDataCount ||
|
||||||
|
startIx < 0 || endIx >= optoDataCount || endIx <= startIx + MinLength + 3) return null;
|
||||||
|
|
||||||
|
float[] modulatedData = GetModulatedEmf(optoData, optoDataCount, AdcBit);
|
||||||
|
|
||||||
|
FindShiftAndDemodulate(modulatedData, downsample,
|
||||||
|
new float[] { +1, +1, +1, +1 }, out offsetV,
|
||||||
|
new float[] { +1, +1, -1, -1 }, out kOhmsR,
|
||||||
|
new float[] { +1, -1, -1, +1 }, out kOhmsC,
|
||||||
|
new float[] { +1, -1, +1, -1 }, out dutFlow);
|
||||||
|
//offsetV = FirFilter(modulatedData, new float[] { 1, 3, 4, 4, 3, 1}, 0.0625F);
|
||||||
|
|
||||||
|
magField = GetMagField(optoData, optoDataCount, downsample, new float[] { 1, 1, 1, 1 });
|
||||||
|
|
||||||
|
refFlow = GetRefFlow(optoData, optoDataCount, downsample, new float[] { 1, 1, 1, 1 });
|
||||||
|
|
||||||
|
flowRatio = new float[Math.Min(dutFlow.Length, refFlow.Length)];
|
||||||
|
for (int i = 0; i < flowRatio.Length; i++)
|
||||||
|
{
|
||||||
|
flowRatio[i] = (refFlow[i] != 0) ? dutFlow[i] / refFlow[i] : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float[] x = new float[VectorSize];
|
||||||
|
|
||||||
|
/// X1 = Number of outliers
|
||||||
|
int outliersCount = GetOutliers(flowRatio, out outliers, out extendedOutliers);
|
||||||
|
|
||||||
|
|
||||||
|
/// X2 = Relative cal-factor shift due to outliers
|
||||||
|
|
||||||
|
/// X3 = Standard deviation of high-pass filteres ++++ demodulation of EMF (cut-off at Nyquist frequency)
|
||||||
|
|
||||||
|
/// X4 = Robust standard deviation of high-pass filtered ++++ demodulation
|
||||||
|
|
||||||
|
/// X5 = Peak-to-peak of low-pass filtered ++++ demodulation of EMF (cut-off TBD)
|
||||||
|
|
||||||
|
/// X6 = Peak-to-peak of reference flow rate
|
||||||
|
|
||||||
|
/// X7 = Mean impedance (++-- demodulation)
|
||||||
|
double sum = 0;
|
||||||
|
foreach (var z in kOhmsR) sum += z;
|
||||||
|
x[6] = Convert.ToSingle(sum / kOhmsR.Length);
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static float[] GetModulatedEmf(OptoTelegramRaw[] optoData, int optoDataCount, float factor)
|
||||||
|
{
|
||||||
|
if (optoData == null || optoDataCount < 0) return null;
|
||||||
|
|
||||||
|
float[] result = new float[optoDataCount];
|
||||||
|
for (int i = 0; i < optoDataCount; i++)
|
||||||
|
{
|
||||||
|
result[i] = optoData[i].EmfRaw * factor;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static float[] GetMagField(OptoTelegramRaw[] optoData, int optoDataCount, bool downsample, float[] kernel)
|
||||||
|
{
|
||||||
|
if (optoData == null || optoDataCount < 0 || (downsample && (kernel == null || kernel.Length < 4))) return null;
|
||||||
|
|
||||||
|
int resultLen = downsample ? (optoDataCount / 4) : optoDataCount;
|
||||||
|
float[] result = new float[resultLen];
|
||||||
|
|
||||||
|
if (downsample)
|
||||||
|
{
|
||||||
|
float ksum = 0;
|
||||||
|
for (int j = 0; j < kernel.Length; j++) ksum += kernel[j];
|
||||||
|
for (int j = 0; j < kernel.Length; j++) kernel[j] /= ksum;
|
||||||
|
|
||||||
|
for (int i = 0; (4 * i) + kernel.Length - 1 < optoDataCount; i++)
|
||||||
|
{
|
||||||
|
float sum = 0;
|
||||||
|
for (int j = 0; j < kernel.Length; j++) sum += Convert.ToSingle(optoData[4 * i + j].MagneticFieldRaw) * kernel[j];
|
||||||
|
result[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < optoDataCount; i++) result[i] = optoData[i].MagneticFieldRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static float[] GetRefFlow(OptoTelegramRaw[] optoData, int optoDataCount, bool downsample, float[] kernel)
|
||||||
|
{
|
||||||
|
if (optoData == null || optoDataCount < 0 || (downsample && (kernel == null || kernel.Length < 4))) return null;
|
||||||
|
|
||||||
|
int resultLen = downsample ? (optoDataCount / 4) : optoDataCount;
|
||||||
|
float[] result = new float[resultLen];
|
||||||
|
|
||||||
|
if (downsample)
|
||||||
|
{
|
||||||
|
float ksum = 0;
|
||||||
|
for (int j = 0; j < kernel.Length; j++) ksum += kernel[j];
|
||||||
|
for (int j = 0; j < kernel.Length; j++) kernel[j] /= ksum;
|
||||||
|
|
||||||
|
for (int i = 0; (4 * i) + kernel.Length - 1 < optoDataCount; i++)
|
||||||
|
{
|
||||||
|
float sum = 0;
|
||||||
|
for (int j = 0; j < kernel.Length; j++) sum += Convert.ToSingle(optoData[4 * i + j].RefFlow) * kernel[j];
|
||||||
|
result[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < optoDataCount; i++) result[i] = optoData[i].RefFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void FindShiftAndDemodulate(float[] modulatedData, bool downsample,
|
||||||
|
float[] kernel1, out float[] data1,
|
||||||
|
float[] kernel2, out float[] data2,
|
||||||
|
float[] kernel3, out float[] data3,
|
||||||
|
float[] kernel4, out float[] data4)
|
||||||
|
{
|
||||||
|
int shift = GetShift(modulatedData.SubArray(0, MinLength));
|
||||||
|
|
||||||
|
data1 = (kernel1 != null) ? Demodulate(modulatedData, kernel1, shift, downsample) : null;
|
||||||
|
data2 = (kernel2 != null) ? Demodulate(modulatedData, kernel2, shift, downsample) : null;
|
||||||
|
data3 = (kernel3 != null) ? Demodulate(modulatedData, kernel3, shift, downsample) : null;
|
||||||
|
data4 = (kernel4 != null) ? Demodulate(modulatedData, kernel4, shift, downsample) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unlike FIR filtering, demodulation shifts the kernel in 4 phases
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Input data</param>
|
||||||
|
/// <param name="kernel">Demodulation kernel</param>
|
||||||
|
/// <param name="shift">shift 0..3</param>
|
||||||
|
/// <returns>Output data</returns>
|
||||||
|
static float[] Demodulate(float[] data, float[] kernel, int shift, bool downsample)
|
||||||
|
{
|
||||||
|
if (data == null || data.Length < MinLength || kernel == null || kernel.Length != 4)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ksum = 0;
|
||||||
|
for (int i = 0; i < 4; i++) ksum += Math.Abs(kernel[i]);
|
||||||
|
for (int i = 0; i < 4; i++) kernel[i] /= ksum;
|
||||||
|
|
||||||
|
int rsltLen = downsample ? (data.Length - 3) / 4 : data.Length - 3;
|
||||||
|
float[] result = new float[rsltLen];
|
||||||
|
|
||||||
|
if (downsample)
|
||||||
|
{
|
||||||
|
for (int i = shift; i < 4 * rsltLen; i += 4)
|
||||||
|
{
|
||||||
|
float sum = 0;
|
||||||
|
for (int j = 0; j < 4; j++) sum += data[i + j] * kernel[(i + j + 4 - shift) % 4];
|
||||||
|
result[i / 4] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < rsltLen; i++)
|
||||||
|
{
|
||||||
|
float sum = 0;
|
||||||
|
for (int j = 0; j < 4; j++) sum += data[i + j] * kernel[(i + j + 4 - shift) % 4];
|
||||||
|
result[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determine modulation phase by maximizing ++-- demodulation result.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modulatedEmf">Input data</param>
|
||||||
|
/// <returns>0..3 = modulation phase or, -1 = error</returns>
|
||||||
|
static int GetShift(float[] modulatedData)
|
||||||
|
{
|
||||||
|
float[] kernel = new float[4] { 1, 1, -1, -1 };
|
||||||
|
int maximizingShift = -1;
|
||||||
|
float maximum = float.MinValue;
|
||||||
|
|
||||||
|
for (int shift = 0; shift <= 3; shift++)
|
||||||
|
{
|
||||||
|
var demodulatedCandidate = Demodulate(modulatedData, kernel, shift, false);
|
||||||
|
float sum = 0;
|
||||||
|
foreach (var d in demodulatedCandidate) sum += d;
|
||||||
|
if (sum > maximum)
|
||||||
|
{
|
||||||
|
maximum = sum;
|
||||||
|
maximizingShift = shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maximizingShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FIR filtering = convolution with a kernel
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Input data</param>
|
||||||
|
/// <param name="kernel">Convolution kernel</param>
|
||||||
|
/// <returns>Output data</returns>
|
||||||
|
static float[] FirFilter(float[] data, float[] kernel, float factor)
|
||||||
|
{
|
||||||
|
if (data == null || kernel == null) return null;
|
||||||
|
|
||||||
|
int kernelLen = kernel.Length;
|
||||||
|
int rsltLen = data.Length - kernelLen + 1;
|
||||||
|
if (rsltLen < 0) return null;
|
||||||
|
|
||||||
|
float[] result = new float[rsltLen];
|
||||||
|
for (int i = 0; i < rsltLen; i++)
|
||||||
|
{
|
||||||
|
float sum = 0;
|
||||||
|
for (int j = 0; j < kernelLen; j++) sum += data[i + j] * kernel[j];
|
||||||
|
result[i] = sum * factor;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int GetOutliers(float[] flowRatio, out PointF[] outliers, out PointF[] extendedOutliers)
|
||||||
|
{
|
||||||
|
float mean = Enumerable.Average(flowRatio);
|
||||||
|
var fr = new float[flowRatio.Length];
|
||||||
|
for (int i = 0; i < fr.Length; i++) fr[i] = flowRatio[i] - mean;
|
||||||
|
|
||||||
|
Array.Sort(fr);
|
||||||
|
float qLo = fr[fr.Length / 4];
|
||||||
|
float qHi = fr[3 * fr.Length / 4];
|
||||||
|
|
||||||
|
int N = fr.Length / 2;
|
||||||
|
float sumY = 0;
|
||||||
|
float sumYY = 0;
|
||||||
|
for (int i = fr.Length / 4; i < 3 * fr.Length / 4; i++)
|
||||||
|
{
|
||||||
|
sumY += fr[i];
|
||||||
|
sumYY += fr[i] * fr[i];
|
||||||
|
}
|
||||||
|
float std = (float)Math.Sqrt(sumYY / N - (sumY / N) * (sumY / N));
|
||||||
|
float robustStd = std * 5.1812824F;
|
||||||
|
float threshold = 7 * robustStd;
|
||||||
|
|
||||||
|
/// Restore fr as it was before sorting
|
||||||
|
for (int i = 0; i < fr.Length; i++) fr[i] = flowRatio[i] - mean;
|
||||||
|
|
||||||
|
IList<PointF> listOfOutliers = new List<PointF>();
|
||||||
|
bool[] boolExtendedOutliers = new bool[fr.Length];
|
||||||
|
int outliersCount = 0;
|
||||||
|
for (int i = 0; i < fr.Length; i++)
|
||||||
|
{
|
||||||
|
if (fr[i] < -threshold || fr[i] > threshold)
|
||||||
|
{
|
||||||
|
/// This is an outlier
|
||||||
|
listOfOutliers.Add(new PointF(Convert.ToSingle(i), fr[i] + mean));
|
||||||
|
outliersCount++;
|
||||||
|
for (int j = Math.Max(0, i - NeighbourhoodSize); j <= Math.Min(i + NeighbourhoodSize, fr.Length - 1); j++)
|
||||||
|
{
|
||||||
|
boolExtendedOutliers[j] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IList<PointF> listOfExtendedOutliers = new List<PointF>();
|
||||||
|
for (int i = 0; i < fr.Length; i++)
|
||||||
|
{
|
||||||
|
if (boolExtendedOutliers[i])
|
||||||
|
{
|
||||||
|
listOfExtendedOutliers.Add(new PointF(Convert.ToSingle(i), fr[i] + mean));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outliers = listOfOutliers.ToArray<PointF>();
|
||||||
|
extendedOutliers = listOfExtendedOutliers.ToArray<PointF>();
|
||||||
|
|
||||||
|
return outliersCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,11 +2,7 @@
|
|||||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||||
///
|
///
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
@ -19,47 +15,6 @@ namespace Common
|
|||||||
return string.Format("{0} ({1}/{2})", name, repetitionNr, repeats);
|
return string.Format("{0} ({1}/{2})", name, repetitionNr, repeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CalculateFeatureVector(Iperl.OptoTelegramRaw[] optoData, int optoDataCount, int startIx, int endIx, ref float[] x)
|
|
||||||
{
|
|
||||||
if (startIx < 0 || endIx >= optoDataCount || startIx >= endIx) return;
|
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
Int64 sumFlow = 0;
|
|
||||||
Int64 sumFlow2 = 0;
|
|
||||||
Int64 sumEmf = 0;
|
|
||||||
Int64 sumEmf2 = 0;
|
|
||||||
Int64 sumMagF = 0;
|
|
||||||
Int64 sumMagF2 = 0;
|
|
||||||
Int64 sumImp = 0;
|
|
||||||
Int64 sumImp2 = 0;
|
|
||||||
|
|
||||||
for (int ix = startIx; ix <= endIx; ix++)
|
|
||||||
{
|
|
||||||
if (optoData[ix].Flags == Iperl.OptoTelegramFlags.OK ||
|
|
||||||
optoData[ix].Flags == Iperl.OptoTelegramFlags.OK_TestStart ||
|
|
||||||
optoData[ix].Flags == Iperl.OptoTelegramFlags.OK_TestEnd)
|
|
||||||
{
|
|
||||||
n++;
|
|
||||||
sumFlow += optoData[ix].FlowRaw;
|
|
||||||
sumFlow2 += ((int)optoData[ix].FlowRaw * (int)optoData[ix].FlowRaw);
|
|
||||||
sumEmf += (int)optoData[ix].EmfRaw;
|
|
||||||
sumEmf2 += ((Int64)optoData[ix].EmfRaw * (Int64)optoData[ix].EmfRaw);
|
|
||||||
sumMagF += optoData[ix].MagneticFieldRaw;
|
|
||||||
sumMagF2 += ((int)optoData[ix].MagneticFieldRaw * (int)optoData[ix].MagneticFieldRaw);
|
|
||||||
sumImp += optoData[ix].Impedance;
|
|
||||||
sumImp2 += ((int)optoData[ix].Impedance * (int)optoData[ix].Impedance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n >= 2)
|
|
||||||
{
|
|
||||||
if (x.Length > 0) x[0] = ((float)sumFlow2 - (float)sumFlow * (float)sumFlow / n) / (n - 1);
|
|
||||||
if (x.Length > 1) x[1] = ((float)sumEmf2 - (float)sumEmf * (float)sumEmf / n) / (n - 1);
|
|
||||||
if (x.Length > 2) x[2] = ((float)sumMagF2 - (float)sumMagF * (float)sumMagF / n) / (n - 1);
|
|
||||||
if (x.Length > 3) x[3] = ((float)sumImp2 - (float)sumImp * (float)sumImp / n) / (n - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Parity GetParity(string str, Parity defaultParity = Parity.None)
|
public static Parity GetParity(string str, Parity defaultParity = Parity.None)
|
||||||
{
|
{
|
||||||
if (str.Equals(Parity.None.ToString())) return Parity.None;
|
if (str.Equals(Parity.None.ToString())) return Parity.None;
|
||||||
|
|||||||
229
FeatureVectorCalculator/CalculatorWnd.Designer.cs
generated
229
FeatureVectorCalculator/CalculatorWnd.Designer.cs
generated
@ -30,21 +30,46 @@
|
|||||||
{
|
{
|
||||||
this.rawFileComboBox = new System.Windows.Forms.ComboBox();
|
this.rawFileComboBox = new System.Windows.Forms.ComboBox();
|
||||||
this.browseButton = new System.Windows.Forms.Button();
|
this.browseButton = new System.Windows.Forms.Button();
|
||||||
this.processButton = new System.Windows.Forms.Button();
|
|
||||||
this.resultsTextBox = new System.Windows.Forms.TextBox();
|
this.resultsTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||||
|
this.splitContainer2 = new System.Windows.Forms.SplitContainer();
|
||||||
|
this.splitContainer3 = new System.Windows.Forms.SplitContainer();
|
||||||
|
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||||
|
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||||
|
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||||
|
this.tabPage3 = new System.Windows.Forms.TabPage();
|
||||||
|
this.tabPage4 = new System.Windows.Forms.TabPage();
|
||||||
|
this.tabPage5 = new System.Windows.Forms.TabPage();
|
||||||
|
this.tabPage6 = new System.Windows.Forms.TabPage();
|
||||||
|
this.tabPage7 = new System.Windows.Forms.TabPage();
|
||||||
|
this.tabPage8 = new System.Windows.Forms.TabPage();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
|
||||||
|
this.splitContainer1.Panel1.SuspendLayout();
|
||||||
|
this.splitContainer1.Panel2.SuspendLayout();
|
||||||
|
this.splitContainer1.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
|
||||||
|
this.splitContainer2.Panel1.SuspendLayout();
|
||||||
|
this.splitContainer2.Panel2.SuspendLayout();
|
||||||
|
this.splitContainer2.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).BeginInit();
|
||||||
|
this.splitContainer3.Panel1.SuspendLayout();
|
||||||
|
this.splitContainer3.Panel2.SuspendLayout();
|
||||||
|
this.splitContainer3.SuspendLayout();
|
||||||
|
this.tabControl1.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// rawFileComboBox
|
// rawFileComboBox
|
||||||
//
|
//
|
||||||
|
this.rawFileComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
this.rawFileComboBox.FormattingEnabled = true;
|
this.rawFileComboBox.FormattingEnabled = true;
|
||||||
this.rawFileComboBox.Location = new System.Drawing.Point(29, 28);
|
this.rawFileComboBox.Location = new System.Drawing.Point(0, 0);
|
||||||
this.rawFileComboBox.Name = "rawFileComboBox";
|
this.rawFileComboBox.Name = "rawFileComboBox";
|
||||||
this.rawFileComboBox.Size = new System.Drawing.Size(715, 21);
|
this.rawFileComboBox.Size = new System.Drawing.Size(1040, 21);
|
||||||
this.rawFileComboBox.TabIndex = 0;
|
this.rawFileComboBox.TabIndex = 0;
|
||||||
//
|
//
|
||||||
// browseButton
|
// browseButton
|
||||||
//
|
//
|
||||||
this.browseButton.Location = new System.Drawing.Point(769, 19);
|
this.browseButton.Location = new System.Drawing.Point(7, 0);
|
||||||
this.browseButton.Name = "browseButton";
|
this.browseButton.Name = "browseButton";
|
||||||
this.browseButton.Size = new System.Drawing.Size(66, 37);
|
this.browseButton.Size = new System.Drawing.Size(66, 37);
|
||||||
this.browseButton.TabIndex = 1;
|
this.browseButton.TabIndex = 1;
|
||||||
@ -52,37 +77,184 @@
|
|||||||
this.browseButton.UseVisualStyleBackColor = true;
|
this.browseButton.UseVisualStyleBackColor = true;
|
||||||
this.browseButton.Click += new System.EventHandler(this.browseButton_Click);
|
this.browseButton.Click += new System.EventHandler(this.browseButton_Click);
|
||||||
//
|
//
|
||||||
// processButton
|
|
||||||
//
|
|
||||||
this.processButton.Location = new System.Drawing.Point(29, 66);
|
|
||||||
this.processButton.Name = "processButton";
|
|
||||||
this.processButton.Size = new System.Drawing.Size(91, 46);
|
|
||||||
this.processButton.TabIndex = 2;
|
|
||||||
this.processButton.Text = "Process";
|
|
||||||
this.processButton.UseVisualStyleBackColor = true;
|
|
||||||
this.processButton.Click += new System.EventHandler(this.processButton_Click);
|
|
||||||
//
|
|
||||||
// resultsTextBox
|
// resultsTextBox
|
||||||
//
|
//
|
||||||
this.resultsTextBox.Location = new System.Drawing.Point(29, 131);
|
this.resultsTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.resultsTextBox.Location = new System.Drawing.Point(0, 0);
|
||||||
this.resultsTextBox.Multiline = true;
|
this.resultsTextBox.Multiline = true;
|
||||||
this.resultsTextBox.Name = "resultsTextBox";
|
this.resultsTextBox.Name = "resultsTextBox";
|
||||||
this.resultsTextBox.Size = new System.Drawing.Size(715, 181);
|
this.resultsTextBox.Size = new System.Drawing.Size(1127, 156);
|
||||||
this.resultsTextBox.TabIndex = 3;
|
this.resultsTextBox.TabIndex = 3;
|
||||||
//
|
//
|
||||||
|
// splitContainer1
|
||||||
|
//
|
||||||
|
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.splitContainer1.Name = "splitContainer1";
|
||||||
|
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||||
|
//
|
||||||
|
// splitContainer1.Panel1
|
||||||
|
//
|
||||||
|
this.splitContainer1.Panel1.Controls.Add(this.splitContainer2);
|
||||||
|
//
|
||||||
|
// splitContainer1.Panel2
|
||||||
|
//
|
||||||
|
this.splitContainer1.Panel2.Controls.Add(this.tabControl1);
|
||||||
|
this.splitContainer1.Size = new System.Drawing.Size(1127, 733);
|
||||||
|
this.splitContainer1.SplitterDistance = 200;
|
||||||
|
this.splitContainer1.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// splitContainer2
|
||||||
|
//
|
||||||
|
this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
|
||||||
|
this.splitContainer2.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.splitContainer2.Name = "splitContainer2";
|
||||||
|
this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||||
|
//
|
||||||
|
// splitContainer2.Panel1
|
||||||
|
//
|
||||||
|
this.splitContainer2.Panel1.Controls.Add(this.splitContainer3);
|
||||||
|
//
|
||||||
|
// splitContainer2.Panel2
|
||||||
|
//
|
||||||
|
this.splitContainer2.Panel2.Controls.Add(this.resultsTextBox);
|
||||||
|
this.splitContainer2.Size = new System.Drawing.Size(1127, 200);
|
||||||
|
this.splitContainer2.SplitterDistance = 40;
|
||||||
|
this.splitContainer2.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// splitContainer3
|
||||||
|
//
|
||||||
|
this.splitContainer3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.splitContainer3.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
|
||||||
|
this.splitContainer3.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.splitContainer3.Name = "splitContainer3";
|
||||||
|
//
|
||||||
|
// splitContainer3.Panel1
|
||||||
|
//
|
||||||
|
this.splitContainer3.Panel1.Controls.Add(this.rawFileComboBox);
|
||||||
|
//
|
||||||
|
// splitContainer3.Panel2
|
||||||
|
//
|
||||||
|
this.splitContainer3.Panel2.Controls.Add(this.browseButton);
|
||||||
|
this.splitContainer3.Size = new System.Drawing.Size(1127, 40);
|
||||||
|
this.splitContainer3.SplitterDistance = 1040;
|
||||||
|
this.splitContainer3.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// tabControl1
|
||||||
|
//
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage1);
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage2);
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage3);
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage4);
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage5);
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage6);
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage7);
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage8);
|
||||||
|
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.tabControl1.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.tabControl1.Name = "tabControl1";
|
||||||
|
this.tabControl1.SelectedIndex = 0;
|
||||||
|
this.tabControl1.Size = new System.Drawing.Size(1127, 529);
|
||||||
|
this.tabControl1.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// tabPage1
|
||||||
|
//
|
||||||
|
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabPage1.Name = "tabPage1";
|
||||||
|
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tabPage1.Size = new System.Drawing.Size(1119, 503);
|
||||||
|
this.tabPage1.TabIndex = 0;
|
||||||
|
this.tabPage1.Text = "OffsetV";
|
||||||
|
this.tabPage1.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tabPage2
|
||||||
|
//
|
||||||
|
this.tabPage2.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabPage2.Name = "tabPage2";
|
||||||
|
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tabPage2.Size = new System.Drawing.Size(1119, 503);
|
||||||
|
this.tabPage2.TabIndex = 1;
|
||||||
|
this.tabPage2.Text = "KOhmsR";
|
||||||
|
this.tabPage2.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tabPage3
|
||||||
|
//
|
||||||
|
this.tabPage3.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabPage3.Name = "tabPage3";
|
||||||
|
this.tabPage3.Size = new System.Drawing.Size(1119, 503);
|
||||||
|
this.tabPage3.TabIndex = 2;
|
||||||
|
this.tabPage3.Text = "KOhmsC";
|
||||||
|
this.tabPage3.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tabPage4
|
||||||
|
//
|
||||||
|
this.tabPage4.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabPage4.Name = "tabPage4";
|
||||||
|
this.tabPage4.Size = new System.Drawing.Size(1119, 503);
|
||||||
|
this.tabPage4.TabIndex = 3;
|
||||||
|
this.tabPage4.Text = "DutFlowLph";
|
||||||
|
this.tabPage4.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tabPage5
|
||||||
|
//
|
||||||
|
this.tabPage5.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabPage5.Name = "tabPage5";
|
||||||
|
this.tabPage5.Size = new System.Drawing.Size(1119, 503);
|
||||||
|
this.tabPage5.TabIndex = 4;
|
||||||
|
this.tabPage5.Text = "RefFlowLph";
|
||||||
|
this.tabPage5.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tabPage6
|
||||||
|
//
|
||||||
|
this.tabPage6.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabPage6.Name = "tabPage6";
|
||||||
|
this.tabPage6.Size = new System.Drawing.Size(1119, 503);
|
||||||
|
this.tabPage6.TabIndex = 5;
|
||||||
|
this.tabPage6.Text = "FlowRatio";
|
||||||
|
this.tabPage6.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tabPage7
|
||||||
|
//
|
||||||
|
this.tabPage7.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabPage7.Name = "tabPage7";
|
||||||
|
this.tabPage7.Size = new System.Drawing.Size(1119, 503);
|
||||||
|
this.tabPage7.TabIndex = 6;
|
||||||
|
this.tabPage7.Text = "MagField";
|
||||||
|
this.tabPage7.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tabPage8
|
||||||
|
//
|
||||||
|
this.tabPage8.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabPage8.Name = "tabPage8";
|
||||||
|
this.tabPage8.Size = new System.Drawing.Size(1119, 503);
|
||||||
|
this.tabPage8.TabIndex = 7;
|
||||||
|
this.tabPage8.Text = "EmfV";
|
||||||
|
this.tabPage8.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
// CalculatorWnd
|
// CalculatorWnd
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.ClientSize = new System.Drawing.Size(859, 335);
|
this.ClientSize = new System.Drawing.Size(1127, 733);
|
||||||
this.Controls.Add(this.resultsTextBox);
|
this.Controls.Add(this.splitContainer1);
|
||||||
this.Controls.Add(this.processButton);
|
|
||||||
this.Controls.Add(this.browseButton);
|
|
||||||
this.Controls.Add(this.rawFileComboBox);
|
|
||||||
this.Name = "CalculatorWnd";
|
this.Name = "CalculatorWnd";
|
||||||
this.Text = "Feature vector calculator";
|
this.Text = "Feature vector calculator";
|
||||||
|
this.splitContainer1.Panel1.ResumeLayout(false);
|
||||||
|
this.splitContainer1.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
|
||||||
|
this.splitContainer1.ResumeLayout(false);
|
||||||
|
this.splitContainer2.Panel1.ResumeLayout(false);
|
||||||
|
this.splitContainer2.Panel2.ResumeLayout(false);
|
||||||
|
this.splitContainer2.Panel2.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
|
||||||
|
this.splitContainer2.ResumeLayout(false);
|
||||||
|
this.splitContainer3.Panel1.ResumeLayout(false);
|
||||||
|
this.splitContainer3.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).EndInit();
|
||||||
|
this.splitContainer3.ResumeLayout(false);
|
||||||
|
this.tabControl1.ResumeLayout(false);
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +262,19 @@
|
|||||||
|
|
||||||
private System.Windows.Forms.ComboBox rawFileComboBox;
|
private System.Windows.Forms.ComboBox rawFileComboBox;
|
||||||
private System.Windows.Forms.Button browseButton;
|
private System.Windows.Forms.Button browseButton;
|
||||||
private System.Windows.Forms.Button processButton;
|
|
||||||
private System.Windows.Forms.TextBox resultsTextBox;
|
private System.Windows.Forms.TextBox resultsTextBox;
|
||||||
|
private System.Windows.Forms.SplitContainer splitContainer1;
|
||||||
|
private System.Windows.Forms.SplitContainer splitContainer2;
|
||||||
|
private System.Windows.Forms.SplitContainer splitContainer3;
|
||||||
|
private System.Windows.Forms.TabControl tabControl1;
|
||||||
|
private System.Windows.Forms.TabPage tabPage1;
|
||||||
|
private System.Windows.Forms.TabPage tabPage2;
|
||||||
|
private System.Windows.Forms.TabPage tabPage3;
|
||||||
|
private System.Windows.Forms.TabPage tabPage4;
|
||||||
|
private System.Windows.Forms.TabPage tabPage5;
|
||||||
|
private System.Windows.Forms.TabPage tabPage6;
|
||||||
|
private System.Windows.Forms.TabPage tabPage7;
|
||||||
|
private System.Windows.Forms.TabPage tabPage8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,13 +4,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using System.Windows.Forms.DataVisualization.Charting;
|
||||||
using Common.Iperl;
|
using Common.Iperl;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace FeatureVectorCalculator
|
namespace FeatureVectorCalculator
|
||||||
{
|
{
|
||||||
public partial class CalculatorWnd : Form
|
public partial class CalculatorWnd : Form
|
||||||
{
|
{
|
||||||
public const int MaxOptoDataCount = 40000;
|
public const int MaxOptoDataCount = 40000;
|
||||||
|
public const bool Downsample = true;
|
||||||
|
public const bool Extend = true;
|
||||||
|
|
||||||
|
|
||||||
OptoTelegramRaw[] optoData;
|
OptoTelegramRaw[] optoData;
|
||||||
Int64 volumeRawExtLast;
|
Int64 volumeRawExtLast;
|
||||||
Int64 timestampExtLast;
|
Int64 timestampExtLast;
|
||||||
@ -27,63 +34,115 @@ namespace FeatureVectorCalculator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearOutput()
|
||||||
|
{
|
||||||
|
resultsTextBox.Clear();
|
||||||
|
tabControl1.TabPages[0].Controls.Clear();
|
||||||
|
tabControl1.TabPages[1].Controls.Clear();
|
||||||
|
tabControl1.TabPages[2].Controls.Clear();
|
||||||
|
tabControl1.TabPages[3].Controls.Clear();
|
||||||
|
tabControl1.TabPages[4].Controls.Clear();
|
||||||
|
tabControl1.TabPages[5].Controls.Clear();
|
||||||
|
tabControl1.TabPages[6].Controls.Clear();
|
||||||
|
tabControl1.TabPages[7].Controls.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
private void browseButton_Click(object sender, EventArgs e)
|
private void browseButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
OpenFileDialog ofd = new OpenFileDialog();
|
OpenFileDialog ofd = new OpenFileDialog();
|
||||||
var dr = ofd.ShowDialog();
|
|
||||||
rawFileComboBox.Text = ofd.FileName;
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
rawFileComboBox.Text = ofd.FileName;
|
||||||
|
ProcessRawDataFile(ofd.FileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processButton_Click(object sender, EventArgs e)
|
void ProcessRawDataFile(string fileName)
|
||||||
{
|
{
|
||||||
if (optoData == null) return;
|
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
int startIx = -1;
|
int startIx = -1;
|
||||||
int endIx = -1;
|
int endIx = -1;
|
||||||
|
|
||||||
using (StreamReader reader = new StreamReader(rawFileComboBox.Text))
|
ClearOutput();
|
||||||
|
|
||||||
|
resultsTextBox.Text = string.Format("File name: {0}{1}", fileName, Environment.NewLine);
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
string line;
|
using (StreamReader reader = new StreamReader(fileName))
|
||||||
while ((line = reader.ReadLine()) != null && counter < MaxOptoDataCount)
|
|
||||||
{
|
{
|
||||||
int ix = line.IndexOf(" :\t");
|
string line;
|
||||||
|
while ((line = reader.ReadLine()) != null && counter < MaxOptoDataCount)
|
||||||
if (ix >= 0)
|
|
||||||
{
|
{
|
||||||
if (optoData[counter].UpdateFromString(line.Substring(ix + 3), counter, 0, ref volumeRawExtLast, ref timestampExtLast, true))
|
int ix = line.IndexOf(" :\t");
|
||||||
|
string[] items = line.Split('\t');
|
||||||
|
|
||||||
|
if (items.Length > 18)
|
||||||
{
|
{
|
||||||
if (line.EndsWith("#### start test ####"))
|
string telegram = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\r\n",
|
||||||
|
items[2], items[3], items[4], items[5], items[6], items[7], items[8]);
|
||||||
|
|
||||||
|
if (optoData[counter].UpdateFromString(telegram, counter, 0, ref volumeRawExtLast, ref timestampExtLast))
|
||||||
{
|
{
|
||||||
startIx = counter;
|
if (line.EndsWith("#### start test ####"))
|
||||||
optoData[counter].Flags = OptoTelegramFlags.OK_TestStart;
|
{
|
||||||
}
|
startIx = counter;
|
||||||
else if (line.EndsWith("#### end of test ####"))
|
optoData[counter].Flags = OptoTelegramFlags.OK_TestStart;
|
||||||
{
|
}
|
||||||
endIx = counter;
|
else if (line.EndsWith("#### end of test ####"))
|
||||||
optoData[counter].Flags = OptoTelegramFlags.OK_TestEnd;
|
{
|
||||||
|
endIx = counter;
|
||||||
|
optoData[counter].Flags = OptoTelegramFlags.OK_TestEnd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
optoData[counter].Flags = OptoTelegramFlags.OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optoData[counter].RefFlow = float.Parse(items[15].Replace(',', '.'), CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
optoData[counter].Flags = OptoTelegramFlags.InvalidTelegram;
|
||||||
optoData[counter].Flags = OptoTelegramFlags.InvalidTelegram;
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
counter++;
|
reader.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.Close();
|
|
||||||
}
|
}
|
||||||
|
catch (Exception exc)
|
||||||
float[] featureVector = new float[9];
|
|
||||||
Common.Utils.CalculateFeatureVector(optoData, counter, startIx, endIx, ref featureVector);
|
|
||||||
|
|
||||||
resultsTextBox.Clear();
|
|
||||||
for (int i = 0; i < 9; i++)
|
|
||||||
{
|
{
|
||||||
resultsTextBox.Text += string.Format("X{0} = {1}\r\n", i + 1, featureVector[i]);
|
MessageBox.Show(string.Format("Exception: {0}", exc.Message));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int start = Extend ? 0 : startIx;
|
||||||
|
int end = Extend ? (counter - 1) : endIx;
|
||||||
|
float[] offsetV, kOhmsR, kOhmsC, dutFlow, refFlow, flowRatio, magField, emfV;
|
||||||
|
PointF[] outliers, extendedOutliers;
|
||||||
|
float[] featureVector = Common.StatisticalMetrics.Calculate(optoData, counter, start, end, Downsample,
|
||||||
|
out offsetV, out kOhmsR, out kOhmsC, out dutFlow,
|
||||||
|
out refFlow, out flowRatio, out magField, out emfV,
|
||||||
|
out outliers, out extendedOutliers);
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.Min(9, featureVector.Length); i++)
|
||||||
|
{
|
||||||
|
resultsTextBox.Text += string.Format("X{0} = {1}{2}", i + 1, featureVector[i], Environment.NewLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
float period = Downsample ? 0.5F : 0.125F;
|
||||||
|
if (offsetV != null) tabControl1.TabPages[0].Controls.Add(SignalChart.GetChart(offsetV, period, "OffsetV", "OffsetV [μV]"));
|
||||||
|
if (kOhmsR != null) tabControl1.TabPages[1].Controls.Add(SignalChart.GetChart(kOhmsR, period, "kOhmsR", "kΩ"));
|
||||||
|
if (kOhmsC != null) tabControl1.TabPages[2].Controls.Add(SignalChart.GetChart(kOhmsC, period, "kOhmsC", "kΩ"));
|
||||||
|
if (dutFlow != null) tabControl1.TabPages[3].Controls.Add(SignalChart.GetChart(dutFlow, period, "dutFlow", "L/h"));
|
||||||
|
if (refFlow != null) tabControl1.TabPages[4].Controls.Add(SignalChart.GetChart(refFlow, period, "refFlow", "L/h"));
|
||||||
|
if (flowRatio != null) tabControl1.TabPages[5].Controls.Add(SignalChart.GetChart(flowRatio, period, "flowRatio", "", true, extendedOutliers, outliers));
|
||||||
|
if (magField != null) tabControl1.TabPages[6].Controls.Add(SignalChart.GetChart(magField, period, "magField", "μV", false));
|
||||||
|
if (emfV != null) tabControl1.TabPages[7].Controls.Add(SignalChart.GetChart(emfV, period, "emfV", "μV"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Windows.Forms.DataVisualization" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
@ -55,6 +56,7 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="SignalChart.cs" />
|
||||||
<EmbeddedResource Include="CalculatorWnd.resx">
|
<EmbeddedResource Include="CalculatorWnd.resx">
|
||||||
<DependentUpon>CalculatorWnd.cs</DependentUpon>
|
<DependentUpon>CalculatorWnd.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|||||||
78
FeatureVectorCalculator/SignalChart.cs
Normal file
78
FeatureVectorCalculator/SignalChart.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Windows.Forms.DataVisualization.Charting;
|
||||||
|
|
||||||
|
namespace FeatureVectorCalculator
|
||||||
|
{
|
||||||
|
public class SignalChart
|
||||||
|
{
|
||||||
|
public static Chart GetChart(float[] data, float period, string caption, string captionY, bool fromZero = true,
|
||||||
|
PointF[] extendedOutliers = null, PointF[] outliers = null)
|
||||||
|
{
|
||||||
|
Series series1 = null, series2 = null, series3 = null;
|
||||||
|
|
||||||
|
series1 = new Series { Name = caption, ChartArea = "area1", ChartType = SeriesChartType.Line, Color = Color.DeepSkyBlue };
|
||||||
|
float minY = float.MaxValue;
|
||||||
|
float maxY = float.MinValue;
|
||||||
|
for (int x = 0; x < data.Length; x++)
|
||||||
|
{
|
||||||
|
float y = data[x];
|
||||||
|
if (minY > y) minY = y;
|
||||||
|
if (maxY < y) maxY = y;
|
||||||
|
series1.Points.AddXY(x * period, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extendedOutliers != null)
|
||||||
|
{
|
||||||
|
series2 = new Series { Name = "extended outliers", ChartArea = "area1", ChartType = SeriesChartType.Point, Color = Color.Yellow };
|
||||||
|
for (int i = 0; i < extendedOutliers.Length; i++)
|
||||||
|
{
|
||||||
|
series2.Points.AddXY(extendedOutliers[i].X * period, extendedOutliers[i].Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outliers != null)
|
||||||
|
{
|
||||||
|
series3 = new Series { Name = "outliers", ChartArea = "area1", ChartType = SeriesChartType.Point, Color = Color.DarkRed };
|
||||||
|
for (int i = 0; i < outliers.Length; i++)
|
||||||
|
{
|
||||||
|
series3.Points.AddXY(outliers[i].X * period, outliers[i].Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ChartArea chArea = new ChartArea { Name = "area1" };
|
||||||
|
chArea.AxisX.Title = "Time [s]";
|
||||||
|
chArea.AxisX.IsLogarithmic = false;
|
||||||
|
chArea.AxisX.IsLabelAutoFit = true;
|
||||||
|
chArea.AxisX.Minimum = 0;
|
||||||
|
chArea.AxisX.Maximum = (data.Length - 1) * period;
|
||||||
|
// for (int j = i; j < i + 3; j++)
|
||||||
|
// {
|
||||||
|
// CustomLabel cl = new CustomLabel();
|
||||||
|
// cl.Text = string.Format("{0} {1}", xs[j], flowUnit.ToDescription());
|
||||||
|
// cl.FromPosition = Math.Log10(xs[j] * spacer);
|
||||||
|
// cl.ToPosition = Math.Log10(xs[j] / spacer);
|
||||||
|
// chArea.AxisX.CustomLabels.Add(cl);
|
||||||
|
// }
|
||||||
|
chArea.AxisY.Title = captionY;
|
||||||
|
chArea.AxisY.IsLogarithmic = false;
|
||||||
|
chArea.AxisY.IsLabelAutoFit = true;
|
||||||
|
chArea.AxisY.IsStartedFromZero = fromZero;
|
||||||
|
chArea.AxisY.Minimum = chArea.AxisY.IsStartedFromZero ? 0 : minY;
|
||||||
|
chArea.AxisY.Maximum = 1.1 * maxY;
|
||||||
|
if (chArea.AxisY.Maximum == chArea.AxisY.Minimum)
|
||||||
|
{
|
||||||
|
chArea.AxisY.Maximum = chArea.AxisY.Maximum + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Chart chart = new Chart { Text = caption, Dock = DockStyle.Fill };
|
||||||
|
chart.ChartAreas.Add(chArea);
|
||||||
|
chart.Series.Add(series1);
|
||||||
|
if (series2 != null) chart.Series.Add(series2);
|
||||||
|
if (series3 != null) chart.Series.Add(series3);
|
||||||
|
|
||||||
|
return chart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -620,9 +620,15 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
|
|||||||
AddTestStartEndMarksToData(out startIx, out endIx);
|
AddTestStartEndMarksToData(out startIx, out endIx);
|
||||||
StopDataStreamProcessing();
|
StopDataStreamProcessing();
|
||||||
DataStreamPostProcessing();
|
DataStreamPostProcessing();
|
||||||
Common.Utils.CalculateFeatureVector(optoData, optoDataCount, startIx, endIx, ref x);
|
|
||||||
|
|
||||||
log.DebugFormat("Feature vector calculation end, save opto-file start: {0:HH:mm:ss.fff}", DateTime.Now);
|
// TODO: Enable when calculations completed
|
||||||
|
//
|
||||||
|
// float[] offsetV, kOhmsR, kOhmsC, dutFlow, refFlow, flowRatio, magField, emfV;
|
||||||
|
// x = Common.StatisticalMetrics.Calculate(optoData, optoDataCount, startIx, endIx, true,
|
||||||
|
// out offsetV, out kOhmsR, out kOhmsC, out dutFlow,
|
||||||
|
// out refFlow, out flowRatio, out magField, out emfV);
|
||||||
|
//
|
||||||
|
// log.DebugFormat("Feature vector calculation end, save opto-file start: {0:HH:mm:ss.fff}", DateTime.Now);
|
||||||
|
|
||||||
string relativeDirectory = Path.Combine(StateMachine.CycleStartTimeStamp.ToString("yy"),
|
string relativeDirectory = Path.Combine(StateMachine.CycleStartTimeStamp.ToString("yy"),
|
||||||
StateMachine.CycleStartTimeStamp.ToString("MM"),
|
StateMachine.CycleStartTimeStamp.ToString("MM"),
|
||||||
|
|||||||
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
|||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyVersion("2.26.1770.0")]
|
[assembly: AssemblyVersion("2.26.1771.0")]
|
||||||
[assembly: AssemblyFileVersion("2.26.1770.0")]
|
[assembly: AssemblyFileVersion("2.26.1771.0")]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user