124 lines
4.1 KiB
Python
Executable File
124 lines
4.1 KiB
Python
Executable File
# Copyright 2008-2021 pydicom authors. See LICENSE file for details.
|
|
"""Code to fix non-standard dicom issues in files
|
|
"""
|
|
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
from pydicom import config
|
|
from pydicom import datadict
|
|
from pydicom import values
|
|
from pydicom.valuerep import VR
|
|
|
|
if TYPE_CHECKING: # pragma: no cover
|
|
from pydicom.dataelem import RawDataElement
|
|
|
|
|
|
def fix_separator_callback(
|
|
raw_elem: "RawDataElement", **kwargs: Any
|
|
) -> "RawDataElement":
|
|
"""Used by fix_separator as the callback function from read_dataset"""
|
|
return_val = raw_elem
|
|
try_replace = False
|
|
# If elements are implicit VR, attempt to determine the VR
|
|
if raw_elem.VR is None:
|
|
try:
|
|
vr = datadict.dictionary_VR(raw_elem.tag)
|
|
# Not in the dictionary, process if flag says to do so
|
|
except KeyError:
|
|
try_replace = kwargs["process_unknown_VRs"]
|
|
else:
|
|
try_replace = vr in kwargs["for_VRs"]
|
|
else:
|
|
try_replace = raw_elem.VR in kwargs["for_VRs"]
|
|
|
|
if try_replace:
|
|
# Note value has not been decoded yet when this function called,
|
|
# so need to replace backslash as bytes
|
|
new_value = None
|
|
if raw_elem.value is not None:
|
|
if kwargs["invalid_separator"] == b" ":
|
|
stripped_val = raw_elem.value.strip()
|
|
strip_count = len(raw_elem.value) - len(stripped_val)
|
|
new_value = (
|
|
stripped_val.replace(kwargs["invalid_separator"], b"\\")
|
|
+ b" " * strip_count
|
|
)
|
|
else:
|
|
new_value = raw_elem.value.replace(kwargs["invalid_separator"], b"\\")
|
|
return_val = raw_elem._replace(value=new_value)
|
|
|
|
return return_val
|
|
|
|
|
|
def fix_separator(
|
|
invalid_separator: bytes,
|
|
for_VRs: tuple[str, ...] = ("DS", "IS"),
|
|
process_unknown_VRs: bool = True,
|
|
) -> None:
|
|
"""A callback function to fix RawDataElement values using
|
|
some other separator than the dicom standard backslash character
|
|
|
|
Parameters
|
|
----------
|
|
invalid_separator : bytes
|
|
A single byte to replace with dicom backslash, in raw data element
|
|
values before they have been decoded or processed by pydicom
|
|
for_VRs : list, optional
|
|
A list of VRs for which the replacement will be done.
|
|
If the VR is unknown (for example, if a private element),
|
|
then process_unknown_VR is used to determine whether to replace or not.
|
|
process_unknown_VRs: bool, optional
|
|
If True (default) then attempt the fix even if the VR is not known.
|
|
|
|
Returns
|
|
-------
|
|
No return value. However, the callback function will return either
|
|
the original RawDataElement instance, or a fixed one.
|
|
"""
|
|
config.data_element_callback = fix_separator_callback
|
|
config.data_element_callback_kwargs = {
|
|
"invalid_separator": invalid_separator,
|
|
"for_VRs": for_VRs,
|
|
"process_unknown_VRs": process_unknown_VRs,
|
|
}
|
|
|
|
|
|
def fix_mismatch_callback(
|
|
raw_elem: "RawDataElement", **kwargs: Any
|
|
) -> "RawDataElement":
|
|
if raw_elem.VR is None:
|
|
return raw_elem
|
|
|
|
try:
|
|
values.convert_value(raw_elem.VR, raw_elem)
|
|
except ValueError:
|
|
for vr in kwargs["with_VRs"]:
|
|
try:
|
|
values.convert_value(vr, raw_elem)
|
|
except ValueError:
|
|
pass
|
|
else:
|
|
raw_elem = raw_elem._replace(VR=vr)
|
|
return raw_elem
|
|
|
|
|
|
def fix_mismatch(with_VRs: tuple[str, ...] = (VR.PN, VR.DS, VR.IS)) -> None:
|
|
"""A callback function to check that RawDataElements are translatable
|
|
with their provided VRs. If not, re-attempt translation using
|
|
some other translators.
|
|
|
|
Parameters
|
|
----------
|
|
with_VRs : Tuple[str]
|
|
A tuple of VR strings to attempt if the raw data element value cannot
|
|
be translated with the raw data element's VR. Default
|
|
``('PN', 'DS', 'IS')``.
|
|
|
|
Returns
|
|
-------
|
|
No return value. The callback function will return either
|
|
the original RawDataElement instance, or one with a fixed VR.
|
|
"""
|
|
config.data_element_callback = fix_mismatch_callback
|
|
config.data_element_callback_kwargs = {"with_VRs": with_VRs}
|