L_DicomChannelSetSamples8

#include "Ltdic.h"

L_LTDIC_API L_UINT32 L_DicomChannelSetSamples8(hDICOMWaveFormChannel, pSamples, uCount)

Sets 8-bit data for a channel.

Parameters

HDICOMWAVEFORMCHANNEL hDICOMWaveFormChannel

A DICOM waveform channel handle.

L_UCHAR * pSamples

Pointer to the buffer that holds the new channel samples.

L_UINT32 uCount

Size of the buffer pointed to by pSamples.

Returns

The actual number of samples set for the channel.

Comments

This function sets the new samples for a channel. Before calling the L_DicomChannelSetSamples8 function, be sure to call L_DicomWaveGrpSetSampleInterpretation to set the waveform sample interpretation.

The number of samples actually set will be less than or equal to the "Number of samples per channel" (003A, 0010) in the multiplex group that represents the parent of this channel. To get that number, call the L_DicomWaveGrpGetNumberOfSamplesPerChannel function.

This function is intended to be used for setting the data of 8-bit channels where the "Waveform Sample Interpretation" (5400,1006) is signed 8-bit linear (DICOM_SAMPLE_INTERPRETATION_SB), unsigned 8-bit linear (DICOM_SAMPLE_INTERPRETATION_UB), 8-bit mu-law (DICOM_SAMPLE_INTERPRETATION_MB) or 8-bit A-law (DICOM_SAMPLE_INTERPRETATION_AB). To get the waveform sample interpretation, use the L_DicomWaveGrpGetSampleInterpretation function.

Required DLLs and Libraries

Platforms

Win32, x64, Linux.

See Also

Functions

Topics

Example

This is a comprehensive sample which shows how to insert a
waveform group with one ECG channel into a dataset.
The main function is InsertECGCWaveform ,and the rest of the functions are helping functions.

// Function prototypes 
L_INT SetChannelSourceAndSensitivity(HDICOMWAVEFORMCHANNEL  hECGChannel); 
L_INT SetChannelAnnotations(HDICOMWAVEFORMCHANNEL  hECGChannel); 
L_INT InsertECGCChannel(HDICOMWAVEFORMGROUP hECGWaveformGroup, L_INT16* pSamples, L_UINT32 uSampleCount); 
 
