Files
DP44/DataPRO/IService/.svn/pristine/f6/f65553066e58c23f1fe2bf9cd8223baa16df1ece.svn-base

989 lines
52 KiB
Plaintext
Raw Normal View History

2026-04-17 14:55:32 -04:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using DTS.Common.Utilities.Logging;
using DTS.DASLib.Command.SLICE;
using DTS.DASLib.Command;
using DTS.DASLib.Service;
using DTS.Slice.Service;
using DTS.Common.DAS.Concepts;
using DTS.Common.DASResource;
using DTS.Common.Enums;
using DTS.Common.ICommunication;
using DTS.Common.Enums.Sensors;
using DTS.Common.Interface.Connection;
using DTS.Common.Interface.DASFactory.Download;
using DTS.Common.Enums.DASFactory;
using DTS.Common.Interface.DASFactory;
namespace DTS.DASLib.Service
{
public partial class TDAS<T> : Communication<T>,
IDASCommunication,
IConfigurationActions,
IDiagnosticsActions,
ITriggerCheckActions,
IRealTimeActions,
IArmActions,
IDownloadActions where T : IConnection, new()
{
#region Downloading
public class TDASSetEventInfoAsync : TDASServiceAsyncInfo
{
public int EventIndex { get; set; }
public UInt32 EventHasDownloaded { get; set; }
public TDASSetEventInfoAsync(ServiceCallback callback,
object userData,
int eventIndex,
UInt32 eventHasDownloaded)
: base(callback, userData)
{
EventIndex = eventIndex;
EventHasDownloaded = eventHasDownloaded;
}
}
public void CorrectT0s(ServiceCallback callback, object userData)
{
var asyncInfo = new TDASServiceAsyncInfo(callback, userData);
asyncInfo.Error("Not supported");
return;
}
void IDownloadActions.SetEventInfo(int eventindex,
string id,
Guid guid,
ulong totalSamples,
ulong[] triggerSamples,
ulong startRecordSample,
UInt32 eventHasDownloaded,
ServiceCallback callback,
object userData)
{
var info = new TDASSetEventInfoAsync(callback, userData, eventindex, eventHasDownloaded);
LaunchAsyncWorker("TDAS.SetEventInfo", new WaitCallback(AsyncSetEventInfo), info);
}
private void AsyncSetEventInfo(object asyncInfo)
{
var info = asyncInfo as TDASSetEventInfoAsync;
try
{
if (UInt32.MaxValue != info.EventHasDownloaded)
{
foreach (DASModule module in ConfigData.Modules)
{
if (DASInfo.Modules[module.ModuleArrayIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK)
{
continue;
}
Command.TDAS.ClearDataAvailable cda = new DTS.DASLib.Command.TDAS.ClearDataAvailable(this);
cda.ModuleIndex = module.ModuleArrayIndex;
cda.SyncExecute();
if (cda.IsErrored) { throw new Exception(string.Format("{0}:{1}", SerialNumber, cda.ResponseData)); }
// Only need to do once for G5
if (IsG5()) { break; }
}
}
}
catch (System.Exception ex)
{
info.Error("Failed to set event downloaded status", ex);
return;
}
info.Success();
}
void IDownloadActions.Download(ServiceCallback callback, object userData)
{
if (!Connected)
{
// "Slice.Download: Not currently connected"
throw new Exception(string.Format(Strings.TDAS_Download_NotConnected, ((InfoResult)DASInfo).OwningDAS.SerialNumber));
}
var state = new TDASDownloadState(callback, userData, WhatToDownload);
LaunchAsyncWorker("TDAS.Download", new WaitCallback(TDASDownload), state);
}
private class TDASDownloadState : TDASServiceAsyncInfo
{
public IDownloadRequest Request;
public ulong SamplesDownloaded; // how many samples have we downloaded so far
public Command.TDAS.Download DownloadCommand;
public TDASDownloadState(ServiceCallback cb, object cbObj, IDownloadRequest _Request)
: base(cb, cbObj)
{
Request = _Request;
SamplesDownloaded = 0;
DownloadCommand = null;
}
}
private static string ToByteFormat(int valIn, int digits)
{
var bitsString = new StringBuilder(digits);
int mask = (1 << digits - 1);
for (int i = 0; i < digits; i++)
{
bitsString.Append((valIn & mask) != 0 ? "1" : "0");
mask >>= 1;
}
return bitsString.ToString();
}
/// <summary>
/// reflects the number of channels on a TOM module (4 SQUIB x 2 channels (squib + current) + 8 digital)
/// </summary>
private const int TOM_CHANNEL_COUNT = 16;
private void TDASDownload(object asyncInfo)
{
var state = asyncInfo as TDASDownloadState;
try
{
int NumberOfChannels = 0;
ulong moduleZerosT0 = 0;
foreach (var module in EventInfo.Events[WhatToDownload.EventNumber].Modules)
{
//Since "What to Download" was calculated using the last module with configured channel's trigger point,
//set moduleZerosT0 here on the same basis so that the delta calculation below is correct.
if ((module.TriggerSampleNumbers != null) && (module.NumberOfConfiguredChannels() > 0))
{
moduleZerosT0 = module.TriggerSampleNumbers[0];
}
//if ((module.Channels.Length > 0) && module.Channels[0].ConfigurationMode != DASChannel.ConfigMode.DummyArm)
//20088 TDAS Download with unused TOM fails.
//TOM modules are included in NewData even if they are dummy armed
//so include them in the count
if (module.IsDummyArmed() && (!IsG5()) && !IsTom(module)) { continue; }
else
{
NumberOfChannels += module.NumberOfChannels();
}
}
ulong totalNumberOfSamples = 1 + WhatToDownload.EndSample - WhatToDownload.StartSample;
//const uint downloadChunkSize = 16384;
ulong downloadChunkSize = 1 + WhatToDownload.EndSample - WhatToDownload.StartSample;
ulong samplesDownloaded = 0;
int channelsToDownload = 0;
foreach (var iDASModule in EventInfo.Events[WhatToDownload.EventNumber].Modules)
{
var m = (DASModule)iDASModule;
if ((m.Channels.Length > 0) && (!(IsTom(m) && (m.Channels[0].ConfigurationMode == DFConstantsAndEnums.ConfigMode.DummyArm))))
{
//If DummyArm and a G5, then count the channels; if a TOM don't
foreach (var ch in m.Channels)
{
if (ch is DTS.DASLib.Service.AnalogInputDASChannel)
{
var aic = ch as DTS.DASLib.Service.AnalogInputDASChannel;
if (aic.ConfigurationMode == DFConstantsAndEnums.ConfigMode.Normal)
{
channelsToDownload++;
}
}
else if (ch is DTS.DASLib.Service.OutputSquibChannel)
{
var osc = ch as DTS.DASLib.Service.OutputSquibChannel;
if (osc.ConfigurationMode == DFConstantsAndEnums.ConfigMode.Normal)
{
channelsToDownload++;
}
}
}
}
}
int channelsDownloaded = 0;
for (ulong z = WhatToDownload.StartSample; z <= WhatToDownload.EndSample; z += downloadChunkSize)
{
ulong end = z + downloadChunkSize;
bool bDigitalDownload = false;
if (end > WhatToDownload.EndSample) { end = WhatToDownload.EndSample; }
short[][] newData = new short[NumberOfChannels][];
for (int i = 0; i < NumberOfChannels; i++)
{
newData[i] = new short[end + 1 - z];
}
int channelIdx = -1;
for (int i = 0; i < EventInfo.Events[WhatToDownload.EventNumber].Modules.Length && z < WhatToDownload.EndSample; i++)
{
if (EventInfo.Events[WhatToDownload.EventNumber].Modules[i].IsDummyArmed())
{
if (IsG5())
{
//Unlike modules in a rack that don't have channels, G5 modules that don't have channels must all be downloaded (and then purged)
channelIdx += EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Count();
}
//20088A TDAS Download with unused TOM fails.
//TOM channels are included in the NewData structure
//even when dummyarmed, so we must account for it if we see it
if (IsTom(EventInfo.Events[WhatToDownload.EventNumber].Modules[i]))
{
channelIdx += TOM_CHANNEL_COUNT;
}
continue;
}
DASModule mod = (DASModule)EventInfo.Events[WhatToDownload.EventNumber].Modules[i];
//tdas wants start, end, but wants it specified in terms of - = pretrigger,
//+ = post trigger, so we have to convert.
long start = 0;
long stop = 0;
//we make the adjustment here because the "What to Download" was calculated using
//the last module with configured channel's trigger point, but trigger points in tdas are module specific
//so we just adjust by the difference in triggers.
double delta = mod.TriggerSampleNumbers[0] - (double)moduleZerosT0;
//hack to move everything to the the left in the window (by moving the data download to the right
//this seems inaccurate but is consistent with the TDC viewer.
//http://fogbugz/fogbugz/default.asp?7084#45268
//DTM - 2016-09-28 we are now _UNDOING_ thing change, per TJK
double startSample = (double)(z + delta);
double endSample = (double)(end + delta) + 1;
startSample -= mod.PreTriggerSeconds * mod.SampleRateHz;
endSample -= 1 + mod.PreTriggerSeconds * mod.SampleRateHz;
start = Convert.ToInt64(startSample);
stop = Convert.ToInt64(endSample);
//also per CPB and TJK we are one sample too far, so don't do the below adjustment...
//start -= 1;
//stop -= 1;
//NOW per TJK, ADD a sample, for
//http://fogbugz/fogbugz/default.asp?8747
start += 1;
stop += 1;
short[] dimData = new short[0];
bool bIsDIM = !IsG5() &&
EventInfo.Events[WhatToDownload.EventNumber].Modules[i].SerialNumber()
.StartsWith("DIM");
if (bIsDIM)
{
Command.TDAS.Download download = new Command.TDAS.Download(this);
download.ChannelIndex = 0;
download.ModuleIndex = mod.ModuleArrayIndex;
download.FirstPoint = start;
download.LastPoint = stop;
download.SyncExecute();
dimData = download.GetData();
}
for (int k = 0; k < EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length; k++)
{
channelIdx++;
if (EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels[k].ConfigurationMode != DFConstantsAndEnums.ConfigMode.Normal)
{
continue;
}
//DIMS send there data with all 16 channels per each short
//so to get one channel we've already gotten all channels, so to increase efficiency, we process all channels at the same time here as well
if (bIsDIM)
{
if (dimData.Length > 0)
{
//note that k doesn't necessarily start at 0, so we just start wherever k started at
//first we initialize the data structures since we know how much data we will have
for (int curChannel = k;
curChannel <
EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length;
curChannel++)
{
//we also have to keep in mind, we might have started at 1, and we are adding in the "current" channel index
//this is OK with digital channels, because at worse we'll write blank data into the next modules channels, which aren't downloaded yet
//[ideally we'd keep track of which channel we are in the module as well, rather than just overall in the DAS]
//but we need to make sure we don't index out of range ...
if ((curChannel + channelIdx) < newData.Length)
{
newData[curChannel + channelIdx] = new short[dimData.Length];
}
}
//for each data point, break out all the remaining channels and store the bits
//we store them as ADC, which is wasteful, but consistent with Slice pro dim
for (int iDataIndex = 0; iDataIndex < dimData.Length; iDataIndex++)
{
System.Collections.Specialized.BitVector32 bv =
new System.Collections.Specialized.BitVector32(
Convert.ToInt32(dimData[iDataIndex]));
for (int curChannel = k;
curChannel <
EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length;
curChannel++)
{
//bit vectors expect a bit mask, our bit mask is just the one channel we are interested in
if (bv[(1 << curChannel)])
{
//cur channel starts at k, so we are inserting at just channelIdx, which is what we want
//as we increase curChannel we are at channelIdx+1, +2, etc.
newData[(curChannel - k) + channelIdx][iDataIndex] = short.MaxValue;
}
else
{
newData[(curChannel - k) + channelIdx][iDataIndex] = short.MinValue;
}
}
}
//update progress
int numberOfDigitalIns = EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length - k;
channelsDownloaded += numberOfDigitalIns;
state.Progress((int)(100D * channelsDownloaded / channelsToDownload));
channelIdx += numberOfDigitalIns - 1;//we are ++ at the begining, so we have to subtract one here as numberOfDigitalIns is inclusive
}
//we've finished all channels in this module, since it's a DIM ...
k = EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length;
continue;
}
if (EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels[k] is DTS.DASLib.Service.AnalogInputDASChannel &&
(EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels[k] as DTS.DASLib.Service.AnalogInputDASChannel).TypeOfBridge == SensorConstants.BridgeType.DigitalInput
&& IsG5())
{//download digital all at once
bDigitalDownload = true;
continue;
}
Command.TDAS.Download download = new DTS.DASLib.Command.TDAS.Download(this);
if (IsTom(mod))
{
OutputSquibChannel osc = EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels[k] as OutputSquibChannel;
if (null == osc) { continue; }
switch (osc.MeasurementType)
{
case SquibMeasurementType.INIT_SIGNAL:
case SquibMeasurementType.VOLTAGE:
download.DoVoltageOrInsertionDownload = true;
break;
case SquibMeasurementType.CURRENT:
case SquibMeasurementType.NONE:
default:
download.DoCurrentDownload = true;
break;
}
}
download.ModuleIndex = mod.ModuleArrayIndex;
download.ChannelIndex = k;
if (IsTom(mod))
{
download.ChannelIndex = Convert.ToInt32(System.Math.Floor(download.ChannelIndex / 2D));
}
download.FirstPoint = start;
download.LastPoint = stop;
try
{
download.SyncExecute();
}
catch (System.Exception ex)
{
APILogger.Log("Failed to download: ", ex);
download = new Command.TDAS.Download(this, download);
download.SyncExecute();
}
newData[channelIdx] = download.GetData();
channelsDownloaded++;
state.Progress((int)(100D * channelsDownloaded / channelsToDownload));
}
}
if (bDigitalDownload && IsG5())
{
Command.TDAS.Download download = new DTS.DASLib.Command.TDAS.Download(this);
download.ModuleIndex = 0;
var mod = EventInfo.Events[0].Modules[0];
long start = 0;
long stop = 0;
//we make the adjustment here because the "What to Download" was calculated using
//the last module's trigger point, but trigger points in tdas are module specific
//so we just adjust by the difference in triggers.
double delta = mod.TriggerSampleNumbers[0] - (double)moduleZerosT0;
double startSample = (double)(z + delta);
double endSample = (double)(end + delta);
startSample -= mod.PreTriggerSeconds * mod.SampleRateHz;
endSample -= 1 + mod.PreTriggerSeconds * mod.SampleRateHz;
start = Convert.ToInt64(startSample);
stop = Convert.ToInt64(endSample);
// Similar to analog channels, this is a somewhat emperically determined adjustment that is suspect.
// In contrast, these adjustments are expected to be 1 more sample because the digital channels do not have a filter,
// and therefore do not have the same phase delay.
download.FirstPoint = start - 1;
download.LastPoint = stop - 1;
download.Digital = true;
download.Bank = 1;
try
{
download.SyncExecute();
}
catch (System.Exception ex)
{
APILogger.Log("failed; ", ex);
download = new Command.TDAS.Download(this, download);
download.SyncExecute();
}
short[] data = download.GetData();
for (int i = 0; i < 16; i++)
{
if (newData[32 + i].Length < data.Length) { newData[32 + i] = new short[data.Length]; }
}
//each short is actually 16 channels of binary data, so we have to parse it out and convert it to ADC for the purpose of the .chn files
for (int iDataIndex = 0; iDataIndex < data.Length; iDataIndex++)
{
System.Collections.Specialized.BitVector32 bv = new System.Collections.Specialized.BitVector32(Convert.ToInt32(data[iDataIndex]));
//there's another trick in here that we've preserved from TDC, we invert the incoming bit. We do this so that the data appears like
//contact closure normally open
for (int iChannelIdx = 0; iChannelIdx < 16; iChannelIdx++)
{
//also note that the bitvector [] operator expects a bitmask, not an index ...
if (bv[(1 << iChannelIdx)]) { newData[32 + iChannelIdx][iDataIndex] = short.MinValue; }
else { newData[32 + iChannelIdx][iDataIndex] = short.MaxValue; }
}
}
}
state.SamplesDownloaded = end - z;
state.NewData(newData, state.SamplesDownloaded + 1, ulong.MinValue, ulong.MinValue);
samplesDownloaded += downloadChunkSize;
double ratio = Convert.ToDouble(samplesDownloaded) / Convert.ToDouble(totalNumberOfSamples);
if (ratio > 1) { ratio = 1; }
//double ratio = Math.Min(1.0, (double)end / (double)(state.Request.EndSample - state.Request.StartSample + 1));
state.Progress((int)(ratio * 100.0));
}
//foreach (DASModule module in ConfigData.Modules)
foreach (DASModule module in EventInfo.Events[WhatToDownload.EventNumber].Modules)
{
try
{
if (DASInfo.Modules[module.ModuleArrayIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK
|| module.IsDummyArmed())
{
continue;
}
Command.TDAS.ClearDataAvailable cda = new DTS.DASLib.Command.TDAS.ClearDataAvailable(this);
cda.ModuleIndex = module.ModuleArrayIndex;
cda.SyncExecute();
if (IsG5()) { continue; } // only need to do it once
}
catch (System.Exception ex)
{
APILogger.Log("Failed to set event downloaded status", ex);
}
}
//state.NewData(data.ToArray(), WhatToDownload.EndSample-WhatToDownload.StartSample);
state.Progress(100);
// send data to user
state.Success();
}
catch (CanceledException)
{
state.Cancel();
}
catch (System.Exception ex)
{
state.Error(ex.Message, ex);
}
}
#endregion
#region Query download
void IDownloadActions.QueryDownload(ServiceCallback callback, object userData, int eventIndex, TDASServiceSetupInfo setupInfo)
{
var info = new TDASServiceAsyncInfo(callback, userData);
TDASDownloadServiceAsyncInfo dlSetupInfo = new TDASDownloadServiceAsyncInfo(info, setupInfo);
if (eventIndex > 0) { info.Error("only single event support for TDAS"); }
else { LaunchAsyncWorker("TDAS.QueryDownload", new WaitCallback(AsyncQueryDownloadedStatus), dlSetupInfo); }
}
#endregion
#region Query downloaded status
void IDownloadActions.QueryDownloadedStatus(ServiceCallback callback, object userData)
{
var info = new TDASServiceAsyncInfo(callback, userData);
var dlSetupInfo = new TDASDownloadServiceAsyncInfo(info, null);
LaunchAsyncWorker("TDAS.QueryDownloadedStatus", new WaitCallback(AsyncQueryDownloadedStatus), dlSetupInfo);
}
private void AsyncQueryDownloadedStatus(object asyncInfo)
{
var downloadInfo = asyncInfo as TDASDownloadServiceAsyncInfo;
var info = downloadInfo.info;
var setupInfo = downloadInfo.setupInfo;
try
{
var eventDownloadStatus = new List<bool>();
var eventIDs = new List<string>();
var eventDescriptions = new List<string>();
//List<string> eventDescriptions = new List<string>();
var eventGUIDs = new List<Guid>();
var faultFlags = new List<ushort>();
var dasModulesPerEvent = new List<List<DASModule>>();
DateTime eventStartTime = DateTime.Now;
int levelTriggerAdjustment = 0;
//turn off lights & clear serial on racks
//var qse = new Command.TDAS.QuerySerialNumberBroadcast(this, -1);
//qse.SyncExecute();
for (int i = 0; i < DASInfo.Modules.Length; i++)
{
string testConfig = "";
string testDescription = "";
double actualSampleRate = 1D;
float hardwareFilterRate = 1F;
Command.TDAS.SetupDASLoad.ARMMode recordingMode = Command.TDAS.SetupDASLoad.ARMMode.WAIT;
if (DASInfo.Modules[i].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK)
{
TDASModuleConfig tConfig = new TDASModuleConfig(DASInfo.Modules[i].SerialNumber + ".xml");
DASModule module = new DASModule(DASInfo.Modules[i].ModuleArrayIndex, this);
module.StartRecordSampleNumber = 0;
module.PreTriggerSeconds = 0;
module.PostTriggerSeconds = 0;
module.NumberOfSamples = ulong.MaxValue;
module.TriggerSampleNumbers = new UInt64[1];
module.TriggerSampleNumbers[0] = 0;
module.Channels = new DASChannel[DASInfo.Modules[i].NumberOfChannels];
module.AAFilterRateHz = hardwareFilterRate;
module.SampleRateHz = Convert.ToUInt32(System.Math.Abs(actualSampleRate));
if (ConfigData != null)
{
module.Channels = (DASChannel[])ConfigData.Modules[i].Channels.Clone();
}
// update the channel info
for (uint channelIdx = 0; channelIdx < module.Channels.Length; channelIdx++)
{
module.Channels[channelIdx].EventStartTime = eventStartTime;
}
if (dasModulesPerEvent.Count > 0)
{
//dasModulesPerEvent.Add(new List<DASModule>());
dasModulesPerEvent[dasModulesPerEvent.Count - 1].Add(module);
}
}
else
{
Command.TDAS.QueryDataAvailable qda = new DTS.DASLib.Command.TDAS.QueryDataAvailable(this);
qda.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
qda.SyncExecute();
if (null == qda.EventCodes || qda.EventCodes.Length == 0) { APILogger.Log(string.Format("No events found on {0}:{1}", SerialNumber, DASInfo.Modules[i].SerialNumber)); continue; }
try
{
//if (IsTom(ConfigData.Modules[i]))
if (IsTom(DASInfo.Modules[i].TypeOfModule))
{
if ((setupInfo == null) || ((setupInfo.CheckoutMode != null) && (setupInfo.SamplesPerSecond == null)))
{
//We were not called from the Download tile
Command.TDAS.SetupTOMDASRead sdr = new DTS.DASLib.Command.TDAS.SetupTOMDASRead(this);
sdr.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
sdr.SyncExecute();
string sTemp = sdr.TestConfig;
string[] tokens = sTemp.Split(SETUPDASREAD_SENTINEL);
if (tokens.Length >= 2) { testConfig = tokens[0]; testDescription = tokens[1]; }
else { testConfig = tokens[0]; }
//testConfig = sdr.TestConfig;
actualSampleRate = sdr.ActualSampleRate;
if ((setupInfo != null) && ((bool)setupInfo.CheckoutMode))
{
actualSampleRate = Math.Abs(actualSampleRate);
}
hardwareFilterRate = sdr.HardwareFilter;
recordingMode = sdr.ArmMode;
}
else
{
//We were called from the Download tile, which means that SDL was not done, so SDR above would have failed
GetUserSelectedSetupInfo(setupInfo, ref testConfig, ref testDescription, ref actualSampleRate, ref hardwareFilterRate, ref recordingMode);
}
}
else
{
if (DASInfo.Modules[i].TypeOfModule == DFConstantsAndEnums.ModuleType.ProDIM && !IsG5())
{
if ((setupInfo == null) || ((setupInfo.CheckoutMode != null) && (setupInfo.SamplesPerSecond == null)))
{
//We were not called from the Download tile
Command.TDAS.SetupDASReadDIM sdr = new DTS.DASLib.Command.TDAS.SetupDASReadDIM(this);
sdr.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
sdr.SyncExecute();
string sTemp = sdr.TestConfig;
string[] tokens = sTemp.Split(SETUPDASREAD_SENTINEL);
if (2 <= tokens.Length)
{
testConfig = tokens[0];
testDescription = tokens[1];
}
else
{
testConfig = tokens[0];
testDescription = tokens[0];
}
recordingMode = sdr.ArmMode;
actualSampleRate = sdr.ActualSampleRate;
}
else
{
//We were called from the Download tile, which means that SDL was not done, so SDR above would have failed
GetUserSelectedSetupInfo(setupInfo, ref testConfig, ref testDescription, ref actualSampleRate, ref hardwareFilterRate, ref recordingMode);
}
}
else
{
if ((setupInfo == null) || ((setupInfo.CheckoutMode != null) && (setupInfo.SamplesPerSecond == null)))
{
//We were not called from the Download tile
Command.TDAS.SetupDASRead sdr = new DTS.DASLib.Command.TDAS.SetupDASRead(this);
sdr.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
sdr.SyncExecute();
string sTemp = sdr.TestConfig;
string[] tokens = sTemp.Split(SETUPDASREAD_SENTINEL);
if (2 <= tokens.Length)
{
testConfig = tokens[0];
testDescription = tokens[1];
}
else
{
testConfig = tokens[0];
testDescription = tokens[0];
}
actualSampleRate = sdr.ActualSampleRate;
hardwareFilterRate = sdr.HardwareFilter;
recordingMode = sdr.ArmMode;
}
else
{
//We were called from the Download tile, which means that SDL was not done, so SDR above would have failed
GetUserSelectedSetupInfo(setupInfo, ref testConfig, ref testDescription, ref actualSampleRate, ref hardwareFilterRate, ref recordingMode);
}
}
}
}
catch (System.Exception ex)
{
APILogger.Log("Error get SDR", ex);
}
//Command.TDAS.QueryDataAvailable qda = new DTS.DASLib.Command.TDAS.QueryDataAvailable(this);
//qda.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
//qda.SyncExecute();
TDASModuleConfig tConfig = new TDASModuleConfig(DASInfo.Modules[i].SerialNumber + ".xml");
//if (null != qda.eventCodes && qda.eventCodes.Length > 0)
{
foreach (string eventCode in qda.EventCodes)
{
if (!eventIDs.Contains(eventCode))
{
if (testConfig.Length > 0)
{
try
{
eventGUIDs.Add(new Guid("11111111111111111111111111111111"));
}
catch (System.Exception ex)
{
APILogger.Log("invalid test guid - ", testConfig, ex);
continue;
}
}
else { continue; }
eventIDs.Add(eventCode);
eventDescriptions.Add(testDescription);
//eventGUIDs.Add(Guid.Empty);
faultFlags.Add(0);
eventDownloadStatus.Add(qda.IsDownloaded);
dasModulesPerEvent.Add(new List<DASModule>());
}
DASModule module = new DASModule(DASInfo.Modules[i].ModuleArrayIndex, this);
switch (recordingMode)
{
case Command.TDAS.SetupDASLoad.ARMMode.WAIT:
module.RecordingMode = DFConstantsAndEnums.RecordingMode.CircularBuffer;
break;
case Command.TDAS.SetupDASLoad.ARMMode.TAPE:
module.RecordingMode = DFConstantsAndEnums.RecordingMode.RecorderMode;
break;
}
module.StartRecordSampleNumber = 0;
module.PreTriggerSeconds = System.Math.Truncate(100D * qda.PreTriggerSamples / actualSampleRate) / 100D;
module.PostTriggerSeconds = System.Math.Truncate(100D * qda.PostTriggerSamples / actualSampleRate) / 100D;
module.NumberOfSamples = Convert.ToUInt64(qda.PreTriggerSamples + qda.PostTriggerSamples);
module.TriggerSampleNumbers = new UInt64[1];
module.TriggerSampleNumbers[0] = Convert.ToUInt64(qda.PreTriggerSamples + 1);
ulong phaseshift = GetPhaseShiftSamples(Convert.ToUInt32(module.ModuleArrayIndex), actualSampleRate, Convert.ToUInt32(hardwareFilterRate), module.TriggerSampleNumbers[0]);
module.TriggerSampleNumbers[0] += phaseshift;
module.Channels = new DASChannel[DASInfo.Modules[i].NumberOfChannels];
module.AAFilterRateHz = hardwareFilterRate;
module.SampleRateHz = Convert.ToUInt32(System.Math.Abs(actualSampleRate));
if (null != ConfigData)
{
module.Channels = (DASChannel[])ConfigData.Modules[i].Channels.Clone();
// update the channel info
for (uint channelIdx = 0; channelIdx < module.Channels.Length; channelIdx++)
{
module.Channels[channelIdx].EventStartTime = eventStartTime;
}
dasModulesPerEvent[eventIDs.IndexOf(eventCode)].Add(module);
}
if (qda.LevelTriggerOffset > levelTriggerAdjustment)
{
levelTriggerAdjustment = qda.LevelTriggerOffset;
}
}
}
}
}
if (0 < dasModulesPerEvent.Count() && 0 < dasModulesPerEvent[0].Count())
{
foreach (DASModule tempModule in dasModulesPerEvent[0])
{
foreach (var channel in tempModule.Channels)
{
channel.LevelTriggerT0AdjustmentSamples = levelTriggerAdjustment;
}
}
}
SetEventGuids(eventGUIDs.ToArray());
SetEventFaultFlags(faultFlags.ToArray());
DownloadReport dlReport = new DownloadReport();
dlReport.Events = new DownloadReport.EventInfo[EventGuids.Length];
for (int eventIndex = 0; eventIndex < EventGuids.Length; eventIndex++)
{
dlReport.Events[eventIndex] = new DownloadReport.EventInfo();
dlReport.Events[eventIndex].Description = eventDescriptions[eventIndex];
dlReport.Events[eventIndex].EventNumber = eventIndex;
dlReport.Events[eventIndex].TestID = eventIDs[eventIndex];
dlReport.Events[eventIndex].HasBeenDownloaded = false;
dlReport.Events[eventIndex].WasTriggered = false;
dlReport.Events[eventIndex].TestGUID = EventGuids[eventIndex];
dlReport.Events[eventIndex].ClearFaults();
dlReport.Events[eventIndex].Modules = dasModulesPerEvent[eventIndex].ToArray();
}
for (int eventIndex = 0; eventIndex < EventGuids.Length; eventIndex++)
{
double minPre = double.MaxValue;
double minPost = double.MaxValue;
bool dummyArmed = true;
foreach (var module in dasModulesPerEvent[eventIndex])
{
if (DASInfo.Modules[module.ModuleArrayIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK) { continue; }
if ((module.PreTriggerSeconds >= 0) && (module.PostTriggerSeconds >= 0))
{
// Negative trigger seconds are from dummy-armed modules
minPre = System.Math.Min(module.PreTriggerSeconds, minPre);
minPost = System.Math.Min(module.PostTriggerSeconds, minPost);
dummyArmed = false;
}
}
if (0 == dlReport.Events[eventIndex].Modules.Length) { }
else
{
if (!dummyArmed)
{
ulong numberOfSamples = Convert.ToUInt64((minPre + minPost) * dlReport.Events[eventIndex].Modules[0].SampleRateHz);
for (int i = 0; i < dlReport.Events[eventIndex].Modules.Length; i++)
{
DASModule module = (DASModule)dlReport.Events[eventIndex].Modules[i];
module.PreTriggerSeconds = minPre;
module.PostTriggerSeconds = minPost;
module.TriggerSampleNumbers = new ulong[]
{
Convert.ToUInt64(minPre*System.Math.Abs(module.SampleRateHz))
};
// If not triggered, racks return 0 and G5s return number of samples
if ((module.TriggerSampleNumbers[0] > 0) && (module.TriggerSampleNumbers[0] < numberOfSamples))
{
dlReport.Events[eventIndex].WasTriggered = true;
}
//the above statement the pretrigger seconds appears to be off by one sample, so I adjust it here as
//there might already be a lot of different side effects to changing the pre trigger time.
if (module.TriggerSampleNumbers[0] > 0) { module.TriggerSampleNumbers[0] = module.TriggerSampleNumbers[0] - 1; }
module.NumberOfSamples = numberOfSamples;
//module.NumberOfSamples = Convert.ToUInt64(qda.PreTriggerSamples + qda.PostTriggerSamples);
}
}
}
}
//normalize the data here just for sanity sake.
//IE, set start to min(abs(preTrigger))
//set end to min(abs(posttrigger))
//set t0 to min(abs(preTrigger))
SetEventInfo(dlReport);
SetEventDownloadStatus(eventDownloadStatus.ToArray());
if (null != EventInfo && EventInfo.Events.Length > 0)
{
for (int i = 0; i < EventInfo.Events.Length && i < EventDownloadedStatus.Length; i++)
{
if (EventInfo.Events[i].TestID == "TESTTRIG") { EventDownloadedStatus[i] = true; }
}
}
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (System.Exception ex)
{
info.Error(ex.Message, ex);
}
}
private void GetUserSelectedSetupInfo(TDASServiceSetupInfo setupInfo, ref string testConfig, ref string testDescription, ref double actualSampleRate,
ref float hardwareFilterRate, ref Command.TDAS.SetupDASLoad.ARMMode recordingMode)
{
if (setupInfo == null)
{
testConfig = "";
testDescription = "";
actualSampleRate = 1D;
hardwareFilterRate = 1F;
recordingMode = Command.TDAS.SetupDASLoad.ARMMode.WAIT;
}
else
{
// If this was from the Download tile, use the SETUP that the user selected
testConfig = "UsingUser-specifiedTestSetup";
testDescription = setupInfo.SetupDescription;
actualSampleRate = (double)setupInfo.SamplesPerSecond;
hardwareFilterRate = setupInfo.HardwareFilterRateHz;
switch (setupInfo.RecordingMode)
{
case DFConstantsAndEnums.RecordingMode.CircularBuffer:
case DFConstantsAndEnums.RecordingMode.CircularBufferPlusUART:
recordingMode = Command.TDAS.SetupDASLoad.ARMMode.WAIT;
break;
case DFConstantsAndEnums.RecordingMode.RecorderMode:
case DFConstantsAndEnums.RecordingMode.RecorderModePlusUART:
case DFConstantsAndEnums.RecordingMode.a14_NormalRecorderAndStreamSubSampleMode:
recordingMode = Command.TDAS.SetupDASLoad.ARMMode.TAPE;
break;
default:
recordingMode = Command.TDAS.SetupDASLoad.ARMMode.WAIT;
break;
}
}
}
#endregion
#region Set trigger sample numbers
void IDownloadActions.SetTriggerSampleNumbers(ServiceCallback callback, object userData)
{
throw new NotSupportedException("SetTriggerSampleNumbers not supported for TDAS");
}
#endregion
#region Set downloaded
void IDownloadActions.SetDownloaded(ServiceCallback callback, object userData)
{
var info = new TDASSetEventInfoAsync(callback, userData, 0, 1);
//FB12656: Launch synchronously. This call needs the full round-trip (4s) before proceeding with other commands
CallSyncMethod("TDAS.SetDownloaded", SendClearDataAvailable, info);
}
private void SendClearDataAvailable(object asyncInfo)
{
var info = asyncInfo as TDASSetEventInfoAsync;
try
{
if (UInt32.MaxValue != info.EventHasDownloaded)
{
foreach (DASModule module in ConfigData.Modules)
{
if (DASInfo.Modules[module.ModuleArrayIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK
|| module.IsDummyArmed())
{
continue;
}
Command.TDAS.ClearDataAvailable cda = new DTS.DASLib.Command.TDAS.ClearDataAvailable(this);
cda.ModuleIndex = module.ModuleArrayIndex;
cda.SyncExecute();
if (cda.IsErrored) { throw new Exception(string.Format("{0}:{1}", SerialNumber, cda.ResponseData)); }
// Only need to do once for G5
if (IsG5()) { break; }
}
}
}
catch (System.Exception ex)
{
info.Error("Failed to set event downloaded status", ex);
return;
}
info.Success();
}
#endregion
}
}