using System; using System.Collections.Generic; using System.Globalization; using DTS.Common.DAS.Concepts; using DTS.Common.Enums.Sensors; using DTS.Common.Utilities; using DTS.Common.Utilities.Logging; namespace DTS.Serialization.TDM { public class ChannelHeader { internal const int MAX_HEADER_LINES = 15; internal const int DAS_LINE = 0; internal const int CAPACITY_LINE = 1; internal const int EU_LINE = 2; internal const int SENSOR_SN_LINE = 3; internal const int SENSITIVITY_LINE = 4; internal const int EXCITATION_LINE = 5; internal const int MIN_LINE = 6; internal const int MAX_LINE = 7; internal const int TOYOTA_CALC1_LINE = 8; internal const int TOYOTA_CALC2_LINE = 9; internal const int TOYOTA_CALC3_LINE = 10; internal const int KNEE_POINT_LINE = 11; internal const int STRANGE_DATA_FLAG_LINE = 12; internal const int CHANNEL_CODE_LINE = 13; internal const int CHANNEL_JCODE_LINE = 14; public void WriteChannelHeaderToString(Writer writer, System.IO.TextWriter tw, bool bFiltered, double start, double end) { var test = writer.Test; writer.IncrementDone(2); var HeaderLines = new string[MAX_HEADER_LINES]; for (var i = 0; i < MAX_HEADER_LINES; i++) { HeaderLines[i] = ""; } var testChannels = new List(test.Channels); for (var i = 0; i < testChannels.Count; i++) { if (testChannels[i] is Test.Module.AnalogInputChannel) { var channel = testChannels[i] as Test.Module.AnalogInputChannel; if (channel.IsSquibVoltage()) { continue; } var startSampleNumber = start * channel.ParentModule.SampleRateHz + channel.ParentModule.TriggerSampleNumbers[0]; var endSampleNumber = end * channel.ParentModule.SampleRateHz + channel.ParentModule.TriggerSampleNumbers[0]; if (startSampleNumber < channel.ParentModule.StartRecordSampleNumber) { startSampleNumber = channel.ParentModule.StartRecordSampleNumber; } if (endSampleNumber > channel.ParentModule.NumberOfSamples + (double)channel.ParentModule.StartRecordSampleNumber) { endSampleNumber = channel.ParentModule.StartRecordSampleNumber + (double)channel.ParentModule.NumberOfSamples; } var startSample = Convert.ToInt32(startSampleNumber - channel.ParentModule.StartRecordSampleNumber); var endSample = Convert.ToInt32(endSampleNumber - channel.ParentModule.StartRecordSampleNumber - 1); if (channel.IsDigital()) { HeaderLines[DAS_LINE] = string.Format("{0},{1}", HeaderLines[DAS_LINE], channel.HardwareChannelName); HeaderLines[CAPACITY_LINE] = string.Format("{0},{1}", HeaderLines[CAPACITY_LINE], 1); HeaderLines[EU_LINE] = string.Format("{0},{1}", HeaderLines[EU_LINE], "Digital"); HeaderLines[SENSOR_SN_LINE] = string.Format("{0},{1}", HeaderLines[SENSOR_SN_LINE], channel.HardwareChannelName); } else if (channel.IsSquib()) { HeaderLines[DAS_LINE] = string.Format("{0},{1}", HeaderLines[DAS_LINE], channel.HardwareChannelName); HeaderLines[CAPACITY_LINE] = string.Format("{0},{1}", HeaderLines[CAPACITY_LINE], 10); //hardcoded per TDM cpp file HeaderLines[EU_LINE] = string.Format("{0},{1}", HeaderLines[EU_LINE], channel.EngineeringUnits.TrimEnd()); HeaderLines[SENSOR_SN_LINE] = string.Format("{0},{1}", HeaderLines[SENSOR_SN_LINE], channel.HardwareChannelName); } else { HeaderLines[DAS_LINE] = string.Format("{0},{1}", HeaderLines[DAS_LINE], channel.HardwareChannelName); if (channel.ProportionalToExcitation || (channel.SensorCapacity == 0)) { HeaderLines[CAPACITY_LINE] = string.Format("{0},{1}", HeaderLines[CAPACITY_LINE], channel.DesiredRange); } else { HeaderLines[CAPACITY_LINE] = string.Format("{0},{1}", HeaderLines[CAPACITY_LINE], channel.SensorCapacity); } HeaderLines[EU_LINE] = string.Format("{0},{1}", HeaderLines[EU_LINE], channel.EngineeringUnits.TrimEnd()); HeaderLines[SENSOR_SN_LINE] = string.Format("{0},{1}", HeaderLines[SENSOR_SN_LINE], channel.SerialNumber); } if (channel.IsSquib()) { HeaderLines[SENSITIVITY_LINE] = string.Format("{0},{1:0.000000000000}", HeaderLines[SENSITIVITY_LINE], 1D); } else { HeaderLines[SENSITIVITY_LINE] = string.Format("{0},{1:0.000000000000}", HeaderLines[SENSITIVITY_LINE], channel.Sensitivity); } if (channel.IsSquib()) { HeaderLines[EXCITATION_LINE] = string.Format("{0},{1}", HeaderLines[EXCITATION_LINE], (5D).ToString("e4", CultureInfo.InvariantCulture)); } else if (channel.IsDigital()) { HeaderLines[EXCITATION_LINE] = string.Format("{0},{1}", HeaderLines[EXCITATION_LINE], (1D).ToString("e4", CultureInfo.InvariantCulture)); } else { HeaderLines[EXCITATION_LINE] = string.Format("{0},{1}", HeaderLines[EXCITATION_LINE], channel.MeasuredExcitationVoltageValid ? channel.MeasuredExcitationVoltage.ToString("e4", CultureInfo.InvariantCulture) : channel.FactoryExcitationVoltageValid ? channel.FactoryExcitationVoltage.ToString("e4", CultureInfo.InvariantCulture) : (5D).ToString("e4", CultureInfo.InvariantCulture)); } var dMin = double.MaxValue; var dMax = double.MinValue; var scaler = new DataScaler(); scaler.IsInverted = channel.IsInverted;//channel is DTS.Common.DAS.Concepts.DAS.Channel.IInversionAware ? (channel as DTS.Common.DAS.Concepts.DAS.Channel.IInversionAware).IsInverted : false; scaler.SetLinearizationFormula(channel.LinearizationFormula); scaler.SetScaleFactorMv(channel.Data.ScaleFactorMv); scaler.SetScaleFactorEU(channel.Data.ScaleFactorEU); scaler.SetUseEUScaleFactors(channel.Data.UseEUScaleFactors); scaler.UnitConversion = channel.UnitConversion; scaler.BasedOnOutputAtCapacity = channel.AtCapacity; scaler.CapacityOutputIsBasedOn = channel.CapacityOutputIsBasedOn; scaler.SensitivityUnits = channel.SensitivityUnits; scaler.IEPE = channel.Bridge == SensorConstants.BridgeType.IEPE; scaler.Digital = channel.Bridge == SensorConstants.BridgeType.DigitalInput; scaler.SetLinearizationFormula(channel.LinearizationFormula); scaler.SetDigitalMultiplier(channel.DigitalMultiplier); scaler.Digital = channel.IsDigital(); scaler.DigitalMode = channel.DigitalMode; scaler.SetMvPerEu(channel.Data.MvPerEu); var analogChannel = channel; try { scaler.SetInitialOffset(analogChannel.InitialOffset); scaler.ZeroMethodType = analogChannel.ZeroMethod; if (analogChannel.RemoveOffset) { scaler.SetRemovedADC(channel.RemovedADC); scaler.SetRemovedInternalADC(channel.RemovedInternalADC); } else { scaler.SetRemovedADC(0); scaler.SetRemovedInternalADC(0); } scaler.SetDataZeroLevelADC(channel.DataZeroLevelAdc); scaler.SetZeroMvInADC(channel.ZeroMvInADC); try { scaler.SetWindowAverageADC(channel.WindowAverageADC); } catch (Exception) { } } catch (Exception) { } scaler.NominalExcitationVoltage = analogChannel.ExcitationVoltage; if (analogChannel.MeasuredExcitationVoltageValid) { try { scaler.MeasuredExcitationVoltage = analogChannel.MeasuredExcitationVoltage; } catch { }; } if (analogChannel.FactoryExcitationVoltageValid) { try { scaler.FactoryExcitationVoltage = analogChannel.FactoryExcitationVoltage; } catch { }; } scaler.ProportionalToExcitation = channel.ProportionalToExcitation; if (bFiltered) { for (var curSample = startSample; curSample <= endSample; curSample++) { var d = channel.Sensitivity * scaler.GetEU(writer.FilteredData[i].Data[Convert.ToUInt64(curSample)]); dMin = Math.Min(dMin, d); dMax = Math.Max(dMax, d); } } else { for (var curSample = startSample; curSample <= endSample; curSample++) { try { var d = channel.Sensitivity * scaler.GetEU(channel.PersistentChannelInfo.Data[Convert.ToUInt64(curSample)]); dMin = Math.Min(dMin, d); dMax = Math.Max(dMax, d); } catch (IndexOutOfRangeException ex) { APILogger.Log("unexpected end in TDM export looking for min/max, ", ex); break; } } } HeaderLines[MIN_LINE] = string.Format("{0},{1}", HeaderLines[MIN_LINE], dMin.ToString("e4", CultureInfo.InvariantCulture)); HeaderLines[MAX_LINE] = string.Format("{0},{1}", HeaderLines[MAX_LINE], dMax.ToString("e4", CultureInfo.InvariantCulture)); //11344 The function of Cable Multiplier on Analog Channels in TTS import is not ready yet //var cableMultipler = "0"; //default in the old code //if (!string.IsNullOrWhiteSpace(channel.UserValue2)) //{ // if (double.TryParse(channel.UserValue2, NumberStyles.Any, CultureInfo.InvariantCulture, // out var dTemp)) // { // cableMultipler = dTemp.ToString(CultureInfo.InvariantCulture); // } //} //22284 Use a hardcoded value of 1 for cable multiplier for TTS export HeaderLines[TOYOTA_CALC1_LINE] += $",1"; HeaderLines[TOYOTA_CALC2_LINE] += $",0"; HeaderLines[TOYOTA_CALC3_LINE] += ",0"; double softwareFrequency = 0; if (channel.IsSquib()) { softwareFrequency = 2000; } else { if (!string.IsNullOrEmpty(channel.SoftwareFilter)) { if (channel.SoftwareFilter.Contains("Hz")) { double d; if (double.TryParse(channel.SoftwareFilter.Replace("Hz", ""), out d)) { softwareFrequency = d; } } else { var coder = new DescriptionAttributeCoder(); foreach (ChannelFilter filterType in Enum.GetValues(typeof(ChannelFilter))) { if (coder.DecodeAttributeValue(filterType).Equals(channel.SoftwareFilter, StringComparison.OrdinalIgnoreCase)) { softwareFrequency = (double)filterType; break; } } } } } // This used to have manipulation logic, but no more. See http://fogbugz/fogbugz/default.asp?4594 HeaderLines[KNEE_POINT_LINE] = string.Format("{0},{1}", HeaderLines[KNEE_POINT_LINE], softwareFrequency); HeaderLines[STRANGE_DATA_FLAG_LINE] = string.Format("{0},{1}", HeaderLines[STRANGE_DATA_FLAG_LINE], channel.DataFlag); //7714 Remove " (Current)" from AIC channel name/description in TTS export. var chName = channel.UserCode; if (channel.IsSquibChannel) { chName = channel.ChannelName2; var index = chName.IndexOf(" (Current)"); if (index >= 0) { chName = chName.Substring(0, index); } } HeaderLines[CHANNEL_CODE_LINE] = string.Format("{0},{1}", HeaderLines[CHANNEL_CODE_LINE], chName); var description = channel.UserChannelName; if (channel.IsSquib()) { description = channel.ChannelDescriptionString; var index = description.IndexOf(" (Current)"); if (index >= 0) { description = description.Remove(index, 10); } } HeaderLines[CHANNEL_JCODE_LINE] = string.Format("{0},{1}", HeaderLines[CHANNEL_JCODE_LINE], description); } } foreach (var line in HeaderLines) { tw.WriteLine("{0},", line); } } } }