init
This commit is contained in:
@@ -0,0 +1,682 @@
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace DTS.Common.DAS.Concepts
|
||||
{
|
||||
public class LinearizationFormula
|
||||
{
|
||||
private bool _bIsValid;
|
||||
public bool IsValid() { return _bIsValid; }
|
||||
public void MarkValid(bool bValid)
|
||||
{
|
||||
_bIsValid = bValid;
|
||||
}
|
||||
|
||||
|
||||
// Translation
|
||||
public NonLinearSLICEWareStyles NonLinearSliceWareStyle
|
||||
{
|
||||
get => (NonLinearSLICEWareStyles)NonLinearStyle;
|
||||
set => NonLinearStyle = (NonLinearStyles)value;
|
||||
}
|
||||
|
||||
public NonLinearStyles NonLinearStyle { get; set; } = NonLinearStyles.Polynomial; // Dont make the default style one that locks a specific zero-method FB 10323
|
||||
|
||||
public double PolynomialSensitivity { get; set; } = 1D;
|
||||
|
||||
public double LinearizationExponent { get; set; } = 1D;
|
||||
|
||||
/// <summary>
|
||||
/// THIS IS MM/V, (UI has already been updated, we need to update the variable name)
|
||||
/// </summary>
|
||||
private double _mmPerMV;
|
||||
public double MMPerV
|
||||
{
|
||||
get => _mmPerMV;
|
||||
set => _mmPerMV = value;
|
||||
}
|
||||
|
||||
public double MVAt0MM { get; set; }
|
||||
|
||||
public double Slope { get; set; }
|
||||
|
||||
public double Intercept { get; set; }
|
||||
|
||||
public double CalibrationFactor { get; set; }
|
||||
|
||||
public double ZeroPositionIntercept { get; set; }
|
||||
|
||||
public LinearizationFormula()
|
||||
{
|
||||
ZeroPositionIntercept = 0D;
|
||||
CalibrationFactor = 0D;
|
||||
Intercept = 0D;
|
||||
_coefficients = new List<double>(new double[] { 0, 0, 0, 0 });
|
||||
_exponents = new List<double>(new double[] { 0, 1, 2, 3 });
|
||||
}
|
||||
|
||||
public LinearizationFormula(LinearizationFormula copy)
|
||||
{
|
||||
UsemVOverVForPolys = copy.UsemVOverVForPolys;
|
||||
_bIsValid = copy._bIsValid;
|
||||
_coefficients = new List<double>(copy._coefficients.ToArray());
|
||||
_exponents = new List<double>(copy._exponents.ToArray());
|
||||
Intercept = copy.Intercept;
|
||||
LinearizationExponent = copy.LinearizationExponent;
|
||||
_mmPerMV = copy._mmPerMV;
|
||||
MVAt0MM = copy.MVAt0MM;
|
||||
Slope = copy.Slope;
|
||||
NonLinearStyle = copy.NonLinearStyle;
|
||||
_coefficients = new List<double>(copy._coefficients);
|
||||
_exponents = new List<double>(copy._exponents);
|
||||
PolynomialSensitivity = copy.PolynomialSensitivity;
|
||||
ZeroPositionIntercept = copy.ZeroPositionIntercept;
|
||||
CalibrationFactor = copy.CalibrationFactor;
|
||||
}
|
||||
public double GetCoefficient(double exponent)
|
||||
{
|
||||
for (var i = 0; i < _exponents.Count && i < _coefficients.Count; i++)
|
||||
{
|
||||
if (_exponents[i] == exponent) { return _coefficients[i]; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public void SetCoefficient(double exponent, double coefficient)
|
||||
{
|
||||
for (var i = 0; i < _exponents.Count && i < _coefficients.Count; i++)
|
||||
{
|
||||
if (_exponents[i] == exponent) { _coefficients[i] = coefficient; return; }
|
||||
}
|
||||
}
|
||||
public double GetLinearizedValue(double input, double excitation)
|
||||
{
|
||||
if (NonLinearStyle != NonLinearStyles.Polynomial && input <= 0)
|
||||
{
|
||||
//ir-tracc should never be < 0, however we may get readings less than zero due to
|
||||
//noise and other factors, treat these as positive near to zero
|
||||
input = .001;
|
||||
}
|
||||
//first linearize
|
||||
input /= 1000D;//assume input is in mV and we want it in Volts
|
||||
input = Math.Pow(input, LinearizationExponent);
|
||||
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
return GetEUDiagnosticsZero(input);
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
return GetEUIRTraccManual(input);
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
return GetEUZeroMMmV(input);
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
return GetEUAverageOverTime(input);
|
||||
case NonLinearStyles.Polynomial:
|
||||
return GetEUPolynomial(input, excitation);
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
return GetEUIRTraccCalFactor(input);
|
||||
default:
|
||||
throw new NotSupportedException("unknown format: " + NonLinearStyle);
|
||||
}
|
||||
}
|
||||
private double GetEUIRTraccCalFactor(double volts)
|
||||
{
|
||||
return volts * CalibrationFactor + ZeroPositionIntercept;
|
||||
}
|
||||
private double GetEUIRTraccManual(double volts)
|
||||
{
|
||||
return (volts - Intercept) / Slope;
|
||||
}
|
||||
|
||||
public bool UsemVOverVForPolys { get; set; }
|
||||
|
||||
private double GetEUZeroMMmV(double volts)
|
||||
{
|
||||
var input = MVAt0MM / 1000D;
|
||||
input = Math.Pow(input, LinearizationExponent);
|
||||
if (double.IsNaN(input) || double.IsNegativeInfinity(input) || double.IsPositiveInfinity(input))
|
||||
{
|
||||
return volts * MMPerV;
|
||||
}
|
||||
return (volts * MMPerV - MMPerV * input);
|
||||
}
|
||||
private List<double> _coefficients = new List<double>();
|
||||
private List<double> _exponents = new List<double>();
|
||||
private double GetEUPolynomial(double volts, double excitation)
|
||||
{
|
||||
//per J2517
|
||||
//3.4 Use of the Calibration Coefficients
|
||||
//The potentiometer assembly should be re-installed in the dummy without any mechanical adjustment of the
|
||||
//potentiometer. Prior to a crash test, the original zero offset level must be preserved by either not zeroing the
|
||||
//potentiometer (by signal conditioning or post-processing) or the amount that was zeroed must be added during postprocessing.
|
||||
//During the test the absolute voltage output time history should be recorded. This voltage signal is then
|
||||
//converted to engineering units by:
|
||||
//1. Convert voltage signal to mV/V at the sensor. This is the sensor reading S.
|
||||
//2. Convert the sensor reading S to displacement D by using the equation:
|
||||
//D = A*S^3 + B*S^2 + C*S + M (Eq. 2)
|
||||
//where:
|
||||
//D is the displacement relative to the thorax design position in mm
|
||||
//S is the sensor output reading in mV/V
|
||||
//A, B, C, and M are the calibration coefficients
|
||||
//NOTE: Make sure to use sufficient significant digits on all coefficients to assure accuracy of the conversion to
|
||||
//engineering units. It is recommended to use 5 significant digits (example 0.000012345).
|
||||
|
||||
//double mV = volts * 1000D;
|
||||
//double gain = 1D;
|
||||
//mV = mV / (gain * excitation);
|
||||
|
||||
//if (0 != PolynomialSensitivity && 1!= PolynomialSensitivity) { mV /= PolynomialSensitivity; }
|
||||
//double eu = 0D;
|
||||
//for (int i = 0; i < _coefficients.Count && i < _exponents.Count; i++)
|
||||
//{
|
||||
// eu += _coefficients[i] * Math.Pow(mV, _exponents[i]);
|
||||
//}
|
||||
//return eu;
|
||||
|
||||
//CHANGED FOR GM TESTING
|
||||
|
||||
if (0 != PolynomialSensitivity && 1 != PolynomialSensitivity)
|
||||
{
|
||||
volts /= PolynomialSensitivity;
|
||||
}
|
||||
|
||||
var voltsOverV = 0D;
|
||||
if (UsemVOverVForPolys)
|
||||
{
|
||||
//convert to mV first
|
||||
voltsOverV = (volts * 1000D) / excitation;
|
||||
}
|
||||
else
|
||||
{
|
||||
//used by GM
|
||||
voltsOverV = volts / excitation;
|
||||
}
|
||||
double eu = 0;
|
||||
|
||||
for (var i = 0; i < _coefficients.Count && i < _exponents.Count; i++)
|
||||
{
|
||||
if (_exponents[i] != 0)
|
||||
{
|
||||
eu += _coefficients[i] * Math.Pow(voltsOverV, _exponents[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
eu += _coefficients[i];
|
||||
}
|
||||
}
|
||||
return eu;
|
||||
}
|
||||
/// <summary>
|
||||
/// MvAt0MM set at diagnostics
|
||||
/// </summary>
|
||||
/// <param name="volts"></param>
|
||||
/// <returns></returns>
|
||||
private double GetEUDiagnosticsZero(double volts)
|
||||
{
|
||||
//double input = MVAt0MM/1000D;
|
||||
//input = System.Math.Pow(input,LinearizationExponent);
|
||||
var input = double.NaN;
|
||||
if (double.IsNaN(input) || double.IsPositiveInfinity(input) || double.IsNegativeInfinity(input))
|
||||
{
|
||||
return volts * MMPerV;
|
||||
}
|
||||
return volts * MMPerV - MMPerV * input;
|
||||
}
|
||||
/// <summary>
|
||||
/// MVAt0MM set by diagnostics and then later on at
|
||||
/// Average Over Time
|
||||
/// </summary>
|
||||
/// <param name="volts"></param>
|
||||
/// <returns></returns>
|
||||
private double GetEUAverageOverTime(double volts)
|
||||
{
|
||||
//double input = MVAt0MM / 1000D;
|
||||
//input = System.Math.Pow(input, LinearizationExponent);
|
||||
var input = double.NaN;
|
||||
if (double.IsNaN(input) || double.IsNegativeInfinity(input) || double.IsPositiveInfinity(input))
|
||||
{
|
||||
return volts * MMPerV;
|
||||
}
|
||||
return volts * MMPerV - MMPerV * input;
|
||||
}
|
||||
|
||||
|
||||
public string ToSLICEWareSerializeString()
|
||||
{
|
||||
if (!_bIsValid) { return ""; }
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendFormat("{0}_", NonLinearStyle);
|
||||
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
sb.Append(ToIRTraccDiagnosticZeroString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
sb.Append(ToIRTraccManualString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
sb.Append(ToIRTraccZeroMMmVString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
sb.Append(ToIRTraccAverageOverTimeString());
|
||||
break;
|
||||
case NonLinearStyles.Polynomial:
|
||||
sb.Append(ToSLICEWarePolynomialString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
throw new NotSupportedException("CalFactor not supported in SLICEWare");
|
||||
default:
|
||||
throw new NotSupportedException("unknown type: " + NonLinearStyle);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// serializes to a string of the format "c0xe0 c1xe1...cnxen"
|
||||
/// this will allow us arbitrary length polynomials and fractional exponents.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToSerializeString()
|
||||
{
|
||||
if (!_bIsValid) { return ""; }
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendFormat("{0}_", NonLinearStyle);
|
||||
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
sb.Append(ToIRTraccDiagnosticZeroString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
sb.Append(ToIRTraccManualString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
sb.Append(ToIRTraccZeroMMmVString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
sb.Append(ToIRTraccAverageOverTimeString());
|
||||
break;
|
||||
case NonLinearStyles.Polynomial:
|
||||
sb.Append(ToPolynomialString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
sb.Append(ToIRTraccCalFactorString());
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("unknown type: " + NonLinearStyle);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
public string ToIRTraccDiagnosticZeroString()
|
||||
{
|
||||
return $"{MMPerV.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public string ToIRTraccCalFactorString()
|
||||
{
|
||||
return $"{CalibrationFactor.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{ZeroPositionIntercept.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public void FromIRTraccCalFactorString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 3) { throw new NotSupportedException("Invalid CalFactor format: " + s); }
|
||||
|
||||
CalibrationFactor = double.Parse(tokens[0], culture);
|
||||
LinearizationExponent = double.Parse(tokens[1], culture);
|
||||
ZeroPositionIntercept = double.Parse(tokens[2], culture);
|
||||
}
|
||||
public void FromIRTraccDiagnosticZeroString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 2) { throw new NotSupportedException("Invalid DiagnosticsZero format: " + s); }
|
||||
MMPerV = double.Parse(tokens[0], culture);
|
||||
LinearizationExponent = double.Parse(tokens[1], culture);
|
||||
}
|
||||
public string ToIRTraccManualString()
|
||||
{
|
||||
return $"{Slope.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{Intercept.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public void FromIRTraccManualString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 3) { throw new NotSupportedException("Invalid IRTraccManual format: " + s); }
|
||||
Slope = double.Parse(tokens[0], culture);
|
||||
Intercept = double.Parse(tokens[1], culture);
|
||||
LinearizationExponent = double.Parse(tokens[2], culture);
|
||||
}
|
||||
public string ToIRTraccZeroMMmVString()
|
||||
{
|
||||
return $"{MMPerV.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{MVAt0MM.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public string ToSLICEWarePolynomialString()
|
||||
{
|
||||
//SLICEWare is the reverse order of our DataPRO Database
|
||||
var sb = new StringBuilder();
|
||||
for (var i = _exponents.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (i != _exponents.Count - 1) { sb.Append(","); }
|
||||
sb.AppendFormat("{0}x{1}", _coefficients[i].ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
_exponents[i].ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
sb.AppendFormat(",S={0}", PolynomialSensitivity.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
return sb.ToString();
|
||||
}
|
||||
public string ToPolynomialString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (var i = 0; i < _coefficients.Count && i < _exponents.Count; i++)
|
||||
{
|
||||
if (i > 0) { sb.Append(","); }
|
||||
sb.AppendFormat("{0}x{1}", _coefficients[i].ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
_exponents[i].ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
sb.AppendFormat(",S={0},mV={1}",
|
||||
PolynomialSensitivity.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
UsemVOverVForPolys.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
public double[] PolynomialCoefficients
|
||||
{
|
||||
get => _coefficients.ToArray();
|
||||
set => _coefficients = new List<double>(value);
|
||||
}
|
||||
public double[] PolynomialExponents
|
||||
{
|
||||
get => _exponents.ToArray();
|
||||
set => _exponents = new List<double>(value);
|
||||
}
|
||||
public string ToIRTraccAverageOverTimeString()
|
||||
{
|
||||
return $"{MMPerV.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public void FromIRTraccAverageOverTimeString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 2) { throw new NotSupportedException("Invalid IRTRaccAverageOverTime format: " + s); }
|
||||
MMPerV = double.Parse(tokens[0], culture);
|
||||
LinearizationExponent = double.Parse(tokens[1], culture);
|
||||
}
|
||||
public void FromIRTraccZeroMMmVString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 3) { throw new NotSupportedException("Invalid IRTraccZeroMMmV format: " + s); }
|
||||
MMPerV = double.Parse(tokens[0], culture);
|
||||
MVAt0MM = double.Parse(tokens[1], culture);
|
||||
LinearizationExponent = double.Parse(tokens[2], culture);
|
||||
}
|
||||
public void FromPolynomialString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
_coefficients.Clear();
|
||||
_exponents.Clear();
|
||||
|
||||
var tokens = s.Split(',');
|
||||
foreach (var t in tokens)
|
||||
{
|
||||
var subtokens = t.Split('x');
|
||||
if (2 == subtokens.Length)
|
||||
{
|
||||
if (double.TryParse(subtokens[0], System.Globalization.NumberStyles.Float, culture, out var d))
|
||||
{
|
||||
_coefficients.Add(d);
|
||||
_exponents.Add(double.Parse(subtokens[1], culture));
|
||||
}
|
||||
else
|
||||
{
|
||||
PolynomialSensitivity = double.Parse(subtokens[1], culture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
subtokens = t.Split('=');
|
||||
if (subtokens.Length == 2)
|
||||
{
|
||||
switch (subtokens[0])
|
||||
{
|
||||
case "S":
|
||||
PolynomialSensitivity = double.Parse(subtokens[1], culture);
|
||||
break;
|
||||
case "mV":
|
||||
UsemVOverVForPolys = Convert.ToBoolean(subtokens[1], culture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void FromSerializeString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s)) { _bIsValid = false; return; }
|
||||
if (s.Equals("1") || s.Equals("0") || s.Equals("1 ")) { _bIsValid = false; return; }
|
||||
|
||||
var tokens = s.Split('_');
|
||||
if (tokens.Length < 2) { throw new NotSupportedException("unsupported Linearization Formula Format"); }
|
||||
var style = (NonLinearStyles)Enum.Parse(typeof(NonLinearStyles), tokens[0], true);
|
||||
NonLinearStyle = style;
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
FromIRTraccDiagnosticZeroString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
FromIRTraccManualString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
FromIRTraccZeroMMmVString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.Polynomial:
|
||||
FromPolynomialString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
FromIRTraccAverageOverTimeString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
FromIRTraccCalFactorString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("Unknown format: " + NonLinearStyle);
|
||||
}
|
||||
}
|
||||
public void FromSerializeString(string s)
|
||||
{
|
||||
FromSerializeString(s, System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public void FromTDCSerializeString()
|
||||
{
|
||||
_bIsValid = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will return a display string for a nonlinear calibration based on N4 formating
|
||||
/// </summary>
|
||||
public string ToDisplayString()
|
||||
{
|
||||
return ToDisplayString("N4");
|
||||
}
|
||||
/// <summary>
|
||||
/// Will return a display string for a nonlinear calibration based on 1st paramater formating string
|
||||
/// </summary>
|
||||
/// <param name="nonlinearFormat"></param>
|
||||
/// <returns></returns>
|
||||
public string ToDisplayString(string nonlinearFormat)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nonlinearFormat)) { nonlinearFormat = "N4"; }
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.Polynomial:
|
||||
{
|
||||
return ToPolynomial(nonlinearFormat);
|
||||
}
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
{
|
||||
return $"mV = {MVAt0MM:n4}, {MMPerV:n4}*(V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})";
|
||||
}
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
{
|
||||
return $"((V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})-{Intercept:n4})/{Slope:n4}";
|
||||
}
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
{
|
||||
return $"{MMPerV:n4}*(V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})";
|
||||
}
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
{
|
||||
return $"{MMPerV:n4}*(V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})";
|
||||
}
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
{
|
||||
return $"{ZeroPositionIntercept:n4}+{CalibrationFactor:n4}*(V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})";
|
||||
}
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
private string ToPolynomial(string nonlinearFormat)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nonlinearFormat)) { nonlinearFormat = "N4"; }
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var termNumber = PolynomialCoefficients.Length - 1;
|
||||
foreach (var x in PolynomialCoefficients)
|
||||
{
|
||||
if (PolynomialCoefficients[termNumber] != 0)
|
||||
{
|
||||
var coeff = PolynomialCoefficients[termNumber];
|
||||
|
||||
// Let the appended math symbol handle sign unless we're the first term.
|
||||
if (termNumber != PolynomialCoefficients.Length - 1)
|
||||
{
|
||||
coeff = Math.Abs(coeff);
|
||||
}
|
||||
sb.Append(coeff.ToString(nonlinearFormat));
|
||||
if (PolynomialExponents[termNumber] != 0)
|
||||
{
|
||||
sb.Append("x");
|
||||
if (PolynomialExponents[termNumber] != 1)
|
||||
{
|
||||
sb.Append(ToSuperScript(PolynomialExponents[termNumber].ToString("N0")));
|
||||
}
|
||||
}
|
||||
if (termNumber > 0)
|
||||
{
|
||||
// Coerricients are Displayed in absolute value. We need to combine the sign with the addition symbol
|
||||
sb.Append(PolynomialCoefficients[termNumber - 1] > 0 ? " + " : " - ");
|
||||
}
|
||||
}
|
||||
termNumber--;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
private string ToSuperScript(string source)
|
||||
{
|
||||
var superScript = new StringBuilder();
|
||||
|
||||
foreach (var c in source)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '-':
|
||||
superScript.Append('\u207B');
|
||||
break;
|
||||
case '.':
|
||||
superScript.Append('\u00B7');
|
||||
break;
|
||||
case '1':
|
||||
superScript.Append('\u00B9');
|
||||
break;
|
||||
case '2':
|
||||
superScript.Append('\u00B2');
|
||||
break;
|
||||
case '3':
|
||||
superScript.Append('\u00B3');
|
||||
break;
|
||||
case '4':
|
||||
superScript.Append('\u2074');
|
||||
break;
|
||||
case '5':
|
||||
superScript.Append('\u2075');
|
||||
break;
|
||||
case '6':
|
||||
superScript.Append('\u2076');
|
||||
break;
|
||||
case '7':
|
||||
superScript.Append('\u2077');
|
||||
break;
|
||||
case '8':
|
||||
superScript.Append('\u2078');
|
||||
break;
|
||||
case '9':
|
||||
superScript.Append('\u2079');
|
||||
break;
|
||||
case '0':
|
||||
superScript.Append('\u2070');
|
||||
break;
|
||||
case '\'':
|
||||
superScript.Append('\u02C8');
|
||||
break;
|
||||
case ',':
|
||||
superScript.Append('\u22C5'); // there is no unicode superscript comma. this comes close
|
||||
break;
|
||||
case '\u00A0':
|
||||
superScript.Append('\u2009'); // unicode 'thin' space
|
||||
break;
|
||||
default:
|
||||
superScript.Append('\u207F');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return superScript.ToString();
|
||||
}
|
||||
/*
|
||||
* we are given an equation in the form of y = ax^1 + b, except x and y are backwards for us (y=V where we'd prefer X was voltage, so we switch it)
|
||||
* y/a - b/a = x, and then switch y and x, (1/a)x^1 -(b/a)x^0 = y
|
||||
* now we want to get the coefficient of the first equation, which is "a", we get this by taking the inverse
|
||||
* we get b on the other hand by taking -1 * (b/a)*a. if we have the "coefficient", we have a
|
||||
*/
|
||||
/*
|
||||
public double GetIRTraccCoefficient()
|
||||
{
|
||||
foreach (Factor f in Factors)
|
||||
{
|
||||
if (f.Exponent == 1D) { return System.Math.Pow(f.Coefficient, -1); }
|
||||
}
|
||||
return 1D; //0 doesn't make sense for ir
|
||||
}
|
||||
public double GetIRTraccConstant()
|
||||
{
|
||||
foreach (Factor f in Factors)
|
||||
{
|
||||
if (f.Exponent == 0D) { return -1D * GetIRTraccCoefficient() * f.Coefficient; }
|
||||
}
|
||||
return 0D;
|
||||
}
|
||||
public void SetIRTraccFactor(double coefficient, double constant)
|
||||
{
|
||||
if (0 == coefficient)
|
||||
{
|
||||
//well this doesn't make any sense ...
|
||||
coefficient = 1;
|
||||
}
|
||||
Factors = new Factor[]
|
||||
{
|
||||
new Factor(1/coefficient,1),
|
||||
new Factor(-constant/coefficient,0),
|
||||
};
|
||||
}*/
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user