In the recent switch to using DS derived from decimal.Decimal I had several files that stopped being processed properly.
The resulting OverflowError was:
DS value representation must be <= 16 characters by DICOM standard. Initialize with a smaller string, or set config.enforce_valid_values to False to override, or use Decimal.quantize() and initialize with a Decimal instance
After looking at the DICOM data directly, the value in question IS actually a valid value: '-9.81338674e-006'. This value is <= 16 bytes; however, when converted to a decimal.Decimal object, the resulting string becomes: '-0.00000981338674' which is now 17 bytes, and thus the DS construction fails.
This is due to the fact that Decimal really doesn't keep track of how long the string output is and this particular number fails because Decimal.str() expands anything with fewer than 6 digits to the left of the decimal sign no matter how the decimal was initialized.
As a workaround, I check the length of the input to DS if it's a string and if it's a valid length, then I set a flag that enables us to create a DS regardless of the Decimal.str() length. Additionally, I provided an overloaded str method for DS that displays the original string if it was provided and Decimal.str() otherwise.
Additionally, if the user provides the following string:
'-0.000000981338674' # Which is not valid by itself (length = 18)
Then a DS can be created because the Decimal.str() result is:
'-9.81338674E-7' # Which is now valid
However, invalid strings that can't be represented by Decimal.decimal in less than 16 characters are considered invalid.
From Suever@gmail.com on May 21, 2012 13:58:22
In the recent switch to using DS derived from decimal.Decimal I had several files that stopped being processed properly.
The resulting OverflowError was: DS value representation must be <= 16 characters by DICOM standard. Initialize with a smaller string, or set config.enforce_valid_values to False to override, or use Decimal.quantize() and initialize with a Decimal instance
After looking at the DICOM data directly, the value in question IS actually a valid value: '-9.81338674e-006'. This value is <= 16 bytes; however, when converted to a decimal.Decimal object, the resulting string becomes: '-0.00000981338674' which is now 17 bytes, and thus the DS construction fails.
This is due to the fact that Decimal really doesn't keep track of how long the string output is and this particular number fails because Decimal.str() expands anything with fewer than 6 digits to the left of the decimal sign no matter how the decimal was initialized.
As a workaround, I check the length of the input to DS if it's a string and if it's a valid length, then I set a flag that enables us to create a DS regardless of the Decimal.str() length. Additionally, I provided an overloaded str method for DS that displays the original string if it was provided and Decimal.str() otherwise.
Additionally, if the user provides the following string: '-0.000000981338674' # Which is not valid by itself (length = 18)
Then a DS can be created because the Decimal.str() result is: '-9.81338674E-7' # Which is now valid
However, invalid strings that can't be represented by Decimal.decimal in less than 16 characters are considered invalid.
I'm not sure if this is the best workaround but I have the patch committed to my clone if you wish to take a look. I have also added some tests to ensure proper functionality. https://code.google.com/r/suever-pydicom-dev/source/detail?r=f9fde6290ec8408d1a25e522036fac86055814f3 -Suever
Original issue: http://code.google.com/p/pydicom/issues/detail?id=116