// The main function that creates the  
// waveform group and adds to the dataset 
L_INT DicomChannelSetSamples8Example( 
   HDICOMDS hInputDS, 
   L_INT16* pSamples, 
   L_UINT32 uSampleCount) 
{ 
   HDICOMWAVEFORMGROUP  hECGWaveformGroup = NULL; 
   L_UINT32             uWaveformGroupCount=0; 
   L_UINT32             uIndex=0; 
   L_UINT16             nRet; 
  
   // Sanity check 
   if(!pSamples || (uSampleCount == 0) || !hInputDS)  
      return ERROR_INV_PARAMETER; 
 
   // Our new waveform group 
   hECGWaveformGroup = L_DicomWaveGrpCreate(); 
   if(hECGWaveformGroup == NULL) 
      return DICOM_ERROR_NULL_PTR; 
 
   // Reset the waveform group, we don't  
   // really need to call this! 
   L_DicomWaveGrpReset(hECGWaveformGroup); 
    
    
   // Set the number of samples per channel. You can call  
   // L_DicomWaveGrpGetNumberOfSamplesPerChannel to get  
   // the number of samples 
           
   if(!L_DicomWaveGrpSetNumberOfSamplesPerChannel(hECGWaveformGroup,uSampleCount)) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
  
   // Set the sampling frequency. You can call  
   // L_DicomWaveGrpGetSamplingFrequency to  
   // get the sampling frequency 
   L_DicomWaveGrpSetSamplingFrequency(hECGWaveformGroup,240.00); 
 
   // Set sample interpretation 
   if(!L_DicomWaveGrpSetSampleInterpretation(hECGWaveformGroup,DICOM_SAMPLE_INTERPRETATION_SS)) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
   // Just in case! 
   if(L_DicomWaveGrpGetSampleInterpretation(hECGWaveformGroup) != DICOM_SAMPLE_INTERPRETATION_SS) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
  
   // No Multiplex Group Time Offset 
   // You can call L_DicomWaveGrpGetMultiplexGroupTimeOffset  
   // to get the time offset 
   if(!L_DicomWaveGrpSetMultiplexGroupTimeOffset(hECGWaveformGroup,FALSE, 0.0)) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
   // No Trigger Time Offset 
   // You can call L_DicomWaveGrpGetTriggerTimeOffset  
   // to get the trigger time offset 
   if(!L_DicomWaveGrpSetTriggerTimeOffset(hECGWaveformGroup,FALSE, 0.0)) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   }    
   // No Trigger Sample Position 
   // You can call L_DicomWaveGrpGetTriggerSamplePosition 
   // to get the trigger sample position 
   if(!L_DicomWaveGrpSetTriggerSamplePosition(hECGWaveformGroup,FALSE, 0)) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
  
   // Waveform originality is original    
   L_DicomWaveGrpSetOriginality(hECGWaveformGroup,DICOM_WAVEFORM_ORIGINALITY_ORIGINAL); 
    
   // Just in case 
   if(L_DicomWaveGrpGetOriginality(hECGWaveformGroup) != DICOM_WAVEFORM_ORIGINALITY_ORIGINAL) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
    
   // Set the multiplex group label 
   if(!L_DicomWaveGrpSetMultiplexGroupLabel(hECGWaveformGroup,TEXT("SCPECG Waveform"))) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
   if(L_DicomWaveGrpGetMultiplexGroupLabel(hECGWaveformGroup) == NULL) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
  
   // Set the Waveform padding value 
   // You can call L_DicomWaveGrpGetPaddingValue 
   // to get the waveform padding value 
   if(!L_DicomWaveGrpSetPaddingValue(hECGWaveformGroup,TRUE,32768)) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return FAILURE - 1; 
   } 
 
   nRet = (L_UINT16) InsertECGCChannel(hECGWaveformGroup, pSamples, uSampleCount); 
   if (nRet != DICOM_SUCCESS) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return nRet; 
   } 
   // Delete any waveform groups that already exist in the dataset 
   uWaveformGroupCount = L_DicomGetWaveformGroupCount(hInputDS); 
   for(uIndex = 0 ; uIndex < uWaveformGroupCount ; uIndex++) 
   { 
      nRet = L_DicomDeleteWaveformGroup(hInputDS,uIndex,0); 
      if (nRet != DICOM_SUCCESS) 
      { 
         L_DicomWaveGrpFree(hECGWaveformGroup); 
         return nRet; 
      } 
   } 
   // Insert the new waveform group into the dataset 
   nRet = L_DicomAddWaveformGroup(hInputDS,hECGWaveformGroup,0, ELEMENT_INDEX_MAX); 
   if(nRet !=  DICOM_SUCCESS) 
   { 
      L_DicomWaveGrpFree(hECGWaveformGroup); 
      return nRet; 
   } 
 
   L_DicomWaveGrpFree(hECGWaveformGroup); 
   return DICOM_SUCCESS; 
} 
  
