iPerlHead : TimeFromSamples( ), VolumeFromSamples( ), StartEndFilterSamplesCount = 20
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user