public int WaveformGroupCount { get; }
Public ReadOnly Property WaveformGroupCount As Integer
public:
property int WaveformGroupCount {
int get();
}
Value that represents the number of waveform multiplex groups that are included in the dataset.
In DICOM, a waveform consists of one or more multiplex groups, each encoded into an item in the "Waveform Sequence" (5400,0100). Use this method to retrieve the number of items under that sequence. Once you know the total number of multiplex groups, call the GetWaveformGroup method to extract a specific group or the DeleteWaveformGroup method to delete it.
This is a comprehensive sample, which shows how to insert a waveform group with one ECG channel into a dataset. The main method is InsertECGCWaveform ,and the rest of the methods are helping methods.All these methods are assumed to be part of the same class. The main method that creates the waveform group and adds it to the dataset
using Leadtools;
using Leadtools.Dicom;
public void InsertECGCWaveform(DicomDataSet inputDS, short[] samples, int count)
{
// Our new waveform group
DicomWaveformGroup ECGWaveformGroup = new DicomWaveformGroup();
// Reset the waveform group, we don't
// really need to call this!
ECGWaveformGroup.Reset();
// Set the number of samples per channel. You can call
// DicomWaveformGroup.GetNumberOfSamplesPerChannel to get
// the number of samples
ECGWaveformGroup.SetNumberOfSamplesPerChannel(count);
// Set the sampling frequency. You can call
// DicomWaveformGroup.GetSamplingFrequency to
// get the sampling frequency
ECGWaveformGroup.SetSamplingFrequency(240.00);
// Set sample interpretation
ECGWaveformGroup.SetSampleInterpretation(DicomWaveformSampleInterpretationType.Signed16BitLinear);
// Just in case!
Debug.Assert(ECGWaveformGroup.GetSampleInterpretation() == DicomWaveformSampleInterpretationType.Signed16BitLinear);
// No Multiplex Group Time Offset
// You can call DicomWaveformGroup.GetMultiplexGroupTimeOffset
// to get the time offset
ECGWaveformGroup.SetMultiplexGroupTimeOffset(false, 0.0);
// No Trigger Time Offset
// You can call DicomWaveformGroup.GetTriggerTimeOffset
// to get the trigger time offset
ECGWaveformGroup.SetTriggerTimeOffset(false, 0.0);
// No Trigger Sample Position
// You can call DicomWaveformGroup.GetTriggerSamplePosition
// to get the trigger sample position
ECGWaveformGroup.SetTriggerSamplePosition(false, 0);
// Waveform originality is original
ECGWaveformGroup.SetWaveformOriginality(DicomWaveformOriginalityType.Original);
// Just in case!
Debug.Assert(ECGWaveformGroup.GetWaveformOriginality() == DicomWaveformOriginalityType.Original);
// Set the multiplex group label
ECGWaveformGroup.SetMultiplexGroupLabel("SCPECG Waveform");
Debug.Assert(ECGWaveformGroup.GetMultiplexGroupLabel() == "SCPECG Waveform");
// Set the Waveform padding value
// You can call DicomWaveformGroup.GetWaveformPaddingValue
// to get the waveform padding value
ECGWaveformGroup.SetWaveformPaddingValue(true, 32768);
InsertECGCChannel(ECGWaveformGroup, samples, count);
// Delete any waveform groups that already exist in the dataset
for (int index = 0; index < inputDS.WaveformGroupCount; index++)
{
inputDS.DeleteWaveformGroup(index);
}
// Insert the new waveform group into the dataset
inputDS.AddWaveformGroup(ECGWaveformGroup, 0);
}
// Add an ECG channel to the group
void InsertECGCChannel(DicomWaveformGroup ECGWaveformGroup, short[] samples, int count)
{
// Add a channel to the group
DicomWaveformChannel ECGChannel = ECGWaveformGroup.AddChannel(1);
if (ECGChannel == null)
{
return;
}
// If we want to update a channel, we can first call
// DicomWaveformGroup.DeleteChannel and then call
// DicomWaveformGroup.AddChannel with the same
// index we passed to DeleteChannel
// Make sure that the channel really got added
// This is for the purposes of this sample only, because
// the check we did in the previous statement is enough
if ((ECGWaveformGroup.ChannelCount != 1) ||
(ECGWaveformGroup.GetChannel(0) == null))
{
return;
}
// We can call DicomWaveformChannel.GetWaveformGroup to access the waveform
// group that the channel belongs to
if (ECGChannel.Index != 0)
{
return;
}
/*
Set the channel samples
The data we are setting in here is 16 bit data.
We would call SetChannelSamples8 if the data were 8 bit.
We can also call SetChannelSamples32, which will set the data
as either 8-bit or 16-bit depending on the sample interpretation
*/
if (ECGChannel.SetChannelSamples16(samples, count) != count)
{
return;
}
if ((ECGChannel.GetChannelSamples() == null) || (ECGChannel.GetChannelSamplesCount() == 0))
return;
// Set the channel source and sensitivity
SetChannelSourceAndSensitivity(ECGChannel);
// Set the channel status
ECGChannel.SetChannelStatus(DicomChannelStatusType.OK);
if (ECGChannel.GetChannelStatus() != DicomChannelStatusType.OK)
{
return;
}
// Set the channel time skew. You can call
// LDicomWaveformChannel::GetChannelTimeSkew to get the time skew
// You can also call DicomWaveformChannel.SetChannelSampleSkew
// And DicomWaveformChannel.GetChannelSampleSkew to set and get
// the channel samples skew
ECGChannel.SetChannelTimeSkew(0.000000);
// Set the waveform channel number
ECGChannel.SetWaveformChannelNumber(true, 0);
if (ECGChannel.GetWaveformChannelNumber() != 0)
return;
// Set the channel label
ECGChannel.SetChannelLabel("First Channel");
if (ECGChannel.GetChannelLabel() != "First Channel")
return;
// No channel offset
// You can also call DicomWaveformChannel.GetChannelOffset
// To get the channel offset
ECGChannel.SetChannelOffset(false, 0.0);
// Set filter low frequency
// You can also call DicomWaveformChannel.GetFilterLowFrequency
// To get the filter low frequency
ECGChannel.SetFilterLowFrequency(true, 0.050);
// Set filter high frequency
// You can also call DicomWaveformChannel.GetFilterHighFrequency
// To get the filter high frequency
ECGChannel.SetFilterHighFrequency(true, 100.00);
// Set the channel minimum value
ECGChannel.SetChannelMinimumValue(true, -386);
// Set the channel maximum value
ECGChannel.SetChannelMaximumValue(true, 1264);
if (ECGChannel.GetChannelMinimumValue() != -386)
return;
if (ECGChannel.GetChannelMaximumValue() != 1264)
return;
/*
You can also call the following functions to set and get the notch
filter frequency and bandwidth
DicomWaveformChannel.SetNotchFilterFrequency
DicomWaveformChannel.GetNotchFilterFrequency
DicomWaveformChannel.SetNotchFilterBandwidth
DicomWaveformChannel.GetNotchFilterBandwidth
*/
// Last, but not least, set the channel annotations!
SetChannelAnnotations(ECGChannel);
}
//Set the channel source and sensitivity
void SetChannelSourceAndSensitivity(DicomWaveformChannel channel)
{
// Let's use the DICOM context group tables!
///////////////////////Channel Source/////////////////////////
// Load the ECG Leads table
DicomContextGroupTable.Instance.Load(DicomContextIdentifierType.CID3001);
DicomContextGroup ECGLeadsGroup = DicomContextGroupTable.Instance.Find(DicomContextIdentifierType.CID3001);
Assert.IsNotNull(ECGLeadsGroup);
DicomContextIdentifierType type = ECGLeadsGroup.ContextIdentifier;
DicomCodedConcept codedConcept = DicomContextGroupTable.Instance.FindCodedConcept(ECGLeadsGroup, "MDC", "2:1");
Assert.IsNotNull(codedConcept);
using (DicomCodeSequenceItem codeSequenceItem = new DicomCodeSequenceItem())
{
codeSequenceItem.CodeValue = codedConcept.CodeValue;
codeSequenceItem.CodingSchemeDesignator = codedConcept.CodingSchemeDesignator;
codeSequenceItem.CodingSchemeVersion = codedConcept.CodingSchemeVersion;
codeSequenceItem.CodeMeaning = codedConcept.CodeMeaning;
// Set the channel source
channel.SetChannelSource(codeSequenceItem);
}
///////////////////////Channel Sensitivity////////////////////////
using (DicomCodeSequenceItem sourceSequenceItem = new DicomCodeSequenceItem())
{
sourceSequenceItem.CodeValue = "mV";
sourceSequenceItem.CodingSchemeDesignator = "UCUM";
sourceSequenceItem.CodingSchemeVersion = string.Empty;
sourceSequenceItem.CodeMeaning = "millivolt";
// Set the channel sensitivity
channel.SetChannelSensitivity(true, 0.001220, sourceSequenceItem, 1.0, 0.0);
}
}
// Add annotations for the channel
void SetChannelAnnotations(DicomWaveformChannel channel)
{
// Delete any existing channel annotations
for (int index = 0; index < channel.GetAnnotationCount(); index++)
{
if (channel.GetAnnotation(index) != null)
{
channel.DeleteAnnotation(index);
}
}
DicomWaveformAnnotation waveformAnnotation = new DicomWaveformAnnotation();
DicomCodeSequenceItem codedName = new DicomCodeSequenceItem();
codedName.CodeValue = "8867-4";
codedName.CodeMeaning = "Heart rate";
codedName.CodingSchemeDesignator = "LN";
codedName.CodingSchemeVersion = "19971101";
waveformAnnotation.CodedName = codedName;
//Over here we can access other properties such as
// waveformAnnotation.CodedValue and waveformAnnotation.UnformattedTextValue
DicomCodeSequenceItem measurementUnits = new DicomCodeSequenceItem();
measurementUnits.CodeValue = "{H.B.}/min";
measurementUnits.CodeMeaning = "Heart beat per minute";
measurementUnits.CodingSchemeDesignator = "UCUM";
measurementUnits.CodingSchemeVersion = "1.4";
waveformAnnotation.MeasurementUnits = measurementUnits;
waveformAnnotation.SetNumericValue(new double[] { 69.00 }, 1);
channel.AddAnnotation(waveformAnnotation);
}
Imports Leadtools
Imports Leadtools.Dicom
Public Sub InsertECGCWaveform(ByVal inputDS As DicomDataSet, ByVal samples As Short(), ByVal count As Integer)
' Our new waveform group
Dim ECGWaveformGroup As DicomWaveformGroup = New DicomWaveformGroup()
' Reset the waveform group, we don't
' really need to call this!
ECGWaveformGroup.Reset()
' Set the number of samples per channel. You can call
' DicomWaveformGroup.GetNumberOfSamplesPerChannel to get
' the number of samples
ECGWaveformGroup.SetNumberOfSamplesPerChannel(count)
' Set the sampling frequency. You can call
' DicomWaveformGroup.GetSamplingFrequency to
' get the sampling frequency
ECGWaveformGroup.SetSamplingFrequency(240.0)
' Set sample interpretation
ECGWaveformGroup.SetSampleInterpretation(DicomWaveformSampleInterpretationType.Signed16BitLinear)
' Just in case!
Debug.Assert(ECGWaveformGroup.GetSampleInterpretation() = DicomWaveformSampleInterpretationType.Signed16BitLinear)
' No Multiplex Group Time Offset
' You can call DicomWaveformGroup.GetMultiplexGroupTimeOffset
' to get the time offset
ECGWaveformGroup.SetMultiplexGroupTimeOffset(False, 0.0)
' No Trigger Time Offset
' You can call DicomWaveformGroup.GetTriggerTimeOffset
' to get the trigger time offset
ECGWaveformGroup.SetTriggerTimeOffset(False, 0.0)
' No Trigger Sample Position
' You can call DicomWaveformGroup.GetTriggerSamplePosition
' to get the trigger sample position
ECGWaveformGroup.SetTriggerSamplePosition(False, 0)
' Waveform originality is original
ECGWaveformGroup.SetWaveformOriginality(DicomWaveformOriginalityType.Original)
' Just in case!
Debug.Assert(ECGWaveformGroup.GetWaveformOriginality() = DicomWaveformOriginalityType.Original)
' Set the multiplex group label
ECGWaveformGroup.SetMultiplexGroupLabel("SCPECG Waveform")
Debug.Assert(ECGWaveformGroup.GetMultiplexGroupLabel() = "SCPECG Waveform")
' Set the Waveform padding value
' You can call DicomWaveformGroup.GetWaveformPaddingValue
' to get the waveform padding value
ECGWaveformGroup.SetWaveformPaddingValue(True, 32768)
InsertECGCChannel(ECGWaveformGroup, samples, count)
' Delete any waveform groups that already exist in the dataset
Dim index As Integer = 0
Do While index < inputDS.WaveformGroupCount
inputDS.DeleteWaveformGroup(index)
index += 1
Loop
' Insert the new waveform group into the dataset
inputDS.AddWaveformGroup(ECGWaveformGroup, 0)
End Sub
' Add an ECG channel to the group
Private Sub InsertECGCChannel(ByVal ECGWaveformGroup As DicomWaveformGroup, ByVal samples As Short(), ByVal count As Integer)
' Add a channel to the group
Dim ECGChannel As DicomWaveformChannel = ECGWaveformGroup.AddChannel(1)
If ECGChannel Is Nothing Then
Return
End If
' If we want to update a channel, we can first call
' DicomWaveformGroup.DeleteChannel and then call
' DicomWaveformGroup.AddChannel with the same
' index we passed to DeleteChannel
' Make sure that the channel really got added
' This is for the purposes of this sample only, because
' the check we did in the previous statement is enough
If (ECGWaveformGroup.ChannelCount <> 1) OrElse (ECGWaveformGroup.GetChannel(0) Is Nothing) Then
Return
End If
' We can call DicomWaveformChannel.GetWaveformGroup to access the waveform
' group that the channel belongs to
If ECGChannel.Index <> 0 Then
Return
End If
'
'Set the channel samples
'The data we are setting in here is 16 bit data.
'We would call SetChannelSamples8 if the data were 8 bit.
'We can also call SetChannelSamples32, which will set the data
'as either 8-bit or 16-bit depending on the sample interpretation
'
If ECGChannel.SetChannelSamples16(samples, count) <> count Then
Return
End If
If (ECGChannel.GetChannelSamples() Is Nothing) OrElse (ECGChannel.GetChannelSamplesCount() = 0) Then
Return
End If
' Set the channel source and sensitivity
SetChannelSourceAndSensitivity(ECGChannel)
' Set the channel status
ECGChannel.SetChannelStatus(DicomChannelStatusType.OK)
If ECGChannel.GetChannelStatus() <> DicomChannelStatusType.OK Then
Return
End If
' Set the channel time skew. You can call
' LDicomWaveformChannel::GetChannelTimeSkew to get the time skew
' You can also call DicomWaveformChannel.SetChannelSampleSkew
' And DicomWaveformChannel.GetChannelSampleSkew to set and get
' the channel samples skew
ECGChannel.SetChannelTimeSkew(0.0)
' Set the waveform channel number
ECGChannel.SetWaveformChannelNumber(True, 0)
If ECGChannel.GetWaveformChannelNumber() <> 0 Then
Return
End If
' Set the channel label
ECGChannel.SetChannelLabel("First Channel")
If ECGChannel.GetChannelLabel() <> "First Channel" Then
Return
End If
' No channel offset
' You can also call DicomWaveformChannel.GetChannelOffset
' To get the channel offset
ECGChannel.SetChannelOffset(False, 0.0)
' Set filter low frequency
' You can also call DicomWaveformChannel.GetFilterLowFrequency
' To get the filter low frequency
ECGChannel.SetFilterLowFrequency(True, 0.05)
' Set filter high frequency
' You can also call DicomWaveformChannel.GetFilterHighFrequency
' To get the filter high frequency
ECGChannel.SetFilterHighFrequency(True, 100.0)
' Set the channel minimum value
ECGChannel.SetChannelMinimumValue(True, -386)
' Set the channel maximum value
ECGChannel.SetChannelMaximumValue(True, 1264)
If ECGChannel.GetChannelMinimumValue() <> -386 Then
Return
End If
If ECGChannel.GetChannelMaximumValue() <> 1264 Then
Return
End If
'
'You can also call the following functions to set and get the notch
'filter frequency and bandwidth
'DicomWaveformChannel.SetNotchFilterFrequency
'DicomWaveformChannel.GetNotchFilterFrequency
'DicomWaveformChannel.SetNotchFilterBandwidth
'DicomWaveformChannel.GetNotchFilterBandwidth
'
' Last, but not least, set the channel annotations!
SetChannelAnnotations(ECGChannel)
End Sub
'Set the channel source and sensitivity
Private Sub SetChannelSourceAndSensitivity(ByVal channel As DicomWaveformChannel)
' Let's use the DICOM context group tables!
'/////////////////////Channel Source/////////////////////////
' Load the ECG Leads table
DicomContextGroupTable.Instance.Load(DicomContextIdentifierType.CID3001)
Dim ECGLeadsGroup As DicomContextGroup = DicomContextGroupTable.Instance.Find(DicomContextIdentifierType.CID3001)
Assert.IsNotNull(ECGLeadsGroup)
Dim type As DicomContextIdentifierType = ECGLeadsGroup.ContextIdentifier
Dim codedConcept As DicomCodedConcept = DicomContextGroupTable.Instance.FindCodedConcept(ECGLeadsGroup, "MDC", "2:1")
Assert.IsNotNull(codedConcept)
Using codeSequenceItem As New DicomCodeSequenceItem()
codeSequenceItem.CodeValue = codedConcept.CodeValue
codeSequenceItem.CodingSchemeDesignator = codedConcept.CodingSchemeDesignator
codeSequenceItem.CodingSchemeVersion = codedConcept.CodingSchemeVersion
codeSequenceItem.CodeMeaning = codedConcept.CodeMeaning
' Set the channel source
channel.SetChannelSource(codeSequenceItem)
End Using
'/////////////////////Channel Sensitivity////////////////////////
Using sourceSequenceItem As New DicomCodeSequenceItem()
sourceSequenceItem.CodeValue = "mV"
sourceSequenceItem.CodingSchemeDesignator = "UCUM"
sourceSequenceItem.CodingSchemeVersion = String.Empty
sourceSequenceItem.CodeMeaning = "millivolt"
' Set the channel sensitivity
channel.SetChannelSensitivity(True, 0.00122, sourceSequenceItem, 1.0, 0.0)
End Using
End Sub
' Add annotations for the channel
Private Sub SetChannelAnnotations(ByVal channel As DicomWaveformChannel)
' Delete any existing channel annotations
Dim index As Integer = 0
Do While index < channel.GetAnnotationCount()
If Not channel.GetAnnotation(index) Is Nothing Then
channel.DeleteAnnotation(index)
End If
index += 1
Loop
Dim waveformAnnotation As DicomWaveformAnnotation = New DicomWaveformAnnotation()
Dim codedName As DicomCodeSequenceItem = New DicomCodeSequenceItem()
codedName.CodeValue = "8867-4"
codedName.CodeMeaning = "Heart rate"
codedName.CodingSchemeDesignator = "LN"
codedName.CodingSchemeVersion = "19971101"
waveformAnnotation.CodedName = codedName
'Over here we can access other properties such as
'waveformAnnotation.CodedValue and waveformAnnotation.UnformattedTextValue
Dim measurementUnits As DicomCodeSequenceItem = New DicomCodeSequenceItem()
measurementUnits.CodeValue = "{H.B.}/min"
measurementUnits.CodeMeaning = "Heart beat per minute"
measurementUnits.CodingSchemeDesignator = "UCUM"
measurementUnits.CodingSchemeVersion = "1.4"
waveformAnnotation.MeasurementUnits = measurementUnits
waveformAnnotation.SetNumericValue(New Double() {69.0}, 1)
channel.AddAnnotation(waveformAnnotation)
End Sub
Help Collections
Raster .NET | C API | C++ Class Library | HTML5 JavaScript
Document .NET | C API | C++ Class Library | HTML5 JavaScript
Medical .NET | C API | C++ Class Library | HTML5 JavaScript
Medical Web Viewer .NET
Multimedia
Direct Show .NET | C API | Filters
Media Foundation .NET | C API | Transforms
Supported Platforms
.NET, Java, Android, and iOS/macOS Assemblies
Imaging, Medical, and Document
C API/C++ Class Libraries
Imaging, Medical, and Document
HTML5 JavaScript Libraries
Imaging, Medical, and Document