init
This commit is contained in:
988
DataPRO/IService/Classes/TDAS Service/Download.cs
Normal file
988
DataPRO/IService/Classes/TDAS Service/Download.cs
Normal file
@@ -0,0 +1,988 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user