iPerlHead : TimeFromSamples( ), VolumeFromSamples( ), StartEndFilterSamplesCount = 20

This commit is contained in:
Milan Hanajik
2021-05-19 16:16:53 +02:00
parent bec7287531
commit 81151935bc
@@ -19,10 +19,14 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
private static readonly ILog log = LogManager.GetLogger(typeof(IperlHead));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
#if TURA_SPECIAL
public const int MaxOptoDataCount = 250000;
#else
public const int MaxOptoDataCount = 40000;
#endif
public const int StartOptoDataCount = MaxOptoDataCount / 2;
public const int EndOptoDataCount = MaxOptoDataCount - StartOptoDataCount;
public const int StartEndFilterSamplesCount2 = 20; /// StartEndFilterSamplesCount = 2 * StartEndFilterSamplesCount2 + 1
readonly IperlHeadCfg iperlHeadCfg;
@@ -198,7 +202,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
if (meterVolume > 1E-2)
{
PositiveCounting = volumeLtrEnd > volumeLtrStart;
PositiveCounting = VolumeLtrEnd > VolumeLtrStart;
UInt16 newFactor = (UInt16)((double)originalCalibrationFactor * targetVolume / meterVolume + 0.5);
log.InfoFormat("Calibration factor: orig={0} new={1} V_iperl={2} V_ref={3} V_target={4}",
@@ -313,13 +317,10 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
private double volumeLtr;
private double volumeLtr0;
public double VolumeLtrStart { get { return volumeLtrStart; } } /// Test start volume for metrology
public double VolumeLtrEnd { get { return volumeLtrEnd; } } /// Test end volume for metrology
double volumeLtrStart; /// Test start volume for metrology
double volumeLtrEnd; /// Test end volume for metrology
double volumeLtrEnd1; /// auxiliary buffer1 to keep the end volume before test stops
double volumeLtrEnd2; /// auxiliary buffer2 to keep the end volume before test stops
double volumeLtrEnd3; /// auxiliary buffer3 to keep the end volume before test stops
/// Test start volume for metrology in liters
public double VolumeLtrStart { get { return VolumeFromSamples(optoData, optoDataCount, TestStartTelegramIx, ScalingFactor(), StartEndFilterSamplesCount2); } }
/// Test end volume for metrology in liters
public double VolumeLtrEnd { get { return VolumeFromSamples(optoData, optoDataCount, TestEndTelegramIx, ScalingFactor(), StartEndFilterSamplesCount2); } }
///
/// Timestamp from the opto telegram
@@ -328,23 +329,24 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
private double timestampSec;
private double timestampSec0;
public bool NoSamples { get { return (timestampSecEnd - timestampSecStart) < float.Epsilon; } }
public double TimestampSecStart { get { return timestampSecStart; } }
public double TimestampSecEnd { get { return timestampSecEnd; } }
double timestampSecStart;
double timestampSecEnd;
double timestampSecEnd1;
double timestampSecEnd2;
double timestampSecEnd3;
public bool NoSamples { get { return (TimestampSecEnd - TimestampSecStart) < float.Epsilon; } }
/// Test start volume for metrology in seconds
public double TimestampSecStart { get { return TimeFromSamples(optoData, optoDataCount, TestStartTelegramIx, StartEndFilterSamplesCount2); } }
/// Test end time for metrology in seconds
public double TimestampSecEnd { get { return TimeFromSamples(optoData, optoDataCount, TestEndTelegramIx, StartEndFilterSamplesCount2); } }
///
/// Indices to determine centers of start / end samples
///
public int TestStartTelegramIx;
public int TestEndTelegramIx;
int endTelegramIdx1;
int endTelegramIdx2;
int endTelegramIdx3;
int currentTelegramIx;
bool startSampleAcquired;
public int TestStartTelegramIx;
public int TestEndTelegramIx;
OptoTelegramRaw[] optoData;
@@ -589,23 +591,11 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
{
/// Take the test start sample
startSampleAcquired = true;
volumeLtrStart = volumeLtr;
timestampSecStart = timestampSec;
TestStartTelegramIx = currentTelegramIx;
}
else if (startSampleAcquired)
{
/// Shift data in pipelines
volumeLtrEnd = volumeLtrEnd3;
volumeLtrEnd3 = volumeLtrEnd2;
volumeLtrEnd2 = volumeLtrEnd1;
volumeLtrEnd1 = volumeLtr;
timestampSecEnd = timestampSecEnd3;
timestampSecEnd3 = timestampSecEnd2;
timestampSecEnd2 = timestampSecEnd1;
timestampSecEnd1 = timestampSec;
TestEndTelegramIx = endTelegramIdx3;
endTelegramIdx3 = endTelegramIdx2;
endTelegramIdx2 = endTelegramIdx1;
@@ -650,7 +640,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
{
resultCode |= (int)Results.Entities.ResultCode.MissingOptoData;
}
else if (volumeLtrEnd == volumeLtrStart)
else if (VolumeLtrEnd == VolumeLtrStart)
{
resultCode |= (int)Results.Entities.ResultCode.OptoDataWithZeroFlow;
}
@@ -967,6 +957,63 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
}
}
/// <summary>
/// Calculate a filtered volume from data stream samples
/// </summary>
/// <param name="unwrappedIx">Samples used in calculation are centered around unwrappedIx</param>
/// <param name="samplesCount2">Count of samples used in calculation is 2 * smaplesCount2 + 1</param>
/// <returns>Filtered volume</returns>
double VolumeFromSamples(OptoTelegramRaw[] optoData, int optoDataCount, int unwrappedIx, double scalingFactor, int samplesCount2 = 0)
{
if (samplesCount2 < 0) samplesCount2 = 0;
if ((unwrappedIx - samplesCount2) < 0 || (unwrappedIx + samplesCount2) >= optoDataCount) return 0;
Int64 sum = 0;
for (int i = unwrappedIx - samplesCount2; i <= unwrappedIx + samplesCount2; i++)
{
int wrappedIx = OptoTelegramRaw.BufferIdx(i);
if (optoData[wrappedIx].Flags != OptoTelegramFlags.OK &&
optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestStart &&
optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestEnd)
{
return 0;
}
sum += optoData[wrappedIx].VolumeRawExt;
}
return 0.0000625 * scalingFactor * sum / (double)(2 * samplesCount2 + 1);
}
/// <summary>
/// Calculate a filtered time from data stream samples
/// </summary>
/// <param name="unwrappedIx">Samples used in calculation are centered around unwrappedIx</param>
/// <param name="samplesCount2">Count of samples used in calculation is 2 * smaplesCount2 + 1</param>
/// <returns>Filtered time</returns>
double TimeFromSamples(OptoTelegramRaw[] optoData, int optoDataCount, int unwrappedIx, int samplesCount2 = 0)
{
if (samplesCount2 < 0) samplesCount2 = 0;
if ((unwrappedIx - samplesCount2) < 0 || (unwrappedIx + samplesCount2) >= optoDataCount) return 0;
Int64 sum = 0;
for (int i = unwrappedIx - samplesCount2; i <= unwrappedIx + samplesCount2; i++)
{
int wrappedIx = OptoTelegramRaw.BufferIdx(i);
if (optoData[wrappedIx].Flags != OptoTelegramFlags.OK &&
optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestStart &&
optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestEnd)
{
return 0;
}
sum += optoData[wrappedIx].TimestampExt;
}
return sum / (double)(8192 * (2 * samplesCount2 + 1));
}
public void WriteBinary(BinaryWriter writer)
{