1

I am trying to convert digitized ecg data to dicom file. My code looks like as below

        DateTime today = DateTime.Today;

        DicomFile dicomFile = new DicomFile();
        dicomFile.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;

        dicomFile.DataSet[DicomTags.StudyDate].SetStringValue(today.ToString("yyyyMMdd"));
        dicomFile.DataSet[DicomTags.StudyTime].SetStringValue(today.ToString("HHmmss"));

        dicomFile.DataSet[DicomTags.PatientsBirthName].SetStringValue(patientName);
        dicomFile.DataSet[DicomTags.PatientId].SetStringValue(patientId);

        dicomFile.DataSet[DicomTags.StudyInstanceUid].SetStringValue(studyId);

        dicomFile.DataSet[DicomTags.SeriesInstanceUid].SetStringValue(seriesId);
        dicomFile.DataSet[DicomTags.Modality].SetStringValue(modality);
        dicomFile.DataSet[DicomTags.ConversionType].SetStringValue(conversionType);//Drawing

        string sopInstanceUid = DicomUid.GenerateUid().UID; // Should be unique for each image
        this.pacsAccessionNumber = (Functions.GetRandomString() + Functions.GetRandomString()).Substring(0, 16);

        dicomFile.DataSet[DicomTags.InstanceNumber].SetInt32(0, instanceNumber);//Series Instance Number
        dicomFile.DataSet[DicomTags.SopClassUid].SetStringValue(SopClass.Sop12LeadEcgWaveformStorage.Uid);
        dicomFile.DataSet[DicomTags.SopInstanceUid].SetStringValue(sopInstanceUid);
        dicomFile.DataSet[DicomTags.AccessionNumber].SetStringValue(this.pacsAccessionNumber);
        dicomFile.MediaStorageSopClassUid = SopClass.Sop12LeadEcgWaveformStorage.Uid;
        dicomFile.MediaStorageSopInstanceUid = sopInstanceUid;

        dicomFile.DataSet[DicomTags.Manufacturer].SetStringValue("MITS");// Manufacturer Name

        DicomSequenceItem waveFormSeq = new DicomSequenceItem();
        waveFormSeq[DicomTags.WaveformOriginality].SetStringValue("DERIVED");// Other option is ORIGINAL
        waveFormSeq[DicomTags.WaveformChannelNumber].SetUInt32(0, 1);//must be between 1-13
        waveFormSeq[DicomTags.NumberOfWaveformSamples].Values = samplingCount;//NumberOfWaveformSamples -- max value is 16384
        waveFormSeq[DicomTags.SamplingFrequency].SetFloat32(0, 1000);//frequency(must be dynamic) -- must be dynamic must be between 200-100
        waveFormSeq[DicomTags.WaveformSampleInterpretation].SetStringValue("SS");//signed
        waveFormSeq[DicomTags.WaveformBitsAllocated].SetInt32(0, 16);//16 bit
        waveFormSeq[DicomTags.WaveformData].Values = voltageValues;

        DicomSequenceItem channelSeq = new DicomSequenceItem();
        channelSeq[DicomTags.ChannelSensitivityCorrectionFactor].SetUInt32(0, 1);
        channelSeq[DicomTags.ChannelBaseline].SetUInt32(0, 0);
        channelSeq[DicomTags.ChannelTimeSkew].SetUInt32(0, 0);

        DicomSequenceItem channelSourceSeq = new DicomSequenceItem();
        channelSourceSeq[DicomTags.CodeValue].SetStringValue("5.6.3-9-1");
        channelSourceSeq[DicomTags.CodingSchemeDesignator].SetStringValue("SCPECG");
        channelSourceSeq[DicomTags.CodingSchemeVersion].SetStringValue("1.3");

        channelSeq[DicomTags.ChannelSourceSequence].AddSequenceItem(channelSourceSeq);

        DicomSequenceItem channelSensUnitSeq = new DicomSequenceItem();
        channelSensUnitSeq[DicomTags.CodeValue].SetStringValue("uV");
        channelSensUnitSeq[DicomTags.CodingSchemeDesignator].SetStringValue("UCUM");
        channelSensUnitSeq[DicomTags.CodingSchemeVersion].SetStringValue("1.4");

        channelSeq[DicomTags.ChannelSensitivityUnitsSequence].AddSequenceItem(channelSensUnitSeq);

        waveFormSeq[DicomTags.ChannelSequence].AddSequenceItem(channelSeq);

        dicomFile.DataSet[DicomTags.WaveformSequence].AddSequenceItem(waveFormSeq);

        SendFile(dicomFile);

