1280 lines
66 KiB
C#
1280 lines
66 KiB
C#
/*
|
|
* DTS.Slice.Control.Event.cs
|
|
*
|
|
* Copyright © 2009
|
|
* Diversified Technical Systems, Inc.
|
|
* All Rights Reserved
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using DTS.Common.DASResource;
|
|
using DTS.Common.SerializationPlus;
|
|
using DTS.DASLib.Service;
|
|
using DTS.Serialization;
|
|
using DTS.Common.Utilities;
|
|
using DTS.Common.Utilities.DotNetProgrammingConstructs;
|
|
using DTS.Common.Utilities.Logging;
|
|
using DTS.Common.Enums.Sensors;
|
|
using System.Linq;
|
|
using DTS.Common.Enums.DASFactory;
|
|
using DTS.Common.Interface.DASFactory.Config;
|
|
using DTS.Common.Interface.DASFactory;
|
|
|
|
namespace DTS.Slice.Control
|
|
{
|
|
/// <summary>
|
|
/// Slice control representation of all information related to a slice event.
|
|
/// </summary>
|
|
public partial class Event
|
|
: Exceptional,
|
|
Test.IConvertable
|
|
{
|
|
/// <summary>
|
|
/// Get/set the <see cref="string"/> Id for this event.
|
|
/// </summary>
|
|
public string Id
|
|
{
|
|
get => _Id.Value;
|
|
set => _Id.Value = value;
|
|
}
|
|
private readonly Property<string> _Id = new Property<string>("DTS.Slice.Control.Event.Id", null, false);
|
|
|
|
/// <summary>
|
|
/// Get/set the description <see cref="string"/> for this event.
|
|
/// </summary>
|
|
public string Description
|
|
{
|
|
get => _Description.Value;
|
|
set => _Description.Value = value;
|
|
}
|
|
private readonly Property<string> _Description = new Property<string>("DTS.Slice.Control.Event.Description", null, false);
|
|
//FB 18312 added event number
|
|
/// <summary>
|
|
/// Get/set the EventNumber <see cref="string"/> for this event.
|
|
/// </summary>
|
|
public int EventNumber
|
|
{
|
|
get => _EventNumber.Value;
|
|
set => _EventNumber.Value = value;
|
|
}
|
|
private readonly Property<int> _EventNumber = new Property<int>("DTS.Slice.Control.Event.EventNumber", 0, false);
|
|
|
|
/// <summary>
|
|
/// The globally unique identification string for this event.
|
|
/// </summary>
|
|
public Guid Guid
|
|
{
|
|
get => _Guid.Value;
|
|
set => _Guid.Value = value;
|
|
}
|
|
private readonly Property<Guid> _Guid
|
|
= new Property<Guid>(typeof(Event).Namespace + ".Event.Guid", new Guid("00000000-0000-0000-0000-000000000000"), true);
|
|
|
|
/// <summary>
|
|
/// The global Fault Flags for this event.
|
|
/// </summary>
|
|
public UInt16 FaultFlags
|
|
{
|
|
get => _FaultFlags.Value;
|
|
set => _FaultFlags.Value = value;
|
|
}
|
|
private readonly Property<UInt16> _FaultFlags
|
|
= new Property<UInt16>(typeof(Event).Namespace + ".Event.FaultFlags", 0, true);
|
|
|
|
/// <summary>
|
|
/// the global extended fault flags for this event
|
|
/// </summary>
|
|
public uint ExtendedFaultFlags1
|
|
{
|
|
get => _ExtendedFaultFlags1.Value;
|
|
set => _ExtendedFaultFlags1.Value = value;
|
|
}
|
|
private readonly Property<uint> _ExtendedFaultFlags1
|
|
= new Property<uint>(typeof(Event).Namespace + ".Event.ExtendedFaultFlags1", 0, true);
|
|
|
|
public uint ExtendedFaultFlags2
|
|
{
|
|
get => _ExtendedFaultFlags2.Value;
|
|
set => _ExtendedFaultFlags2.Value = value;
|
|
}
|
|
private readonly Property<uint> _ExtendedFaultFlags2
|
|
= new Property<uint>(typeof(Event).Namespace + ".Event.ExtendedFaultFlags2", 0, true);
|
|
|
|
public uint ExtendedFaultFlags3
|
|
{
|
|
get => _ExtendedFaultFlags3.Value;
|
|
set => _ExtendedFaultFlags3.Value = value;
|
|
}
|
|
private readonly Property<uint> _ExtendedFaultFlags3
|
|
= new Property<uint>(typeof(Event).Namespace + ".Event.ExtendedFaultFlags3", 0, true);
|
|
|
|
public uint ExtendedFaultFlags4
|
|
{
|
|
get => _ExtendedFaultFlags4.Value;
|
|
set => _ExtendedFaultFlags4.Value = value;
|
|
}
|
|
private readonly Property<uint> _ExtendedFaultFlags4
|
|
= new Property<uint>(typeof(Event).Namespace + ".Event.ExtendedFaultFlags4", 0, true);
|
|
/// <summary>
|
|
/// Get the date of this object's creation. Expected to be populated with the creation
|
|
/// date of the serialization from which this object has been generated.
|
|
/// </summary>
|
|
public DateTime InceptionDate
|
|
{
|
|
get => _InceptionDate.Value;
|
|
private set => _InceptionDate.Value = value;
|
|
}
|
|
private readonly Property<DateTime> _InceptionDate
|
|
= new Property<DateTime>(
|
|
typeof(Event).Namespace + ".Event.InceptionDate",
|
|
DateTime.Now,
|
|
false
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get/set this event's list of <see cref="DTS.Slice.Control.Event.Module"/>s.
|
|
/// </summary>
|
|
public List<Module> Modules
|
|
{
|
|
get => _Modules.Value;
|
|
set => _Modules.Value = value;
|
|
}
|
|
private readonly Property<List<Module>> _Modules = new Property<List<Module>>("DTS.Slice.Control.Event.Modules", null, false);
|
|
|
|
/// <summary>
|
|
/// Get/set this event's list of calculatedchannels/>s.
|
|
/// </summary>
|
|
public List<Module.Channel> CalculatedChannels
|
|
{
|
|
get => _CalculatedChannels.Value;
|
|
set => _CalculatedChannels.Value = value;
|
|
}
|
|
private readonly Property<List<Module.Channel>> _CalculatedChannels = new Property<List<Module.Channel>>("DTS.Slice.Control.Event.CalculatedChannels", null, false);
|
|
|
|
/// <summary>
|
|
/// Initialize an instance of the DTS.Slice.Control.Event class.
|
|
/// </summary>
|
|
public Event()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialize an instance of the DTS.Slice.Control.Event class.
|
|
/// </summary>
|
|
///
|
|
/// <param name="id">
|
|
/// The <see cref="string"/> ID of this event.
|
|
/// </param>
|
|
///
|
|
/// <param name="description">
|
|
/// The <see cref="string"/> description of this event.
|
|
/// </param>
|
|
///
|
|
public Event(string id, string description)
|
|
{
|
|
try
|
|
{
|
|
Id = id;
|
|
Description = description;
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception(
|
|
string.Format(
|
|
Strings.DTS_Slice_Control_Event_ConstructionFailedString, GetType().FullName),
|
|
ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialize an instance of the DTS.Slice.Control.Event class.
|
|
|
|
/// </summary>
|
|
///
|
|
/// <param name="test">
|
|
/// The <see cref="DTS.Serialization.Test"/> to initialize this object with.
|
|
/// </param>
|
|
/// <param name="reportErrors"></param>
|
|
public Event(Test test, Test.ReportErrors reportErrors)
|
|
{
|
|
try
|
|
{
|
|
FromDtsSerializationTest(test, reportErrors);
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialize an instance of the DTS.Slice.Control.Event class.
|
|
/// </summary>
|
|
///
|
|
/// <param name="id">
|
|
/// The <see cref="string"/> ID of this event.
|
|
/// </param>
|
|
///
|
|
/// <param name="description">
|
|
/// The <see cref="string"/> description of this event.
|
|
/// </param>
|
|
///
|
|
/// <param name="modules">
|
|
/// The list of <see cref="DTS.Slice.Control.Event.Module"/>s associated with this event.
|
|
/// </param>
|
|
///
|
|
public Event(string id, string description, List<Module> modules)
|
|
{
|
|
try
|
|
{
|
|
Id = id;
|
|
Description = description;
|
|
Modules = modules;
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception(
|
|
string.Format(
|
|
Strings.DTS_Slice_Control_Event_ConstructionFailedString, GetType().FullName),
|
|
ex);
|
|
}
|
|
}
|
|
|
|
// xxx Event ID, start sample, stop sample,
|
|
|
|
// xxx Keep a double hash of DAS->Channel... looks like it would probably bypass the
|
|
// module concept since the API just returns based on
|
|
// Also need to add thread protection.
|
|
|
|
// xxx Can we set locks in the property accessors for this stuff? At least for the
|
|
// data methods... should the constructor need just an enclosure, or a lambda that
|
|
// takes a dictionary lookup...
|
|
|
|
/// <summary>
|
|
/// Get a named-DAS/numbered-module accessor to this Event's modules.
|
|
/// </summary>
|
|
public DasModuleAccessor DasModules
|
|
{
|
|
get => _DasModules.Value;
|
|
private set => _DasModules.Value = value;
|
|
}
|
|
private readonly Property<DasModuleAccessor> _DasModules
|
|
= new Property<DasModuleAccessor>(
|
|
typeof(Event).Namespace + ".Event.DasModules",
|
|
new DasModuleAccessor(),
|
|
true
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get a named-DAS/numbered-channel accessor to this Event's channels.
|
|
/// </summary>
|
|
public DasChannelAccessor DasChannels
|
|
{
|
|
get => _DasChannels.Value;
|
|
private set => _DasChannels.Value = value;
|
|
}
|
|
private readonly Property<DasChannelAccessor> _DasChannels
|
|
= new Property<DasChannelAccessor>(
|
|
typeof(Event).Namespace + ".Event.DasChannels",
|
|
new DasChannelAccessor(),
|
|
true
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get a named-DAS/numbered-module/numbered-channel accessor to this Event's channels.
|
|
/// </summary>
|
|
public DasModuleChannelAccessor DasModuleChannels
|
|
{
|
|
get => _DasModuleChannels.Value;
|
|
private set => _DasModuleChannels.Value = value;
|
|
}
|
|
private readonly Property<DasModuleChannelAccessor> _DasModuleChannels
|
|
= new Property<DasModuleChannelAccessor>(
|
|
typeof(Event).Namespace + ".Event.DasModules",
|
|
new DasModuleChannelAccessor(),
|
|
true
|
|
);
|
|
public static bool IsG5(IDASCommunication idas)
|
|
{
|
|
return idas.SerialNumber.StartsWith("5M");
|
|
}
|
|
|
|
|
|
public static bool IsSlice6DBModule(Module module)
|
|
{
|
|
if (null != module && null != module.Description && module.Description.ToLower() == DTS.Common.Constants.DUMMY_MOD_DESCRIP_S6DB)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
public static bool IsPowerProModule(Module module)
|
|
{
|
|
if (null != module && null != module.Description && module.Description.ToLower() == DTS.Common.Constants.DUMMY_MOD_DESCRIP_POWERPRO)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const string ClockModule = "clock module";
|
|
public static bool IsClockModule(Module module)
|
|
{
|
|
if (null != module?.Description && module.Description.ToLower() == ClockModule)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const string StreamInModule = "stream in module";
|
|
public static bool IsStreamInModule(Module module)
|
|
{
|
|
if (null != module?.Description && module.Description.ToLower() == StreamInModule)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
private static void CorrectTestIds(Dictionary<string, TestInformation> lookup)
|
|
{
|
|
var goodIds = lookup.Values.FirstOrDefault(x => !string.IsNullOrEmpty(x.Id) && !DFConstantsAndEnums.GENERIC_SPFD_GUID.Equals(x.Id));
|
|
if (null == goodIds) { return; }
|
|
foreach( var val in lookup.Values)
|
|
{
|
|
if (DFConstantsAndEnums.GENERIC_SPFD_GUID.Equals(val.Id))
|
|
{
|
|
val.Id = goodIds.Id;
|
|
val.Description = goodIds.Description;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Initialize an instance of the DTS.Slice.Control.Event class.
|
|
/// </summary>
|
|
///
|
|
/// <param name="dases">
|
|
/// A list of connected devices that will be used
|
|
/// to determine the dimensions of the Event's internal structures.
|
|
/// </param>
|
|
/// <param name="info"></param>
|
|
public Event(List<IDASCommunication> dases, EventInfoAggregate info)
|
|
{
|
|
try
|
|
{
|
|
if (null == dases)
|
|
throw new ArgumentNullException(Strings.DTS_Slice_Control_Event_Event_NullDasListString);
|
|
if (0 >= dases.Count)
|
|
throw new Exception(Strings.DTS_Slice_Control_Event_Event_EmptyDasListString);
|
|
Modules = new List<Module>();
|
|
var dasTestInformations = new Dictionary<string, TestInformation>();
|
|
var absoluteChannelNumber = 0;
|
|
|
|
var hasCan = dases.Exists(x => x.GetHardwareType() == Common.Enums.Hardware.HardwareTypes.SLICE_PRO_CAN_FD);
|
|
|
|
foreach (var das in dases)
|
|
{
|
|
var eventIndex = info.GetEventIndex(das);
|
|
if (null == das.SerialNumber)
|
|
throw new UserException("Slice API returned no serial number for passed DAS"); // (connect string: " + ( null != das.DASInfo. das.ConnectString ? das.ConnectString : "<NULL>" ) + ")" );
|
|
if (null == das.EventInfo)
|
|
throw new UserException("Slice API returned no EventInfo for passed DAS");
|
|
if (null == das.EventInfo.Events[eventIndex])
|
|
throw new UserException("Slice API returned no configuration data for passed DAS"); // \"" + ( null != das.Comm.SensorSerialNumber ? das.Comm.SensorSerialNumber : "<NULL>" ) + "\"" );
|
|
var eventInfo = das.EventInfo.Events[eventIndex];
|
|
|
|
dasTestInformations.Add(das.SerialNumber, new TestInformation(eventInfo.TestID, eventInfo.Description ?? ""));
|
|
DasModules.Add(das.SerialNumber, new List<Module>());
|
|
DasChannels.Add(das.SerialNumber, new List<Module.Channel>());
|
|
DasModuleChannels.Add(das.SerialNumber, new ModuleChannelAccessor());
|
|
|
|
if (null != eventInfo.Modules)
|
|
{
|
|
var moduleList = new List<IDASModule>(eventInfo.Modules);
|
|
foreach (var iDASModule in moduleList)
|
|
{
|
|
var dasModule = (DASModule)iDASModule;
|
|
//Add entries for empty slots in a TDAS rack
|
|
while (dasModule.ModuleArrayIndex > DasModules[das.SerialNumber].Count)
|
|
{
|
|
Module emptyModule;
|
|
Modules.Add(emptyModule = new Module(this));
|
|
|
|
DasModules[das.SerialNumber].Add(emptyModule);
|
|
}
|
|
|
|
Module nextModule;
|
|
Modules.Add(nextModule = new Module(this));
|
|
|
|
DasModules[das.SerialNumber].Add(nextModule);
|
|
DasModuleChannels[das.SerialNumber].Add(dasModule.ModuleArrayIndex, new ChannelAccessor());
|
|
|
|
// I think this can be done for everyone (and is the right thing), but for now make it TDAS PRO Rack specific
|
|
if (das is EthernetTDAS)
|
|
{
|
|
// We want module to be the actual SIM or TOM serial number, not the rack serial number
|
|
nextModule.DasSerialNumber = das.DASInfo.Modules[dasModule.ModuleArrayIndex].SerialNumber;
|
|
}
|
|
else
|
|
{
|
|
nextModule.DasSerialNumber = das.SerialNumber;
|
|
}
|
|
// This is an important condition if they module property population that occurs after
|
|
// this constructor using the dasModules object is going to line thing up right.
|
|
Debug.Assert(DasModules[das.SerialNumber].Count - 1 == dasModule.ModuleArrayIndex);
|
|
|
|
// Maybe these should be getting populated later on using the SetPropertiesFrom(x) after
|
|
// the query download successfully returns...?
|
|
nextModule.Description = dasModule.Description;
|
|
nextModule.AaFilterRateHz = dasModule.AAFilterRateHz;
|
|
nextModule.Number = dasModule.ModuleArrayIndex;
|
|
nextModule.NumberOfSamples = dasModule.NumberOfSamples;
|
|
nextModule.RequestedPostTriggerSeconds = dasModule.RequestedPostTriggerSeconds;
|
|
nextModule.RequestedPreTriggerSeconds = dasModule.RequestedPreTriggerSeconds;
|
|
nextModule.PostTriggerSeconds = dasModule.PostTriggerSeconds;
|
|
nextModule.PreTriggerSeconds = dasModule.PreTriggerSeconds;
|
|
nextModule.RecordingMode = dasModule.RecordingMode;
|
|
nextModule.SampleRateHz = dasModule.SampleRateHz;
|
|
nextModule.StartRecordSampleNumber = dasModule.StartRecordSampleNumber;
|
|
nextModule.BaseSerialNumber = dasModule.OwningDAS.SerialNumber;
|
|
nextModule.StartRecordTimestampSec = dasModule.StartRecordTimestampSec;
|
|
nextModule.StartRecordTimestampNanoSec = dasModule.StartRecordTimestampNanoSec;
|
|
nextModule.TriggerTimestampSec = dasModule.TriggerTimestampSec;
|
|
nextModule.TriggerTimestampNanoSec = dasModule.TriggerTimestampNanoSec;
|
|
nextModule.PTPMasterSync = dasModule.PTPMasterSync;
|
|
if (dasModule.UseForTiltCalculation)
|
|
{
|
|
nextModule.SystemID = dasModule.SystemID;
|
|
nextModule.SystemLocation = dasModule.SystemLocation;
|
|
nextModule.TargetAxisOne = dasModule.TargetAxisOne;
|
|
nextModule.TargetAxisTwo = dasModule.TargetAxisTwo;
|
|
switch (dasModule.TiltAxes)
|
|
{
|
|
case DFConstantsAndEnums.TiltAxes.IXIYIZ:
|
|
case DFConstantsAndEnums.TiltAxes.IXIYZ:
|
|
case DFConstantsAndEnums.TiltAxes.IXYIZ:
|
|
case DFConstantsAndEnums.TiltAxes.IXYZ:
|
|
case DFConstantsAndEnums.TiltAxes.XIYIZ:
|
|
case DFConstantsAndEnums.TiltAxes.XIYZ:
|
|
case DFConstantsAndEnums.TiltAxes.XYIZ:
|
|
case DFConstantsAndEnums.TiltAxes.XYZ:
|
|
switch (dasModule.AxisIgnored)
|
|
{
|
|
case 1:
|
|
nextModule.TiltSensorAxisXDegreesPre = double.NaN;
|
|
nextModule.TargetAxisX = double.NaN;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 2:
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisYDegreesPre = double.NaN;
|
|
nextModule.TargetAxisY = double.NaN;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 3:
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisTwo;
|
|
nextModule.TiltSensorAxisZDegreesPre = double.NaN;
|
|
nextModule.TargetAxisZ = double.NaN;
|
|
break;
|
|
}
|
|
break;
|
|
case DFConstantsAndEnums.TiltAxes.IXIZIY:
|
|
case DFConstantsAndEnums.TiltAxes.IXIZY:
|
|
case DFConstantsAndEnums.TiltAxes.IXZIY:
|
|
case DFConstantsAndEnums.TiltAxes.IXZY:
|
|
case DFConstantsAndEnums.TiltAxes.XIZIY:
|
|
case DFConstantsAndEnums.TiltAxes.XIZY:
|
|
case DFConstantsAndEnums.TiltAxes.XZIY:
|
|
case DFConstantsAndEnums.TiltAxes.XZY:
|
|
switch (dasModule.AxisIgnored)
|
|
{
|
|
case 1:
|
|
nextModule.TiltSensorAxisXDegreesPre = double.NaN;
|
|
nextModule.TargetAxisX = double.NaN;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 2:
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisZDegreesPre = double.NaN;
|
|
nextModule.TargetAxisZ = double.NaN;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 3:
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisTwo;
|
|
nextModule.TiltSensorAxisYDegreesPre = double.NaN;
|
|
nextModule.TargetAxisY = double.NaN;
|
|
break;
|
|
}
|
|
break;
|
|
case DFConstantsAndEnums.TiltAxes.IYIXIZ:
|
|
case DFConstantsAndEnums.TiltAxes.IYIXZ:
|
|
case DFConstantsAndEnums.TiltAxes.IYXIZ:
|
|
case DFConstantsAndEnums.TiltAxes.IYXZ:
|
|
case DFConstantsAndEnums.TiltAxes.YIXIZ:
|
|
case DFConstantsAndEnums.TiltAxes.YIXZ:
|
|
case DFConstantsAndEnums.TiltAxes.YXIZ:
|
|
case DFConstantsAndEnums.TiltAxes.YXZ:
|
|
switch (dasModule.AxisIgnored)
|
|
{
|
|
case 1:
|
|
nextModule.TiltSensorAxisYDegreesPre = double.NaN;
|
|
nextModule.TargetAxisY = double.NaN;
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 2:
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisXDegreesPre = double.NaN;
|
|
nextModule.TargetAxisX = double.NaN;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 3:
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisTwo;
|
|
nextModule.TiltSensorAxisZDegreesPre = double.NaN;
|
|
nextModule.TargetAxisZ = double.NaN;
|
|
break;
|
|
}
|
|
break;
|
|
case DFConstantsAndEnums.TiltAxes.IYIZIX:
|
|
case DFConstantsAndEnums.TiltAxes.IYIZX:
|
|
case DFConstantsAndEnums.TiltAxes.IYZIX:
|
|
case DFConstantsAndEnums.TiltAxes.IYZX:
|
|
case DFConstantsAndEnums.TiltAxes.YIZIX:
|
|
case DFConstantsAndEnums.TiltAxes.YIZX:
|
|
case DFConstantsAndEnums.TiltAxes.YZIX:
|
|
case DFConstantsAndEnums.TiltAxes.YZX:
|
|
switch (dasModule.AxisIgnored)
|
|
{
|
|
case 1:
|
|
nextModule.TiltSensorAxisYDegreesPre = double.NaN;
|
|
nextModule.TargetAxisY = double.NaN;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 2:
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisZDegreesPre = double.NaN;
|
|
nextModule.TargetAxisZ = double.NaN;
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 3:
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisTwo;
|
|
nextModule.TiltSensorAxisXDegreesPre = double.NaN;
|
|
nextModule.TargetAxisX = double.NaN;
|
|
break;
|
|
}
|
|
break;
|
|
case DFConstantsAndEnums.TiltAxes.IZIXIY:
|
|
case DFConstantsAndEnums.TiltAxes.IZIXY:
|
|
case DFConstantsAndEnums.TiltAxes.IZXIY:
|
|
case DFConstantsAndEnums.TiltAxes.IZXY:
|
|
case DFConstantsAndEnums.TiltAxes.ZIXIY:
|
|
case DFConstantsAndEnums.TiltAxes.ZIXY:
|
|
case DFConstantsAndEnums.TiltAxes.ZXIY:
|
|
case DFConstantsAndEnums.TiltAxes.ZXY:
|
|
switch (dasModule.AxisIgnored)
|
|
{
|
|
case 1:
|
|
nextModule.TiltSensorAxisZDegreesPre = double.NaN;
|
|
nextModule.TargetAxisZ = double.NaN;
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 2:
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisXDegreesPre = double.NaN;
|
|
nextModule.TargetAxisX = double.NaN;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 3:
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisTwo;
|
|
nextModule.TiltSensorAxisYDegreesPre = double.NaN;
|
|
nextModule.TargetAxisY = double.NaN;
|
|
break;
|
|
}
|
|
break;
|
|
case DFConstantsAndEnums.TiltAxes.IZIYIX:
|
|
case DFConstantsAndEnums.TiltAxes.IZIYX:
|
|
case DFConstantsAndEnums.TiltAxes.IZYIX:
|
|
case DFConstantsAndEnums.TiltAxes.IZYX:
|
|
case DFConstantsAndEnums.TiltAxes.ZIYIX:
|
|
case DFConstantsAndEnums.TiltAxes.ZIYX:
|
|
case DFConstantsAndEnums.TiltAxes.ZYIX:
|
|
case DFConstantsAndEnums.TiltAxes.ZYX:
|
|
switch (dasModule.AxisIgnored)
|
|
{
|
|
case 1:
|
|
nextModule.TiltSensorAxisZDegreesPre = double.NaN;
|
|
nextModule.TargetAxisZ = double.NaN;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 2:
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisYDegreesPre = double.NaN;
|
|
nextModule.TargetAxisY = double.NaN;
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TargetAxisX = dasModule.TargetAxisTwo;
|
|
break;
|
|
case 3:
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TargetAxisZ = dasModule.TargetAxisOne;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TargetAxisY = dasModule.TargetAxisTwo;
|
|
nextModule.TiltSensorAxisXDegreesPre = double.NaN;
|
|
nextModule.TargetAxisX = double.NaN;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
|
|
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
|
|
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
|
|
nextModule.TiltSensorAxisXDegreesPost = dasModule.TiltSensorAxisXDegreesPost;
|
|
nextModule.TiltSensorAxisYDegreesPost = dasModule.TiltSensorAxisYDegreesPost;
|
|
nextModule.TiltSensorAxisZDegreesPost = dasModule.TiltSensorAxisZDegreesPost;
|
|
}
|
|
nextModule.TemperatureLocation1Pre = dasModule.TemperatureLocation1Pre;
|
|
nextModule.TemperatureLocation2Pre = dasModule.TemperatureLocation2Pre;
|
|
nextModule.TemperatureLocation3Pre = dasModule.TemperatureLocation3Pre;
|
|
nextModule.TemperatureLocation4Pre = dasModule.TemperatureLocation4Pre;
|
|
nextModule.TemperatureLocation1Post = dasModule.TemperatureLocation1Post;
|
|
nextModule.TemperatureLocation2Post = dasModule.TemperatureLocation2Post;
|
|
nextModule.TemperatureLocation3Post = dasModule.TemperatureLocation3Post;
|
|
nextModule.TemperatureLocation4Post = dasModule.TemperatureLocation4Post;
|
|
|
|
nextModule.InputVoltage = dasModule.InputVoltage;
|
|
nextModule.BatteryVoltage = dasModule.BatteryVoltage;
|
|
|
|
nextModule.Channels = new List<Module.Channel>();
|
|
if (Array.TrueForAll(dasModule.Channels, ch => ch.ConfigurationMode == DFConstantsAndEnums.ConfigMode.Clock))
|
|
{
|
|
nextModule.Description = ClockModule;
|
|
}
|
|
if (Array.TrueForAll(dasModule.Channels, ch => ch.ConfigurationMode == DFConstantsAndEnums.ConfigMode.StreamIn))
|
|
{
|
|
nextModule.Description = StreamInModule;
|
|
}
|
|
var moduleType = dasModule.GetType();
|
|
if ((null != dasModule.Channels)
|
|
&& (dasModule.Channels.Length > 0)
|
|
&& (Array.Exists(dasModule.Channels, x => x.ConfigurationMode != DFConstantsAndEnums.ConfigMode.DummyArm)
|
|
|| IsG5(das)) // How could a SLICE be a G5? Is this the checking serial numbers for SLICE G5s?
|
|
)
|
|
{
|
|
var list = new List<IDASChannel>(dasModule.Channels);
|
|
foreach (var idasChannel in list)
|
|
{
|
|
var dasChannel = (DASChannel)idasChannel;
|
|
|
|
Module.Channel nextChannel = Module.Channel.CreateChannel(dasChannel, nextModule, absoluteChannelNumber++);
|
|
nextChannel.IsSupersampled = dasModule.IsEmbedded();
|
|
nextChannel.UseEUScaler = dasModule.IsEmbedded();
|
|
nextChannel.UnsupersampledSampleRateHz = dasModule.IsEmbedded() && dasModule.ModuleArrayIndex < dasModule.EmbeddedSampleRateHz.Length ?
|
|
dasModule.EmbeddedSampleRateHz[dasModule.ModuleArrayIndex] :
|
|
0;
|
|
nextModule.Channels.Add(nextChannel);
|
|
|
|
DasModuleChannels[das.SerialNumber][dasModule.ModuleArrayIndex].Add(dasChannel.ModuleChannelNumber, nextChannel);
|
|
|
|
nextChannel.Number = dasChannel.ModuleChannelNumber;
|
|
nextChannel.Start = dasChannel.EventStartTime;
|
|
//Debug.Assert( das.SensorSerialNumber.Equals( dasModule.OwningDAS.SensorSerialNumber, StringComparison.OrdinalIgnoreCase ) );
|
|
|
|
//if ( null == das.Comm.ChannelDiagnosticsResults )
|
|
// throw new DTS.Slice.Control.Event.Exception( "no diagnostics results were received from the API for module " + nextModule.Number.ToString( ) + ", channel " + nextChannel.Number.ToString( ) );
|
|
//else
|
|
{
|
|
nextChannel.UnfilteredData = new List<short>();
|
|
nextChannel.UnfilteredAlternateData =
|
|
!string.IsNullOrWhiteSpace(nextChannel.LinearSensorCalibration)
|
|
? new List<short>()
|
|
: null;
|
|
DasChannels[das.SerialNumber].Add(nextChannel);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (hasCan)
|
|
{
|
|
CorrectTestIds(dasTestInformations);
|
|
}
|
|
string testId = null;
|
|
string testDescription = null;
|
|
foreach (var dasId in dasTestInformations.Keys)
|
|
{ //
|
|
// Walk through the list and verify that all of the test ID and description
|
|
// strings are the same.
|
|
//
|
|
var newTestId = dasTestInformations[dasId].Id;
|
|
if (null != testId && !testId.Equals(newTestId, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
if (!newTestId.Equals(DFConstantsAndEnums.MADEUPEVENT_TESTID)
|
|
&& !testId.Equals(DFConstantsAndEnums.MADEUPEVENT_TESTID))
|
|
{
|
|
throw new Exception(
|
|
string.Format(
|
|
Strings.DTS_Slice_Control_Event_Event_DASTestIdMismatchString, testId, dasId, newTestId));
|
|
}
|
|
}
|
|
if (!newTestId.Equals(DFConstantsAndEnums.MADEUPEVENT_TESTID))
|
|
{
|
|
testId = newTestId;
|
|
}
|
|
|
|
var newTestDescription = dasTestInformations[dasId].Description;
|
|
|
|
if (null != testDescription
|
|
&& !testDescription.Equals(newTestDescription, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
/*throw new Exception(
|
|
string.Format(
|
|
Properties.Resources.DTS_Slice_Control_Event_Event_DASTestDescriptionMismatchString, testDescription, dasId, newTestDescription));*/
|
|
}
|
|
else { testDescription = newTestDescription; }
|
|
}
|
|
|
|
if (null == testId) { testId = "Empty"; }
|
|
if (null == testDescription) { testDescription = ""; }
|
|
|
|
if (null == testId || null == testDescription)
|
|
throw new Exception(Strings.DTS_Slice_Control_Event_Event_FailedToDetermineIdOrDescriptionFromConfigurationString);
|
|
Id = testId;
|
|
Description = testDescription;
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception(
|
|
string.Format(
|
|
Strings.DTS_Slice_Control_Event_ConstructionFailedString, GetType().FullName),
|
|
ex);
|
|
}
|
|
}
|
|
|
|
private bool IsTom(DASModule module)
|
|
{
|
|
try
|
|
{
|
|
if (module.SerialNumber().ToLower().Contains("tom"))
|
|
{
|
|
return true;
|
|
}
|
|
if (null != module.Channels && module.Channels.Length > 0)
|
|
{
|
|
if (module.Channels[0] is OutputSquibChannel) { return true; }
|
|
}
|
|
}
|
|
catch (System.Exception ex) { APILogger.Log("problem getting serial number", ex); }
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the highest <see cref="int"/> absolute channel number currently in this event.
|
|
/// </summary>
|
|
public int LastAbsoluteChannelNumberInEvent
|
|
{
|
|
get
|
|
{
|
|
try
|
|
{
|
|
var highestAbsoluteChannelNumberFound = -1;
|
|
foreach (var module in Modules)
|
|
foreach (var channel in module.Channels)
|
|
if (channel.AbsoluteNumber > highestAbsoluteChannelNumberFound)
|
|
highestAbsoluteChannelNumberFound = channel.AbsoluteNumber;
|
|
//if ( highestAbsoluteChannelNumberFound < 0 )
|
|
// throw new Event.Exception( "no absolute channel numbers exist within this event" );
|
|
return highestAbsoluteChannelNumberFound;
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception("encountered problem getting last absolute channel number in event", ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the <see cref="double"/> per-sample threshold that when exceeded by the total basic data
|
|
/// volume of this event results in Event.IsTooLargeFor32BitVisualization to return true.
|
|
/// </summary>
|
|
///
|
|
/// <remarks>
|
|
/// Justification for the current default value:
|
|
/// With filter caching disabled, the memory usage is AT LEAST 76.4 bytes/sample, broken down thus:
|
|
///
|
|
/// Event structure:
|
|
/// 1 sample needs 2 bytes ADC representation,
|
|
/// 8 bytes mV representation,
|
|
/// 8 bytes EU representation. Total: 18 bytes
|
|
/// +
|
|
/// Filtering procedure: 1 sample needs 8 bytes for initial double-sized "ToArray",
|
|
/// and 1.1 * ( 8 * 3 ) bytes for the three 5% padded front & end processing arrays
|
|
/// inside the algorithm. Total: 34.4 bytes
|
|
/// +
|
|
/// Viewer memory: 1 sample needs 8 bytes for the internal viewer representation
|
|
/// (at a minimum) + ( 2 * 8 ) bytes for the two arrays required to feed the viewer
|
|
/// interface. Total: 24 bytes
|
|
///
|
|
/// = 76.5 bytes/sample.
|
|
///
|
|
/// Not sure how much memory the rest of SliceWARE takes when up and running, but using this number
|
|
/// we seem to be okay if we stay below 1GB, but run into trouble when we go over if we first do other
|
|
/// things that might leave things around in memory, i.e., download. The three sections above pretty
|
|
/// much stack while loading a test into the viewer.
|
|
/// </remarks>
|
|
///
|
|
private static readonly double MaximumVisualizationBytesPerSample = 2D;
|
|
public double TooLargeFor32BitVisualizationBytesPerSampleThreshold
|
|
{
|
|
get => _TooLargeFor32BitVisualizationBytesPerSampleThreshold.Value;
|
|
private set => _TooLargeFor32BitVisualizationBytesPerSampleThreshold.Value = value;
|
|
}
|
|
private readonly Property<double> _TooLargeFor32BitVisualizationBytesPerSampleThreshold
|
|
= new Property<double>(
|
|
typeof(Event).FullName + ".TooLargeFor32BitVisualizationBytesPerSampleThreshold",
|
|
MaximumVisualizationBytesPerSample,
|
|
true
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get <see cref="bool"/> value indicating whether or not this event has more combined data than a 32 bit
|
|
/// system could handle all at once.
|
|
/// </summary>
|
|
public bool IsTooLargeFor32BitVisualization
|
|
{
|
|
get
|
|
{
|
|
try
|
|
{
|
|
ulong totalChannelDataCount = 0;
|
|
foreach (var module in Modules)
|
|
{
|
|
foreach (var channel in module.Channels)
|
|
{
|
|
if (channel.UnfilteredData is Serialization.TDAS.File.PersistentChannel persistentChannel)
|
|
{
|
|
totalChannelDataCount += persistentChannel.NumberOfSamples;
|
|
}
|
|
else
|
|
{
|
|
totalChannelDataCount +=
|
|
((Serialization.SliceRaw.File.PersistentChannel)channel.UnfilteredData)
|
|
.NumberOfSamples;
|
|
}
|
|
}
|
|
}
|
|
return (totalChannelDataCount * TooLargeFor32BitVisualizationBytesPerSampleThreshold) > 0x7FFFFFFF;
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception("encountered problem determining whether or not this event's combined data is too big for 32-bit visualization", ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get <see cref="bool"/> value indicating whether or not this event contains channels with average over
|
|
/// time zero methods, but have specified an invalid averaging window.
|
|
/// </summary>
|
|
public bool ContainsChannelsActiveInvalidZeroingWindows => ChannelsWithActiveInvalidZeroingWindows.Count > 0;
|
|
|
|
/// <summary>
|
|
/// we initialize the window average to short min value, which is a valid data value but probably means bad things
|
|
/// if your window average is legitimately short min value ...
|
|
/// </summary>
|
|
private const short InvalidWindowAverage = short.MinValue;
|
|
/// <summary>
|
|
/// Get the list of all <see cref="DTS.Slice.Control.Event.Module.Channel"/>s that with average over time
|
|
/// zero method set, but have specified an invalid averaging window.
|
|
/// </summary>
|
|
public List<Module.Channel> ChannelsWithActiveInvalidZeroingWindows
|
|
{
|
|
get
|
|
{
|
|
try
|
|
{
|
|
var invalidZeroWindowChannels = new List<Module.Channel>();
|
|
foreach (var module in Modules)
|
|
foreach (var channel in module.Channels)
|
|
if (channel is Module.AnalogInputChannel analogChannel)
|
|
{
|
|
if (ZeroMethodType.AverageOverTime == analogChannel.ZeroMethod)
|
|
{
|
|
//if we have a stored window average for the channel, well then it's definitely not an invalid window average ...
|
|
if (analogChannel.WindowAverageADC != InvalidWindowAverage) { continue; }
|
|
//otherwise check to see if we have an invalid window average
|
|
var windowStart = ((analogChannel.ParentModule.TriggerSampleNumbers.Count > 0) ? analogChannel.ParentModule.TriggerSampleNumbers[0] : 0) + (analogChannel.ZeroAverageWindow.Begin * analogChannel.ParentModule.SampleRateHz);
|
|
var windowEnd = ((analogChannel.ParentModule.TriggerSampleNumbers.Count > 0) ? analogChannel.ParentModule.TriggerSampleNumbers[0] : 0) + (analogChannel.ZeroAverageWindow.End * analogChannel.ParentModule.SampleRateHz);
|
|
if (0 > windowStart || 0 > windowEnd) { invalidZeroWindowChannels.Add(analogChannel); }
|
|
else
|
|
{
|
|
var dataStart = analogChannel.ParentModule.StartRecordSampleNumber;
|
|
var dataEnd = dataStart + analogChannel.ParentModule.NumberOfSamples;
|
|
if (dataStart > windowStart || windowStart > dataEnd) { invalidZeroWindowChannels.Add(analogChannel); }
|
|
else if (dataEnd < windowEnd || windowEnd < dataStart) { invalidZeroWindowChannels.Add(analogChannel); }
|
|
}
|
|
}
|
|
}
|
|
return invalidZeroWindowChannels;
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception("encountered problem building list of event channels with active invalid zeroing windows", ex);
|
|
}
|
|
}
|
|
}
|
|
private bool IsEmptyModule(Module module)
|
|
{
|
|
foreach (var channel in module.Channels)
|
|
{
|
|
if (channel.IsConfigured || !IsDummyChannel(channel)) { return false; }
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void PurgeUnconfiguredChannels()
|
|
{
|
|
foreach (var module in Modules)
|
|
{
|
|
module.Channels.RemoveAll(channel => !channel.IsConfigured || IsDummyChannel(channel));
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Convert this object to a DTS.Serialization.Test.
|
|
/// </summary>
|
|
///
|
|
/// <returns>
|
|
/// A <see cref="DTS.Serialization.Test"/> equivalent to this object.
|
|
/// </returns>
|
|
///
|
|
public Test ToDtsSerializationTest()
|
|
{
|
|
try
|
|
{ //
|
|
// Create a test to embody the conversion and copy over all relevant
|
|
// test data members.
|
|
//
|
|
var that = new Test();
|
|
|
|
PurgeUnconfiguredChannels();
|
|
|
|
that.Id = Id;
|
|
that.Description = Description;
|
|
that.EventNumber = EventNumber;
|
|
that.Guid = Guid;
|
|
that.FaultFlags = FaultFlags;
|
|
that.ExtendedFaultFlags1 = ExtendedFaultFlags1;
|
|
that.ExtendedFaultFlags2 = ExtendedFaultFlags2;
|
|
that.ExtendedFaultFlags3 = ExtendedFaultFlags3;
|
|
that.ExtendedFaultFlags4 = ExtendedFaultFlags4;
|
|
that.Modules = new List<Test.Module>();
|
|
//set the test inception date to the timestamp of the test
|
|
//15266 Can we set the date/time of the data collection when exporting CSV data?
|
|
that.InceptionDate = InceptionDate;
|
|
foreach (var thisModule in Modules)
|
|
{
|
|
//Normally, we don't care about empty modules (no data channels), but if it's
|
|
//a SLICE6 Distributor (a null ParentEvent), we want to output a module element to the .dts file.
|
|
if (IsEmptyModule(thisModule) && !IsSlice6DBModule(thisModule) && !IsPowerProModule(thisModule)) { continue; }
|
|
//We do care about the timing data in clock modules, but do not want them output to the .dts file.
|
|
if (IsClockModule(thisModule)) { continue; }
|
|
//We do care about the saved stream data in streaming in modules, but do not want them output to the .dts file.
|
|
if (IsStreamInModule(thisModule)) { continue; }
|
|
//
|
|
// Create a test module to embody each module conversion, and then copy
|
|
// over all relevant module data members.
|
|
//
|
|
that.Modules.Add(thisModule.ToDtsSerializationTestModule(that));
|
|
}
|
|
that.DasTimestamps = new List<Test.DasTimestamp>();
|
|
foreach (var thisClockModule in Modules.Where(mod => IsClockModule(mod)))
|
|
{
|
|
if (!that.DasTimestamps.Exists(stamp => stamp.BaseSerialNumber == thisClockModule.BaseSerialNumber))
|
|
{
|
|
var newstamp = new Test.DasTimestamp(that)
|
|
{
|
|
BaseSerialNumber = thisClockModule.BaseSerialNumber,
|
|
NumberOfSamples = thisClockModule.NumberOfSamples,
|
|
NumberOfBitsPerSample = 8 * sizeof(ulong)
|
|
};
|
|
that.DasTimestamps.Add(newstamp);
|
|
}
|
|
}
|
|
return that;
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception("encountered problem converting " + GetType().FullName + " to " + typeof(Test).FullName, ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialize this object from a DTS.Serialization.Test.
|
|
/// </summary>
|
|
///
|
|
/// <param name="that">
|
|
/// A <see cref="DTS.Serialization.Test"/> from which to initialize this object.
|
|
/// </param>
|
|
///
|
|
public void FromDtsSerializationTest(Test that, Test.ReportErrors reportErrors)
|
|
{
|
|
try
|
|
{
|
|
if (null == that)
|
|
throw new ArgumentNullException("cannot set this object's properties from null serialization test reference");
|
|
//
|
|
// Create the Slice Control test that will be equivalent to the specified serialization
|
|
// test and populate its relevant properties.
|
|
//
|
|
Id = that.Id;
|
|
Description = that.Description;
|
|
EventNumber = that.EventNumber;
|
|
FaultFlags = that.FaultFlags;
|
|
ExtendedFaultFlags1 = that.ExtendedFaultFlags1;
|
|
ExtendedFaultFlags2 = that.ExtendedFaultFlags2;
|
|
ExtendedFaultFlags3 = that.ExtendedFaultFlags3;
|
|
ExtendedFaultFlags4 = that.ExtendedFaultFlags4;
|
|
Guid = that.Guid;
|
|
InceptionDate = that.InceptionDate;
|
|
|
|
Modules = new List<Module>();
|
|
foreach (var thatModule in that.Modules)
|
|
{ //
|
|
// Create a Slice Control module corresponding to the specified serialization module
|
|
// and populate its relevant properties.
|
|
//
|
|
Modules.Add(new Module(thatModule, this, reportErrors));
|
|
}
|
|
}
|
|
catch (System.IO.InvalidDataException) { throw; }
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception("encountered problem initializing " + GetType().FullName + " using " + typeof(Test).FullName, ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method to convert a DTS.Slice.Control.Event object to an equivalent DTS.Serialization.Test object.
|
|
/// </summary>
|
|
///
|
|
/// <param name="sliceControlEvent">
|
|
/// The <see cref="DTS.Slice.Control.Event"/> to be converted.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// A <see cref="DTS.Serialization.Test"/> that is equivalent to the specified Slice Control event.
|
|
/// </returns>
|
|
///
|
|
public static implicit operator Test(Event sliceControlEvent)
|
|
{
|
|
try
|
|
{
|
|
return sliceControlEvent.ToDtsSerializationTest();
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception("encountered problem implicitly converting " + typeof(Event).FullName + " to " + typeof(Test).FullName, ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// this really belongs in the channel object, but for now just abstract the function out of
|
|
/// where the logic is needed
|
|
/// </summary>
|
|
/// <param name="channel"></param>
|
|
/// <returns></returns>
|
|
private bool IsDummyChannel(Module.Channel channel)
|
|
{
|
|
if (null != channel && channel.ChannelDescriptionString.ToLower() == "dummy arm channel")
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get/set the base serialization directory path <see cref="string"/> for events.
|
|
/// </summary>
|
|
public static string BaseSerializationDirectory
|
|
{
|
|
get => _BaseSerializationDirectory.Value;
|
|
set => _BaseSerializationDirectory.Value = value;
|
|
}
|
|
private static readonly Property<string> _BaseSerializationDirectory
|
|
= new Property<string>(
|
|
typeof(Event).Namespace + ".BaseSerializationDirectory",
|
|
null,
|
|
false
|
|
);
|
|
|
|
/// <summary>
|
|
/// Construct the serialization path for the specified event ID.
|
|
/// </summary>
|
|
///
|
|
/// <param name="eventId">
|
|
/// The <see cref="string"/> ID of the event whose serialization path is sought.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The <see cref="string"/> path for the specified event's serialization.
|
|
/// </returns>
|
|
///
|
|
public static string GetEventSerializationDirectory(string eventId)
|
|
{
|
|
try
|
|
{
|
|
return System.IO.Path.Combine(BaseSerializationDirectory, eventId);
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
//throw new ReviewForm.Exception("encountered problem getting target directory for test " + (null != eventId ? "\"" + eventId + "\"" : "<NULL>"), ex);
|
|
throw new Exception("encountered problem getting target directory for test " + (null != eventId ? "\"" + eventId + "\"" : "<NULL>"), ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test the specified object for equality with this object.
|
|
/// </summary>
|
|
///
|
|
/// <param name="obj">
|
|
/// The <see cref="object"/> to be tested for equality.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// <see cref="bool"/> true if the specified object has memberwise equality with
|
|
/// this object; false otherwise.
|
|
/// </returns>
|
|
///
|
|
public override bool Equals(object obj)
|
|
{
|
|
try
|
|
{
|
|
return obj is Event that
|
|
&& Id.Equals(that.Id)
|
|
&& Description.Equals(that.Description)
|
|
&& Guid.Equals(that.Guid)
|
|
&& ModulesEquals(that.Modules)
|
|
&& FaultFlags.Equals(that.FaultFlags)
|
|
&& ExtendedFaultFlags1.Equals(that.ExtendedFaultFlags1)
|
|
&& ExtendedFaultFlags2.Equals(that.ExtendedFaultFlags2)
|
|
&& ExtendedFaultFlags3.Equals(that.ExtendedFaultFlags3)
|
|
&& ExtendedFaultFlags4.Equals(that.ExtendedFaultFlags4);
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception(
|
|
string.Format(
|
|
Strings.DTS_Slice_Control_Equals_ComparisonFailedString, null != obj ? "\"" + obj.ToString() + "\"" : Strings.DTS_Slice_Control_NullIndicatorString),
|
|
ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test the specified object's module list for equality with this object's
|
|
/// module list.
|
|
/// </summary>
|
|
///
|
|
/// <param name="thoseModules">
|
|
/// The <see cref="List"/> of <see cref="DTS.Slice.Control.Event.Module"/> objects to be
|
|
/// compared for equality with this test's equivalent.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// <see cref="bool"/> true if the two lists contain equivalent-valued members;
|
|
/// false otherwise.
|
|
/// </returns>
|
|
///
|
|
private bool ModulesEquals(List<Module> thoseModules)
|
|
{
|
|
try
|
|
{
|
|
if (Modules.Count != thoseModules.Count)
|
|
return false;
|
|
for (var i = 0; i < thoseModules.Count; i++)
|
|
if (!Modules[i].Equals(thoseModules[i]))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new Exception(Strings.DTS_Slice_Control_Event_ModuleEquals_ComparisonFailedString, ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return the hash code for this object.
|
|
/// </summary>
|
|
///
|
|
/// <returns>
|
|
/// The <see cref="int"/> hash code for this object.
|
|
/// </returns>
|
|
///
|
|
public override int GetHashCode()
|
|
{
|
|
return base.GetHashCode();
|
|
}
|
|
}
|
|
}
|