// Add an ECG channel to the group 
L_INT InsertECGCChannel( 
   HDICOMWAVEFORMGROUP hECGWaveformGroup, 
   L_INT16* pSamples, 
   L_UINT32 uSampleCount) 
{ 
   HDICOMWAVEFORMCHANNEL hECGChannel = NULL; 
   L_UINT32 uNumberOfSamples = 0; 
   L_INT32 nChannelNumber = -1; 
   L_INT32 nMinValue = 0; 
   L_INT32 nMaxValue = 0; 
   L_INT nRet; 
    
   if(hECGWaveformGroup == NULL) 
      return ERROR_INV_PARAMETER; 
 
   // Add a channel to the group 
   // If you want to create a channel which is not part of a waveform group, then you need to  
   // call the L_DicomChannelCreate function to create it, and then call L_DicomChannelFree to free 
   // it when you are  
   // finished with the channel. This is not recommended, however. 
   // When creating a channel, it is best to call L_DicomWaveGrpAddChannel which creates a channel 
   // as part of a waveform group. 
   hECGChannel = L_DicomWaveGrpAddChannel(hECGWaveformGroup, ELEMENT_INDEX_MAX); 
   if(hECGChannel == NULL) 
      return DICOM_ERROR_NULL_PTR; 
 
   // If we want to update a channel, we can first call  
   // L_DicomWaveGrpDeleteChannel and then call  
   // L_DicomWaveGrpAddChannel with the same  
   // index we passed to L_DicomWaveGrpDeleteChannel 
  
   // 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(   (L_DicomWaveGrpGetNumberOfChannels(hECGWaveformGroup) != 1)|| 
         (L_DicomWaveGrpGetChannel(hECGWaveformGroup,0) == NULL) ) 
      return DICOM_ERROR_NULL_PTR; 
 
   // Sanity checks! 
   if((L_DicomChannelGetWaveformGroup(hECGChannel) != hECGWaveformGroup)|| 
      (L_DicomChannelGetIndex(hECGChannel) != 0)) 
      return DICOM_ERROR_NULL_PTR; 
 
   /* Set the channel samples 
      The data we are setting in here is 16 bit data. 
      We would call L_DicomChannelSetSamples8 if the data were 8 bit. 
      We can also call L_DicomChannelSetSamples32, which will set the data 
      as either 8-bit or 16-bit depending on the sample interpretation */ 
   if(L_DicomChannelSetSamples16(hECGChannel,pSamples, uSampleCount) != uSampleCount) 
      return FAILURE - 1; 
 
   // Just in case 
   if((!L_DicomChannelGetSamples(hECGChannel, &uNumberOfSamples))|| 
      (uNumberOfSamples == 0)) 
      return FAILURE - 1; 
 
   // Set the channel source and sensitivity 
   nRet = SetChannelSourceAndSensitivity(hECGChannel); 
   if(nRet != DICOM_SUCCESS) 
      return nRet; 
 
   // Set the channel status 
   L_DicomChannelSetStatus(hECGChannel,DICOM_CHANNEL_STATUS_OK); 
   nRet = L_DicomChannelGetStatus(hECGChannel); 
   if(nRet != DICOM_CHANNEL_STATUS_OK) 
      return nRet; 
 
   // Set the channel time skew. You can call  
   // L_DicomChannelGetTimeSkew to get the time skew 
   // You can also call L_DicomChannelSetSampleSkew 
   // And L_DicomChannelGetSampleSkew to set and get  
   // the channel samples skew 
   if (!L_DicomChannelSetTimeSkew(hECGChannel,0.000000)) 
      return FAILURE - 1; 
  
   // Set the waveform channel number 
   if(!L_DicomChannelSetNumber(hECGChannel,TRUE, 0)) 
      return FAILURE - 1; 
 
   if((!L_DicomChannelGetNumber(hECGChannel,&nChannelNumber)) || 
      (nChannelNumber != 0)) 
      return FAILURE - 1; 
 
   // Set the channel label 
   if(!L_DicomChannelSetLabel(hECGChannel,TEXT("First Channel"))) 
      return FAILURE - 1; 
 
   if(!L_DicomChannelGetLabel(hECGChannel)) 
      return FAILURE - 1; 
 
   // No channel offset 
   // You can also call L_DicomChannelGetOffset 
   // To get the channel offset 
   if(!L_DicomChannelSetOffset(hECGChannel,FALSE, 0.0)) 
      return FAILURE - 1; 
 
   // Set filter low frequency 
   // You can also call L_DicomChannelGetFilterLowFrequency 
   // To get the filter low frequency    
   if(!L_DicomChannelSetFilterLowFrequency(hECGChannel,TRUE, 0.050)) 
      return FAILURE - 1; 
 
   // Set filter high frequency 
   // You can also call L_DicomChannelGetFilterHighFrequency 
   // To get the filter high frequency    
   if(!L_DicomChannelSetFilterHighFrequency(hECGChannel,TRUE, 100.00)) 
      return FAILURE - 1; 
 
   // These are hard-coded values! 
   // Set the channel minimum value  
   if(!L_DicomChannelSetMinimumValue(hECGChannel,TRUE, -386)) 
      return FAILURE - 1; 
 
   // Set the channel maximum value 
   if(!L_DicomChannelSetMaximumValue(hECGChannel,TRUE, 1264)) 
      return FAILURE - 1; 
 
   // Just in case 
   if((!L_DicomChannelGetMinimumValue(hECGChannel,&nMinValue))|| 
      (nMinValue !=-386)) 
      return FAILURE - 1; 
 
   // Just in case 
   if((!L_DicomChannelGetMaximumValue(hECGChannel,&nMaxValue))|| 
      (nMaxValue !=1264)) 
      return FAILURE - 1; 
 
   /* You can also call the following functions to set and get the notch  
      filter frequency and bandwidth 
      L_DicomChannelSetNotchFilterFrequency 
      L_DicomChannelGetNotchFilterFrequency 
      L_DicomChannelSetNotchFilterBandwidth 
      L_DicomChannelGetNotchFilterBandwidth */ 
 
   // Last, but not least, set the channel annotations! 
   return SetChannelAnnotations(hECGChannel); 
} 
  
