2

There is a tag which is of type 2 ("required, empty if unknown"), with value representation Integer String which I would like to leave empty. I have tried creating the attribute like so:

var attribute = new DicomIntegerString(DicomTag.SeriesNumber, string.Empty);

The storing of the file works. When I read the file again, the result of the following call returns null:

var result = dicomDataset.GetString(DicomTag.SeriesNumber); // <-- this is null

How can I set the element to be correctly "zero-length", or "empty, if unknown"?

Thanks.

MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46
Ynv
  • 1,824
  • 3
  • 20
  • 29
  • 1
    How do you add the attribute - using `AddOrUpdate`? Have you checked that the tag is written with a DICOM tag viewer? Also: which version of fo-dicom yo are using? – MrBean Bremen May 25 '22 at 18:37
  • Thank you for your reply. I only use the `DicomDataset` constructors. I have checked now with `dcmdump`, and the tag is actually being written, with a "no value available." comment. Could it be that fo-dicoms methods for retrieving values, cannot differentiate between "no value found for that tag", and "tag found, but with empty value"? I'm using version `5.0.2`. – Ynv May 26 '22 at 05:38
  • Yes, I think so, have to check. As far as I remember, an exception would have been raised if the tag was not found. Returning `null` or an empty string for an empty tag is a design decision, as there is no semantic difference between a non existing and an empty value (I remember a similar discussion in pydicom) and should be handled the same way by the client - though I agree that returning an empty string would be more convenient for string tags. – MrBean Bremen May 26 '22 at 06:42
  • 1
    Confirmed that this is the behavior. As I wrote, in DICOM there is really no difference between a tag with no value or a tag with an empty value (at least for string tags), so it is up to the library to decide what to return in this case. As a user, you can just handle `null` values as empty strings for string tags. – MrBean Bremen May 26 '22 at 10:11

1 Answers1

2

As already mentioned in the comments, the code to set an empty string in the dataset is correct:

dataset.AddOrUpdate(new DicomIntegerString(DicomTag.SeriesNumber, string.Empty));

Note that you could also write a null value:

dataset.AddOrUpdate(new DicomIntegerString(DicomTag.SeriesNumber, (string)null));

Writing out the dataset will create an empty tag for SeriesNumber in exactly the same way in both cases, as both cases are equivalent in DICOM.

The code to read the tag back is also correct, and the fact that it returns null is due to this equivalence, which creates an ambiguity in the interpretation of an empty string tag in DICOM. As the number of values in a DICOM string tag is defined only by the string itself (and the number of backslashes it contains), there is no difference between a tag with no values (which usually is represented by a null value), and a tag with an empty string (which would be represented by a "" value). For consistence with other tags it makes sense to return null for a tag with VM 0 - for non-string VRs there is no ambiguity here, as the length of a value is defined. For string values it could also make sense to return an empty string instead - both approaches have pros and cons, so in the end it is a design decision of the library creators.

In fo-dicom, it is probably best to handle both cases (e.g. using something like string.IsNullOrEmpty). If you read the value from a file dataset, you always get null, but if you are writing an empty string to a tag in a dataset (first version shown above) and read it back, you will get the same empty string back.

As an aside: in pydicom (the common Python DICOM library) there was a discussion about this same design decision, and in the end a configuration entry was added that defines the behavior (e.g. return None or an empty string for such values).

MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46