init
This commit is contained in:
@@ -0,0 +1,518 @@
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System.Globalization;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class CalibrationRecords : ICalibrationRecords
|
||||
{
|
||||
public ICalibrationRecord[] Records { get; set; } = new CalibrationRecord[] { new CalibrationRecord() };
|
||||
|
||||
public CalibrationRecords(ICalibrationRecords copy)
|
||||
{
|
||||
var records = new CalibrationRecord[copy.Records.Length];
|
||||
for (var i = 0; i < copy.Records.Length; i++)
|
||||
{
|
||||
records[i] = new CalibrationRecord(copy.Records[i]);
|
||||
}
|
||||
|
||||
Records = records;
|
||||
}
|
||||
|
||||
public CalibrationRecords()
|
||||
{
|
||||
Records = new CalibrationRecord[] { new CalibrationRecord() };
|
||||
}
|
||||
|
||||
public CalibrationRecords(string records)
|
||||
{
|
||||
FromSerializedString(records);
|
||||
}
|
||||
|
||||
public bool IsEqual(object obj, ISensorCalibration sc)
|
||||
{
|
||||
if (obj is CalibrationRecords r)
|
||||
{
|
||||
if (r.Records.Length != Records.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < r.Records.Length; i++)
|
||||
{
|
||||
if (!r.Records[i].IsEqual(Records[i], sc))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public void FromSerializedString(string s)
|
||||
{
|
||||
var tokens = s.Split(new string[] { MySeparator }, StringSplitOptions.None);
|
||||
for (var i = 0; i < tokens.Length; i++)
|
||||
{
|
||||
tokens[i] = tokens[i].Replace(MySeparatorBackup, MySeparator);
|
||||
}
|
||||
|
||||
var records = new List<CalibrationRecord>();
|
||||
foreach (string token in tokens)
|
||||
{
|
||||
records.Add(new CalibrationRecord(token));
|
||||
}
|
||||
|
||||
Records = records.ToArray();
|
||||
}
|
||||
|
||||
private const string MySeparator = "__x__";
|
||||
private const string MySeparatorBackup = "___xx___";
|
||||
|
||||
public string ToSerializedString(ISensorCalDbRecord sc)
|
||||
{
|
||||
var records = new List<string>();
|
||||
|
||||
foreach (var r in Records)
|
||||
{
|
||||
records.Add(r.ToSerializedString(sc));
|
||||
}
|
||||
|
||||
for (var i = 0; i < records.Count; i++)
|
||||
{
|
||||
System.Diagnostics.Trace.Assert(!records[i].Contains(MySeparatorBackup));
|
||||
records[i] = records[i].Replace(MySeparator, MySeparatorBackup);
|
||||
}
|
||||
|
||||
return string.Join(MySeparator, records.ToArray());
|
||||
}
|
||||
|
||||
public string ToDisplayString(ISensorCalibration sc, ISensorCalibration previous, string linearFormat, string nonlinearFormat)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < Records.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
var r = Records[i];
|
||||
ICalibrationRecord r2 = null;
|
||||
|
||||
if (null != previous)
|
||||
{
|
||||
if (i < previous.Records.Records.Length)
|
||||
{
|
||||
r2 = previous.Records.Records[i];
|
||||
}
|
||||
}
|
||||
|
||||
var s = r.ToDisplayString(sc, r2, previous, linearFormat, nonlinearFormat);
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
{
|
||||
sb.Append(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class CalibrationRecord : ICalibrationRecord
|
||||
{
|
||||
public double Sensitivity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ZeroPoint is used to hold the calibration certificate field for 2D/3D IR-TRACC cal certs
|
||||
/// it is used to zero the IR-TRACC and POT data prior to being fed into the 3D equations
|
||||
/// </summary>
|
||||
private double _zeroPoint = 0D;
|
||||
|
||||
public double ZeroPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
if (false == Equals(Poly.CalibrationFactor, 0.0))
|
||||
{
|
||||
// This field is always calculated. Do not return stored value unless we are unable to calculate
|
||||
return Poly.ZeroPositionIntercept / Poly.CalibrationFactor;
|
||||
}
|
||||
|
||||
return _zeroPoint;
|
||||
}
|
||||
set => _zeroPoint = value;
|
||||
}
|
||||
|
||||
public LinearizationFormula Poly { get; set; }
|
||||
|
||||
public bool AtCapacity { get; set; } = false;
|
||||
|
||||
public string EngineeringUnits { get; set; } = "g";
|
||||
|
||||
public SensorConstants.SensUnits SensitivityUnits { get; set; } = SensorConstants.SensUnits.NONE;
|
||||
|
||||
public ExcitationVoltageOptions.ExcitationVoltageOption Excitation { get; set; } = ExcitationVoltageOptions.ExcitationVoltageOption.Volt5;
|
||||
|
||||
public double CapacityOutputIsBasedOn { get; set; } = 1.000;
|
||||
|
||||
public InitialOffsetTypes InitialOffsetMethod { get; set; } = InitialOffsetTypes.EU;
|
||||
|
||||
public string ISOCode { get; set; } = String.Empty;
|
||||
|
||||
private enum Fields
|
||||
{
|
||||
Sensitivity,
|
||||
Poly,
|
||||
AtCapacity,
|
||||
EngineeringUnits,
|
||||
Excitation,
|
||||
CapacityOutputIsBasedOn,
|
||||
SensitivityUnits,
|
||||
ZeroPoint,
|
||||
ISOCode
|
||||
};
|
||||
|
||||
public string ToSerializedString(ISensorCalDbRecord parentCal)
|
||||
{
|
||||
var tokens = new List<string>();
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.AtCapacity:
|
||||
tokens.Add(AtCapacity.ToString());
|
||||
break;
|
||||
case Fields.EngineeringUnits:
|
||||
tokens.Add(EngineeringUnits);
|
||||
break;
|
||||
case Fields.Excitation:
|
||||
tokens.Add(Excitation.ToString());
|
||||
break;
|
||||
case Fields.Poly:
|
||||
Poly.MarkValid(parentCal.NonLinear);
|
||||
if (parentCal.LinearAdded)
|
||||
{
|
||||
//We have a mixed-sensitivity sensor. Mark the first CR valid, kill the rest
|
||||
for (var i = 0; i < parentCal.Records.Records.Length; i++)
|
||||
{
|
||||
parentCal.Records.Records[i].Poly.MarkValid(i == 0);
|
||||
}
|
||||
}
|
||||
|
||||
tokens.Add(Poly.ToSerializeString());
|
||||
break;
|
||||
case Fields.Sensitivity:
|
||||
tokens.Add(Sensitivity.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case Fields.CapacityOutputIsBasedOn:
|
||||
tokens.Add(CapacityOutputIsBasedOn.ToString());
|
||||
break;
|
||||
case Fields.SensitivityUnits:
|
||||
tokens.Add(SensitivityUnits.ToString());
|
||||
break;
|
||||
case Fields.ZeroPoint:
|
||||
tokens.Add(ZeroPoint.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case Fields.ISOCode:
|
||||
if (!string.IsNullOrWhiteSpace(ISOCode)) tokens.Add(ISOCode);
|
||||
break;
|
||||
default: throw new NotSupportedException("unknown CalibrationRecord field: " + field.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < tokens.Count; i++)
|
||||
{
|
||||
if (null == tokens[i])
|
||||
{
|
||||
tokens[i] = "";
|
||||
}
|
||||
|
||||
tokens[i] = tokens[i].Replace(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator,
|
||||
"x_Separator_x");
|
||||
}
|
||||
|
||||
return string.Join(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator,
|
||||
tokens.ToArray());
|
||||
}
|
||||
|
||||
public string ToDisplayString(ISensorCalibration sc, ICalibrationRecord previous, ISensorCalibration sc2, string linearFormat, string nonlinearFormat)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.AtCapacity:
|
||||
if (null == previous || AtCapacity != previous.AtCapacity)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_AtCapacity, AtCapacity);
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.EngineeringUnits:
|
||||
if (null == previous || false == EngineeringUnits.Equals(previous.EngineeringUnits))
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_EngineeringUnits, EngineeringUnits);
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.Excitation:
|
||||
if (null == previous || sc.IsProportional != sc2.IsProportional || Excitation != previous.Excitation)
|
||||
{
|
||||
if (sc.IsProportional)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1:0.0}", Strings.Strings.SensorFields_Excitation,
|
||||
GetExcitationVoltageMagnitudeFromEnum(Excitation));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.Poly:
|
||||
if (null == previous || sc.NonLinear || sc.NonLinear != sc2.NonLinear)
|
||||
{
|
||||
if (sc.NonLinear)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_NonLinearFormat,
|
||||
Poly.ToDisplayString(nonlinearFormat));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.Sensitivity:
|
||||
if (null == previous || Sensitivity != previous.Sensitivity)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_Sensitivity,
|
||||
Sensitivity.ToString(linearFormat));
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.CapacityOutputIsBasedOn:
|
||||
if (false == AtCapacity)
|
||||
{
|
||||
if (null == previous || CapacityOutputIsBasedOn != previous.CapacityOutputIsBasedOn)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_CapacityOutputIsBasedOn,
|
||||
CapacityOutputIsBasedOn);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.SensitivityUnits:
|
||||
if (null == previous || false == SensitivityUnits.Equals(previous.SensitivityUnits))
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_SensitivityUnits, SensitivityUnits);
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.ZeroPoint:
|
||||
if (null == previous || ZeroPoint != previous.ZeroPoint)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_ZeroPoint, ZeroPoint);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
public bool IsEqual(object obj, ISensorCalibration sc)
|
||||
{
|
||||
if (obj is CalibrationRecord r)
|
||||
{
|
||||
return r.ToSerializedString(sc) == ToSerializedString(sc);
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public void FromString(string s)
|
||||
{
|
||||
var tokens = s.Split(new string[] { CultureInfo.InvariantCulture.TextInfo.ListSeparator },
|
||||
StringSplitOptions.None);
|
||||
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
|
||||
for (var i = 0; i < tokens.Length && i < fields.Length; i++)
|
||||
{
|
||||
var token = tokens[i].Replace("x_Separator_x",
|
||||
CultureInfo.InvariantCulture.TextInfo.ListSeparator);
|
||||
switch (fields[i])
|
||||
{
|
||||
case Fields.AtCapacity:
|
||||
AtCapacity = Convert.ToBoolean(token);
|
||||
break;
|
||||
case Fields.EngineeringUnits:
|
||||
EngineeringUnits = token;
|
||||
break;
|
||||
case Fields.Excitation:
|
||||
Excitation =
|
||||
(ExcitationVoltageOptions.ExcitationVoltageOption)Enum.Parse(
|
||||
typeof(ExcitationVoltageOptions.ExcitationVoltageOption), token);
|
||||
break;
|
||||
case Fields.Poly:
|
||||
Poly = new LinearizationFormula();
|
||||
Poly.FromSerializeString(token);
|
||||
break;
|
||||
case Fields.Sensitivity:
|
||||
Sensitivity = Convert.ToDouble(token, System.Globalization.CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Fields.CapacityOutputIsBasedOn:
|
||||
CapacityOutputIsBasedOn = Convert.ToDouble(token);
|
||||
break;
|
||||
case Fields.SensitivityUnits:
|
||||
if (Enum.TryParse(token, out SensorConstants.SensUnits unit))
|
||||
{
|
||||
SensitivityUnits = unit;
|
||||
}
|
||||
else { APILogger.Log($"failed to parse sensitivity units: {token} from {s}"); }
|
||||
break;
|
||||
case Fields.ZeroPoint:
|
||||
ZeroPoint = Convert.ToDouble(token, System.Globalization.CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Fields.ISOCode:
|
||||
ISOCode = token;
|
||||
break;
|
||||
default: throw new NotSupportedException("unknown CalibrationRecord field: " + fields.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CalibrationRecord(string s)
|
||||
{
|
||||
FromString(s);
|
||||
}
|
||||
|
||||
public CalibrationRecord(ICalibrationRecord copy)
|
||||
{
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.AtCapacity:
|
||||
AtCapacity = copy.AtCapacity;
|
||||
break;
|
||||
case Fields.EngineeringUnits:
|
||||
EngineeringUnits = copy.EngineeringUnits;
|
||||
break;
|
||||
case Fields.Excitation:
|
||||
Excitation = copy.Excitation;
|
||||
break;
|
||||
case Fields.Poly:
|
||||
Poly = new LinearizationFormula(copy.Poly);
|
||||
break;
|
||||
case Fields.Sensitivity:
|
||||
Sensitivity = copy.Sensitivity;
|
||||
break;
|
||||
case Fields.CapacityOutputIsBasedOn:
|
||||
CapacityOutputIsBasedOn = copy.CapacityOutputIsBasedOn;
|
||||
break;
|
||||
case Fields.SensitivityUnits:
|
||||
SensitivityUnits = copy.SensitivityUnits;
|
||||
break;
|
||||
case Fields.ZeroPoint:
|
||||
ZeroPoint = copy.ZeroPoint;
|
||||
break;
|
||||
case Fields.ISOCode:
|
||||
ISOCode = copy.ISOCode;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("unknown calibrationrecord field: " + field.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CalibrationRecord()
|
||||
{
|
||||
Poly = new LinearizationFormula();
|
||||
}
|
||||
|
||||
//helpers moved from DAS.Concepts
|
||||
public static double GetExcitationVoltageMagnitudeFromEnum(ExcitationVoltageOptions.ExcitationVoltageOption target)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ExcitationVoltageOptions.VoltageMagnitudeAttributeCoder().DecodeAttributeValue(target);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("encountered problem attempting to get excitation voltage magnitude from enum", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static ExcitationVoltageOptions.ExcitationVoltageOption GetExcitationVoltageEnumFromMagnitude(double magnitude)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ExcitationVoltageOptions.VoltageMagnitudeAttributeCoder().EncodeAttributeValue(magnitude);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("encountered problem attempting to get excitation voltage enum from magnitude", ex);
|
||||
return ExcitationVoltageOptions.ExcitationVoltageOption.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user