//Set the channel source and sensitivity 
L_INT SetChannelSourceAndSensitivity(HDICOMWAVEFORMCHANNEL hECGChannel) 
{ 
   pDICOMCONTEXTGROUP pCardiologyUnitsGroup; 
   pDICOMCONTEXTGROUP pECGLeadsGroup; 
   L_UINT16           nRet; 
 
   // Let's use the DICOM context group tables! 
 
   ///////////////////////Channel Source/////////////////////////    
   // Load the ECG Leads table  
   L_DicomLoadContextGroup(CID_3001); 
   pECGLeadsGroup = L_DicomFindContextGroup(CID_3001); 
   if(pECGLeadsGroup) 
   { 
      // 5.6.3-9-1 is Lead I (Einthoven) 
      pDICOMCODEDCONCEPT pCodedConcept = L_DicomFindCodedConcept( pECGLeadsGroup, 
                                                                  TEXT("SCPECG"), 
                                                                  TEXT("5.6.3-9-1")); 
      if(pCodedConcept) 
      { 
         DICOMCODESEQUENCEITEM   DicomSourceSequenceItem; 
         L_UINT16                uRet; 
  
         memset(&DicomSourceSequenceItem , 0 , sizeof(DICOMCODESEQUENCEITEM)); 
         DicomSourceSequenceItem.uStructSize = sizeof(DICOMCODESEQUENCEITEM);          
         
         DicomSourceSequenceItem.pszCodeValue              = pCodedConcept->pszCodeValue                 ; 
         DicomSourceSequenceItem.pszCodingSchemeDesignator = pCodedConcept->pszCodingSchemeDesignator    ; 
         DicomSourceSequenceItem.pszCodingSchemeVersion    = pCodedConcept->pszCodingSchemeVersion       ; 
         DicomSourceSequenceItem.pszCodeMeaning            = pCodedConcept->pszCodeMeaning               ; 
  
         // Set the channel source          
         uRet = L_DicomChannelSetSource(hECGChannel,&DicomSourceSequenceItem); 
         if(uRet!= DICOM_SUCCESS) 
            return uRet; 
 
         // You can call L_DicomChannelGetSource()  
         // to get the channel source 
      } 
      else 
         return DICOM_ERROR_NULL_PTR; 
   } 
   else 
      return DICOM_ERROR_NULL_PTR; 
 
   ///////////////////////Channel Sensitivity//////////////////////// 
   // Cardiology Units of Measurement 
   nRet = L_DicomLoadContextGroup(CID_3082); 
   if (nRet != DICOM_SUCCESS) 
      return nRet; 
 
   pCardiologyUnitsGroup = L_DicomFindContextGroup(CID_3082); 
   if(pCardiologyUnitsGroup) 
   { 
      pDICOMCODEDCONCEPT pCodedConcept = L_DicomFindCodedConcept( pCardiologyUnitsGroup, 
                                                                  TEXT("UCUM"), 
                                                                  TEXT("mV")); 
      if(pCodedConcept) 
      { 
         DICOMCODESEQUENCEITEM   DicomSourceSequenceItem; 
         L_UINT16                uRet; 
  
         memset(&DicomSourceSequenceItem , 0 , sizeof(DICOMCODESEQUENCEITEM)); 
         DicomSourceSequenceItem.uStructSize = sizeof(DICOMCODESEQUENCEITEM); 
         
         DicomSourceSequenceItem.pszCodeValue              = pCodedConcept->pszCodeValue                 ; 
         DicomSourceSequenceItem.pszCodingSchemeDesignator = pCodedConcept->pszCodingSchemeDesignator    ; 
         DicomSourceSequenceItem.pszCodingSchemeVersion    = pCodedConcept->pszCodingSchemeVersion       ; 
         DicomSourceSequenceItem.pszCodeMeaning            = pCodedConcept->pszCodeMeaning               ; 
  
         // Set the channel sensitivity 
         uRet = L_DicomChannelSetSensitivity(   hECGChannel, 
                                                TRUE, 
                                                0.001220, 
                                                &DicomSourceSequenceItem, 
                                                1.0, 
                                                0.0); 
         if(uRet  != DICOM_SUCCESS) 
            return uRet; 
         // You can call L_DicomChannelGetSensitivity()  
         // to get the channel sensitivity 
      } 
      else 
         return DICOM_ERROR_NULL_PTR; 
   } 
   else 
      return DICOM_ERROR_NULL_PTR; 
 
   return DICOM_SUCCESS; 
} 
 
