dicom icon indicating copy to clipboard operation
dicom copied to clipboard

Consider migrating DataSet to use map of tag -> Element

Open suyashkumar opened this issue 6 years ago • 4 comments

suyashkumar avatar Jul 15 '19 05:07 suyashkumar

Does the order of the tags in the original dicom matter?

suyashkumar avatar Jul 15 '19 05:07 suyashkumar

I believe the order of tags does matter, at least according to dcmdump from dcmtk This code snippet works

        newVals := []*element.Element{
                element.MustNewElement(dicomtag.TransferSyntaxUID, dicomuid.ExplicitVRLittleEndian),
                element.MustNewElement(dicomtag.MediaStorageSOPClassUID, "1.2.840.10008.5.1.4.31"),
                element.MustNewElement(dicomtag.MediaStorageSOPInstanceUID, "1.2.276.0.7230010.3.1.4.2831176407.11154.1448031138.805061"),
                element.MustNewElement(dicomtag.SpecificCharacterSet, "ISO_IR 192"),
                element.MustNewElement(dicomtag.AccessionNumber, "00000"),
                element.MustNewElement(dicomtag.PatientName, fmt.Sprintf("%s^%s", c.LName, p.Name.String)),
                element.MustNewElement(dicomtag.PatientID, strconv.Itoa(wl.PID)),
                element.MustNewElement(dicomtag.IssuerOfPatientID, wl.IDPrefix),
                element.MustNewElement(dicomtag.PatientBirthDate, p.DOB.Time.Format("2006-01-02")),
                element.MustNewElement(dicomtag.PatientSex, p.Sex.String),
                element.MustNewElement(dicomtag.MedicalAlerts, p.Alert.String),
                element.MustNewElement(dicomtag.RequestingPhysician, "VETNAME"),
                element.MustNewElement(dicomtag.ScheduledProcedureStepSequence,
                        element.MustNewElement(dicomtag.Item,
                                element.MustNewElement(dicomtag.Modality, "MR"),
                                element.MustNewElement(dicomtag.RequestedProcedureDescription, wl.Procedure),
                                element.MustNewElement(dicomtag.ScheduledProcedureStepStartDate, wl.ScheduledProcedureStartDate),
                        )),
        }

But if I move the start date above the description as follows:

        newVals := []*element.Element{
                element.MustNewElement(dicomtag.TransferSyntaxUID, dicomuid.ExplicitVRLittleEndian),
                element.MustNewElement(dicomtag.MediaStorageSOPClassUID, "1.2.840.10008.5.1.4.31"),
                element.MustNewElement(dicomtag.MediaStorageSOPInstanceUID, "1.2.276.0.7230010.3.1.4.2831176407.11154.1448031138.805061"),
                element.MustNewElement(dicomtag.SpecificCharacterSet, "ISO_IR 192"),
                element.MustNewElement(dicomtag.AccessionNumber, "00000"),
                element.MustNewElement(dicomtag.PatientName, fmt.Sprintf("%s^%s", c.LName, p.Name.String)),
                element.MustNewElement(dicomtag.PatientID, strconv.Itoa(wl.PID)),
                element.MustNewElement(dicomtag.IssuerOfPatientID, wl.IDPrefix),
                element.MustNewElement(dicomtag.PatientBirthDate, p.DOB.Time.Format("2006-01-02")),
                element.MustNewElement(dicomtag.PatientSex, p.Sex.String),
                element.MustNewElement(dicomtag.MedicalAlerts, p.Alert.String),
                element.MustNewElement(dicomtag.RequestingPhysician, "VETNAME"),
                element.MustNewElement(dicomtag.ScheduledProcedureStepSequence,
                        element.MustNewElement(dicomtag.Item,
                                element.MustNewElement(dicomtag.Modality, "MR"),
                                element.MustNewElement(dicomtag.ScheduledProcedureStepStartDate, wl.ScheduledProcedureStartDate),
                                element.MustNewElement(dicomtag.RequestedProcedureDescription, wl.Procedure),
                        )),
        }

Then dcmdump gives me W: DcmItem: Dataset not in ascending tag order, at element (0032,1060)

I have not tested this with my actual x-ray software yet but orthanc gives me a similar error in the console when I test with findscu

jacobalberty avatar Sep 09 '19 20:09 jacobalberty

@jacobalberty thank you for the information, it's definitely useful to know that when writing the tags they should be in order! It may be useful to still represent the DataSet as a map of tag -> element (or pointer to element) so that it's easy to fetch elements by tag in large DataSets, without too much memory overhead. Thoughts?

suyashkumar avatar Sep 15 '19 03:09 suyashkumar

Migrating DataSet to use map also will make it easier to convert a DataSet to DICOM JSON model and the tag key will be sorted.

https://golang.org/pkg/encoding/json/ `Map values encode as JSON objects. The map's key type must either be a string, an integer type, or implement encoding.TextMarshaler. The map keys are sorted and used as JSON object keys by applying the following rules, subject to the UTF-8 coercion described for string values above:

  • keys of any string type are used directly
  • encoding.TextMarshalers are marshaled
  • integer keys are converted to strings`

When writing the Dataset to a DCM file, sort the keys first, and range map through the ordered keys, then write each element to the file.

luxsa avatar Jan 26 '21 11:01 luxsa