Inserting a Waveform Group Into a Data Set Example for C#
//*****************************************************************//
//* This is a comprehensive sample, which shows how to insert a *//
//* waveform group with one ECG channel into a Data Set. *//
//* The main function is InsertECGWaveform; the rest of the *//
//* functions are helping functions. *//
//*****************************************************************//
// The main function that creates the waveform group and adds to the Data Set
public bool InsertECGWaveform(ref LTDICLib.LEADDicomDS objDataSet, ref
short[] Samples)
{
bool tempInsertECGWaveform = false;
tempInsertECGWaveform = false;
// Our new waveform group
LTDICLib.DicomWaveformGroup objECGWaveformGroup
= new LTDICLib.DicomWaveformGroup();
objECGWaveformGroup.EnableMethodErrors
= false;
// Reset the waveform group, we don't really need to
call this!
objECGWaveformGroup.Reset();
// Set the Waveform Sample Interpretation
objECGWaveformGroup.SampleInterpretation
= LTDICLib.DicomWaveformSampleInterpretation.WAVEFORM_SAMPLE_INTERPRETATION_SS;
int lNumberOfSamples
= 0;
lNumberOfSamples = Samples.GetUpperBound(0) - Samples.GetLowerBound(0)
+ 1;
// Set the Number of Waveform Samples. You can obtain
this number by accessing
// the NumberOfSamplesPerChannel
property.
if (objECGWaveformGroup.SetNumberOfSamplesPerChannel(lNumberOfSamples)
!= (short)LTDicomKernelLib.DicomErrorCodes.DICOM_SUCCESS)
return tempInsertECGWaveform;
// Set the Sampling Frequency
objECGWaveformGroup.SamplingFrequency
= 240.0;
// No Multiplex Group Time Offset. When the value is
defined, it can be set using the
// MultiplexGroupTimeOffset property.
objECGWaveformGroup.set_ValueDefined(LTDICLib.DicomWaveformGroupValues.MULTIPLEX_GROUP_TIME_OFFSET,
false);
// No Trigger Time Offset. When the value is defined,
it can be set using the
// TriggerTimeOffset property.
objECGWaveformGroup.set_ValueDefined(LTDICLib.DicomWaveformGroupValues.TRIGGER_TIME_OFFSET,
false);
// No Trigger Sample Position. When the value is defined,
it can be set using the
// TriggerSamplePosition property.
objECGWaveformGroup.set_ValueDefined(LTDICLib.DicomWaveformGroupValues.TRIGGER_SAMPLE_POSITION,
false);
// Waveform Originality is ORIGINAL
objECGWaveformGroup.WaveformOriginality
= LTDICLib.DicomWaveformOriginality.WAVEFORM_ORIGINALITY_ORIGINAL;
// Set the Multiplex Group Label
objECGWaveformGroup.set_ValueDefined(LTDICLib.DicomWaveformGroupValues.MULTIPLEX_GROUP_LABEL,
true);
objECGWaveformGroup.MultiplexGroupLabel
= "SCPECG Waveform";
// Set the Waveform Padding Value
objECGWaveformGroup.set_ValueDefined(LTDICLib.DicomWaveformGroupValues.WAVEFORM_PADDING_VALUE,
true);
objECGWaveformGroup.WaveformPaddingValue = 32768;
if (! (InsertECGChannel(ref objDataSet, ref objECGWaveformGroup,
ref Samples)))
return tempInsertECGWaveform;
// Delete any waveform groups that already exist in the
Data Set
while (objDataSet.GetWaveformGroupCount()
> 0)
{
objDataSet.DeleteWaveformGroup(0,
0);
}
// Insert the new waveform group into the Data Set
if (objDataSet.AddWaveformGroup(objECGWaveformGroup,
0, -1) != (short)LTDicomKernelLib.DicomErrorCodes.DICOM_SUCCESS)
return tempInsertECGWaveform;
return true;
}
public bool InsertECGChannel(ref LTDICLib.LEADDicomDS objDataSet,
ref LTDICLib.DicomWaveformGroup objWaveformGroup, ref short[] Samples)
{
bool bInsertECGChannel = false;
bInsertECGChannel = false;
LTDICLib.DicomWaveformChannel objECGWaveformChannel =
null;
// Add a channel to the group
try
{
objECGWaveformChannel = objWaveformGroup.Channels.Add();
}
catch
{
return bInsertECGChannel;
}
// Set the samples of the channel
if (objECGWaveformChannel.SetChannelSamples(Samples)
< 0)
return bInsertECGChannel;
// Set the Channel Source and Sensitivity
if (! (SetChannelSourceAndSensitivity(ref objDataSet,
ref objECGWaveformChannel)))
return bInsertECGChannel;
// Set the Channel Status
objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.CHANNEL_STATUS,
true);
objECGWaveformChannel.ChannelStatus
= LTDICLib.DicomWaveformChannelStatus.CHANNEL_STATUS_OK;
// Set the Channel Time Skew
objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.CHANNEL_TIME_SKEW,
true);
objECGWaveformChannel.ChannelTimeSkew
= 0.0;
// Set the Waveform Channel Number
objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.WAVEFORM_CHANNEL_NUMBER,
true);
objECGWaveformChannel.WaveformChannelNumber
= 0;
// Set the Channel Label objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.CHANNEL_LABEL,
true);
objECGWaveformChannel.ChannelLabel
= "First Channel";
// No Channel Offset. When the value is defined, it can
be set using the ChannelOffset
// property
objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.CHANNEL_OFFSET,
false);
// Set the Filter Low Frequency
objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.FILTER_LOW_FREQUENCY,
true);
objECGWaveformChannel.FilterLowFrequency
= 0.05;
// Set Filter High Frequency
objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.FILTER_HIGH_FREQUENCY,
true);
objECGWaveformChannel.FilterHighFrequency
= 100.0;
// Set the Channel Minimum Value
objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.CHANNEL_MINIMUM_VALUE,
true);
objECGWaveformChannel.ChannelMinimumValue
= -386;
// Set the Channel Maximum Value
objECGWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.CHANNEL_MAXIMUM_VALUE,
true);
objECGWaveformChannel.ChannelMaximumValue
= 1264;
// When the Notch Filter Frequency and Bandwidth are
defined, they can be set using the
// NotchFilterFrequency
and NotchFilterBandwidth
properties.
// Last, but not least, set the channel annotations!
return SetChannelAnnotations(ref objECGWaveformChannel);
}
// Sets the Channel Source and Sensitivity
public bool SetChannelSourceAndSensitivity(ref LTDICLib.LEADDicomDS
objDataSet, ref LTDICLib.DicomWaveformChannel objWaveformChannel)
{
bool tempSetChannelSourceAndSensitivity = false;
tempSetChannelSourceAndSensitivity = false;
// We will use the Context Group Table
// -------------------- Channel Source --------------------
const string CID_3001 = "CID 3001";
// Load the ECG Leads Context Group objDataSet.LoadContextGroup(CID_3001);
if (! (objDataSet.FindContextGroup(CID_3001)))
return tempSetChannelSourceAndSensitivity;
// 5.6.3-9-1 is Lead I (Einthoven)
if (! (objDataSet.FindCodedConcept("SCPECG",
"5.6.3-9-1")))
return tempSetChannelSourceAndSensitivity;
// Set the Channel Source
objWaveformChannel.ChannelSource.CodingSchemeDesignator
= objDataSet.CurrentCodedConcept.CodingSchemeDesignator;
objWaveformChannel.ChannelSource.CodingSchemeVersion
= objDataSet.CurrentCodedConcept.CodingSchemeVersion;
objWaveformChannel.ChannelSource.CodeValue
= objDataSet.CurrentCodedConcept.CodeValue;
objWaveformChannel.ChannelSource.CodeMeaning
= objDataSet.CurrentCodedConcept.CodeMeaning;
// -------------------- Channel Sensitivity --------------------
objWaveformChannel.set_ValueDefined(LTDICLib.DicomWaveformChannelValues.CHANNEL_SENSITIVITY,
true);
// The Channel Sensitivity
objWaveformChannel.ChannelSensitivity
= 0.00122;
const string CID_3082 = "CID 3082";
// Load the Cardiology Units of Measurement Context Group
objDataSet.LoadContextGroup(CID_3082);
if (! (objDataSet.FindContextGroup(CID_3082)))
return tempSetChannelSourceAndSensitivity;
if (! (objDataSet.FindCodedConcept("UCUM",
"mV")))
return tempSetChannelSourceAndSensitivity;
// The Channel Sensitivity Units
objWaveformChannel.ChannelSensitivityUnits.CodingSchemeDesignator
= objDataSet.CurrentCodedConcept.CodingSchemeDesignator;
objWaveformChannel.ChannelSensitivityUnits.CodingSchemeVersion
= objDataSet.CurrentCodedConcept.CodingSchemeVersion;
objWaveformChannel.ChannelSensitivityUnits.CodeValue
= objDataSet.CurrentCodedConcept.CodeValue;
objWaveformChannel.ChannelSensitivityUnits.CodeMeaning
= objDataSet.CurrentCodedConcept.CodeMeaning;
// The Channel Sensitivity Correction Factor
objWaveformChannel.ChannelSensitivityCF
= 1.0;
// The Channel Baseline
objWaveformChannel.ChannelBaseline
= 0.0;
return true;
}
// Adds annotations for the channel
public bool SetChannelAnnotations(ref LTDICLib.DicomWaveformChannel objWaveformChannel)
{
bool bSetChannelAnnotations = false;
string ActiveErrorHandler = null;
bSetChannelAnnotations = false;
// Delete any existing channel annotations
while (objWaveformChannel.Annotations.Count
> 0)
{
objWaveformChannel.Annotations.Remove(0);
}
LTDICLib.DicomWaveformAnnotation objECGWaveformAnnotation
= null;
// Add an annotation object
try
{
objECGWaveformAnnotation = objWaveformChannel.Annotations.Add();
}
catch
{
return bSetChannelAnnotations;
}
ActiveErrorHandler = "";
// Our annotation is defined by a Coded Name/Numeric
Measurement pair
objECGWaveformAnnotation.ValueType
= LTDICLib.DicomWaveformAnnValueType.TYPE_CODED_NAME_AND_NUMERIC_VALUE;
// The Coded Name. Note: Instead of setting these values
directly, you can also use
// the Context Group Table; the Context Groups defined
by the DICOM Content Mapping
// Resource (DCMR) can be loaded into this table. Take
a look at the function
// SetChannelSourceAndSensitivity above for an example.
objECGWaveformAnnotation.CodedName.CodingSchemeDesignator
= "LN";
objECGWaveformAnnotation.CodedName.CodingSchemeVersion
= "19971101";
objECGWaveformAnnotation.CodedName.CodeValue
= "8867-4";
objECGWaveformAnnotation.CodedName.CodeMeaning
= "Heart rate";
// The Numeric Value
try
{
objECGWaveformAnnotation.NumericValueCount
= 1;
}
catch
{
return bSetChannelAnnotations;
}
ActiveErrorHandler = "";
objECGWaveformAnnotation.set_NumericValue(0, 69.0);
// The Measurement Units. Refer to the note given when
the Coded Name was set.
objECGWaveformAnnotation.set_ValueDefined(LTDICLib.DicomWaveformAnnValues.MEASUREMENT_UNITS,
true);
objECGWaveformAnnotation.MeasurementUnits.CodingSchemeDesignator
= "UCUM";
objECGWaveformAnnotation.MeasurementUnits.CodingSchemeVersion
= "1.4";
objECGWaveformAnnotation.MeasurementUnits.CodeValue
= "{H.B.}/min";
objECGWaveformAnnotation.MeasurementUnits.CodeMeaning
= "Heart beat per minute";
return true;
}