// Add annotations for the channel 
L_INT SetChannelAnnotations(HDICOMWAVEFORMCHANNEL  hECGChannel) 
{ 
   L_UINT32 uIndex = 0; 
   DICOMWAVEFORMANNOTATION ECGWaveformAnnotation; 
   DICOMCODESEQUENCEITEM CodedName; 
   L_DOUBLE dNumericValue = 69.00; 
   DICOMCODESEQUENCEITEM MeasurementUnits; 
   L_INT nRet; 
  
   // Delete any existing channel annotations 
   for(uIndex = 0; uIndex < L_DicomChannelGetAnnotationCount(hECGChannel); uIndex++) 
   { 
      if(L_DicomChannelGetAnnotation(hECGChannel,uIndex)) 
         L_DicomChannelDeleteAnnotation(hECGChannel,uIndex); 
   } 
    
   memset(&ECGWaveformAnnotation,0, sizeof(DICOMWAVEFORMANNOTATION)); 
   ECGWaveformAnnotation.uStructSize = sizeof(DICOMWAVEFORMANNOTATION); 
 
   // Over here we are populating the DICOMCODESEQUENCEITEM structure 
   // directly. What we can also do is fill it with values from 
   // the LDicomContextGroup table which lists all the context 
   // group tables defined by the DICOM standard.  You can look at 
   // the SetChannelSourceAndSensitivity above for an example on 
   // how to do that 
 
   memset(&CodedName,0, sizeof(DICOMCODESEQUENCEITEM)); 
   CodedName.uStructSize               = sizeof(DICOMCODESEQUENCEITEM); 
   CodedName.pszCodeValue              = TEXT("8867-4"); 
   CodedName.pszCodeMeaning            = TEXT("Heart rate"); 
   CodedName.pszCodingSchemeDesignator = TEXT("LN"); 
   CodedName.pszCodingSchemeVersion    = TEXT("19971101"); 
  
   ECGWaveformAnnotation.pCodedName = &CodedName; 
    
   memset(&MeasurementUnits,0, sizeof(DICOMCODESEQUENCEITEM)); 
   MeasurementUnits.uStructSize               = sizeof(DICOMCODESEQUENCEITEM); 
   MeasurementUnits.pszCodeValue              = TEXT("{H.B.}/min"); 
   MeasurementUnits.pszCodeMeaning            = TEXT("Heart beat per minute"); 
   MeasurementUnits.pszCodingSchemeDesignator = TEXT("UCUM"); 
   MeasurementUnits.pszCodingSchemeVersion    = TEXT("1.4"); 
  
   ECGWaveformAnnotation.pMeasurementUnits = &MeasurementUnits;    
   ECGWaveformAnnotation.pNumericValue = &dNumericValue ; 
   ECGWaveformAnnotation.uNumericValueCount = 1; 
 
   nRet = L_DicomChannelAddAnnotation(hECGChannel,&ECGWaveformAnnotation); 
   if(nRet != DICOM_SUCCESS) 
      return nRet; 
  
   return DICOM_SUCCESS; 
} 

Help Version 20.0.2020.4.2
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2020 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS DICOM C API Help