But in pacs server, I could not open the dcm file.

Is there sth I am missing?

The link of the dicom file http://www.ikincidoktor.com/NonDicomRepository/8/testecg.dcm

Ozan Deniz
  • 1,087
  • 7
  • 22
  • 1
    Does the PACS system actually support the waveform sop classes? Are you able to open the resultant file using Clunie's pixelmed viewer: http://www.pixelmed.com/index.html#PixelMedJavaDICOMToolkit – Brett Okken Mar 07 '15 at 13:30
  • I am using EcgViewer Application to check the data. It says that "failed to get signal". But i put the digitized ECG in the right tag. Where can be the error? @BrettOkken – Ozan Deniz Mar 09 '15 at 13:32
  • This is the file: http://www.ikincidoktor.com/NonDicomRepository/8/testecg.dcm – Ozan Deniz Mar 09 '15 at 14:23

1 Answers1

2

There are 9 different IOD classes defined in the DICOM standard related to waveform and 2 of them are for audio. Many of the attributes are conditional to the waveform data samples you are dealing with and it is not possible to simply list the required elements. So here is a suggestion to help you solve your issue.

Please start with DICOM Standard PS 3.3 (located here) annex A.34 and pick the appropriate IOD that you want to use. In each of the IOD class definition, you will see a table that lists the required modules for the IOD with reference to location of module definition (C.?.?.?). It will also, specify any IOD specific requirement in this section.

As for example, 12-Lead Electrocardiogram IOD definition is located in Annex A.34.3 and table A.34.3-1 lists following module as mandatory modules for this IOD:

  • Patient ( C.7.1.1)
  • General Study ( C.7.2.1)
  • General Series (C.7.3.1)
  • General Equipment (C.7.5.1)
  • Waveform Identification (C.10.8)
  • Waveform (C.10.9)
  • Acquisition Context (C.7.6.14)
  • Waveform Annotation (C.10.10 (conditional and it is required if annotation is present))

Next you want to look at each required module under Annex C. Here you will find a table with a list of DICOM Elements that makes up the module. Type column specifies whether the element is required, optional or conditional. The description of different data element type is located in PS 3.5 section 7.4. In short, Type 1 is required and must not be empty. Type 2 is required and can be empty and type 3 is optional. Type 1C or Type 2C are conditional and must be present if it meets the condition.

Data samples encoding rule for Waveform Data (5400,1010) element is defined in section C.10.9.1.7.

If you are working with only one channel, you may want to look at General Electrocardiogram IOD (A.34.4).

I hope this helps.

LEADTOOLS Support
  • 2,755
  • 1
  • 12
  • 12
  • You are right. I try to add digitized ecg data not pixelated one. I fixed it but what are the mandatory tags for ecg dicom file and what is the raw data format for ecg? I edited the question can you check again the code snippet? – Ozan Deniz Mar 04 '15 at 08:46
  • I also have voltage values in minivolt and I have values just for one channel. – Ozan Deniz Mar 04 '15 at 09:35
  • I think the problem is about the voltage values. I have one channel and values are like 1.4545 1.4354 1.4928 1.4737 1.4545 1.4928 1.4737 1.4545 1.4354 I have multiplied them 1000 and convert to ushort than byte array.(2 bytes -- 16 bit for one voltage value). According to docs It seems ok but there must be sth I am missing. – Ozan Deniz Mar 09 '15 at 14:16