using System; using System.Linq; namespace DTS.Serialization.TDM { public class TestHeader { internal const int MAX_TESTDEVICES = 1000; internal const int MAX_DUMMY_DISPLAY = 16; internal const int MAX_BARRIER_DISPLAY = 3; internal const int MAX_GROUP_DISPLAY = 20; internal const int MAX_DEVICE_DISPLAY = MAX_DUMMY_DISPLAY + MAX_BARRIER_DISPLAY + MAX_GROUP_DISPLAY + 1; internal const char DEV_TYPE_DUMMY = 'D'; internal const char DEV_TYPE_BARRIER = 'B'; internal const char DEV_TYPE_GROUP = 'G'; internal const char DEV_TYPE_UNDEFINED = 'U'; internal const int MAX_DEVICE_LINES = 23; internal const int MAX_OLD_GROUP_LINES = 4; public void WriteTestHeader(Writer writer, System.IO.TextWriter tw, bool bFiltered, UInt16 subSampleInterval, ulong numSamples, int preTriggerSamples) { var test = writer.Test; writer.IncrementDone(1); tw.WriteLine("{0},", test.Id);//test id tw.WriteLine("{0},", 0);//impact speed 1 tw.WriteLine("{0},", 0);//impact weight 1 tw.WriteLine("{0},", 0);//impact speed 2 tw.WriteLine("{0},", 0);//impact weight 2 tw.WriteLine("{0},", "km/h");//unit (m/s or km/h) //test start date tw.WriteLine("'{0:00}-{1:00}-{2:00},", test.InceptionDate.Year - 2000, test.InceptionDate.Month, test.InceptionDate.Day); //test start time tw.WriteLine("{0:00}:{1:00}:{2:00},", test.InceptionDate.Hour, test.InceptionDate.Minute, test.InceptionDate.Second); var testCompleteTime = (test.InceptionDate.AddSeconds(test.Modules[0].PreTriggerSeconds).AddSeconds(test.Modules[0].PostTriggerSeconds)); //test complete time tw.WriteLine("{0:00}:{1:00}:{2:00},", testCompleteTime.Hour, testCompleteTime.Minute, testCompleteTime.Second); // Note this section is not completely implemented equivalent to TDM. Specifically, the dummy list passed in // the test description works, but the notion of barriers and groups and written with blank lines. TBD if THF or TEMA really need this and // how we would propigate that information. var userValue3 = test.Channels.FirstOrDefault().UserValue3; string[] dummyList; if (!string.IsNullOrEmpty(userValue3)) { dummyList = test.Channels.FirstOrDefault().UserValue3.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); } else { dummyList = new string[0]; } var barrierCount = 0; var groupCount = 0; var dummyCount = dummyList.Count(); // this is only of importance if we have more than 4 groups // and if the others are full we're stuck if (groupCount > MAX_OLD_GROUP_LINES && !(dummyCount == MAX_DUMMY_DISPLAY && barrierCount == MAX_BARRIER_DISPLAY)) { // we must prioritize dummies and barriers if (MAX_DEVICE_LINES - dummyCount - barrierCount >= groupCount) { // this will be a full house groupCount = MAX_DEVICE_LINES - dummyCount - barrierCount; WriteDeviceSection(test, DEV_TYPE_DUMMY, dummyCount, dummyCount, tw, dummyList); WriteDeviceSection(test, DEV_TYPE_BARRIER, barrierCount, barrierCount, tw, null); WriteDeviceSection(test, DEV_TYPE_GROUP, groupCount, groupCount, tw, null); } else { // the only thing we know now is that groupCount > MAX_OLD_GROUP_LINES if (dummyCount == 0) { if (barrierCount == 0) { // we only have groups, easy WriteDeviceSection(test, DEV_TYPE_GROUP, MAX_DEVICE_LINES, groupCount, tw, null); } else { // we have barriers and groups var spaceAvail = MAX_DEVICE_LINES - barrierCount - groupCount; WriteDeviceSection(test, DEV_TYPE_BARRIER, barrierCount + spaceAvail, barrierCount, tw, null); WriteDeviceSection(test, DEV_TYPE_GROUP, groupCount, groupCount, tw, null); } } else { if (barrierCount == 0) { // we have dummies and groups var spaceAvail = MAX_DEVICE_LINES - dummyCount - groupCount; WriteDeviceSection(test, DEV_TYPE_DUMMY, dummyCount + spaceAvail, dummyCount, tw, null); WriteDeviceSection(test, DEV_TYPE_GROUP, groupCount, groupCount, tw, null); } else { // we have all three types var spaceAvail = MAX_DEVICE_LINES - dummyCount - barrierCount - groupCount; var firstSpace = spaceAvail / 2; WriteDeviceSection(test, DEV_TYPE_DUMMY, dummyCount + firstSpace, dummyCount, tw, dummyList); WriteDeviceSection(test, DEV_TYPE_BARRIER, barrierCount + spaceAvail - firstSpace, barrierCount, tw, null); WriteDeviceSection(test, DEV_TYPE_GROUP, groupCount, groupCount, tw, null); } } } } else { // this is the normal case with less than 5 groups WriteDeviceSection(test, DEV_TYPE_DUMMY, MAX_DUMMY_DISPLAY, MAX_DUMMY_DISPLAY, tw, dummyList); WriteDeviceSection(test, DEV_TYPE_BARRIER, MAX_BARRIER_DISPLAY, MAX_BARRIER_DISPLAY, tw, null); WriteDeviceSection(test, DEV_TYPE_GROUP, MAX_OLD_GROUP_LINES, MAX_OLD_GROUP_LINES, tw, null); } var TotalSamples = ulong.MaxValue; //the lowest common start in samples from t0 that all modules have var minStart = double.MinValue; //the highest common end in samples from t0 that all modules have var maxEnd = double.MaxValue; foreach (var module in test.Modules) { //Don't process Slice6DB modules that were created to store Temperature values from Arm checklist if (module.Channels.Count <= 0) continue; //TriggerSampleNumber = Math.Min(TriggerSampleNumber, module.TriggerSampleNumbers[0]); TotalSamples = Math.Min(TotalSamples, module.NumberOfSamples); //System.Diagnostics.Trace.Assert(module.TriggerSampleNumbers[0] >= module.StartRecordSampleNumber); double mStart = module.TriggerSampleNumbers[0] - module.StartRecordSampleNumber; minStart = Math.Max(minStart, mStart); var mEnd = module.NumberOfSamples - mStart; maxEnd = Math.Min(maxEnd, mEnd); } if (preTriggerSamples < 0) { preTriggerSamples = 0; } else if (preTriggerSamples > (int)numSamples) { //All of the ROI is pre-trigger preTriggerSamples = (int)numSamples; } tw.WriteLine("{0},", preTriggerSamples); tw.WriteLine("{0},", (int)numSamples - preTriggerSamples); tw.WriteLine("{0},", numSamples); tw.WriteLine("{0},", subSampleInterval); tw.WriteLine("{0},", Math.Truncate(test.Modules[0].SampleRateHz / subSampleInterval)); var tomVoltageCount = 0; foreach (var currentChannel in test.Channels) { if (currentChannel is Test.Module.AnalogInputChannel analogChannel && analogChannel.IsSquibVoltage()) { tomVoltageCount++; } } tw.WriteLine("{0},", test.Channels.Count - tomVoltageCount); tw.WriteLine("{0},", test.Description); } private void WriteDeviceSection(Test test, char devType, int totalSize, int maxDevices, System.IO.TextWriter tw, string[] DeviceList) { var DeviceCount = 0; var channelCount = test.Channels.Count; for (var Index = 0; Index < MAX_DEVICE_DISPLAY && Index < channelCount; Index++) { if (devType == DEV_TYPE_DUMMY)//if (TestPtr->DeviceList[Index].DeviceType == devType) { if (Index < DeviceList.Count() && !String.IsNullOrEmpty(DeviceList[Index])) { tw.Write(DeviceList[Index]); } tw.WriteLine(","); DeviceCount++; } // make sure we don't do more than if (DeviceCount == maxDevices) { break; } } // pad until MAX_DUMMY_DISPLAY lines for (/*NOOP*/; DeviceCount < totalSize; DeviceCount++) { tw.WriteLine(","); //fprintf(fp, ",\n"); } } } }