Пример #1
0
 def test_read_bad_value_in_VR_enforce_valid_value(self):
     pydicom.config.enforce_valid_values = True
     # found a conversion
     assert '1A' == convert_value('SH', self.tag)
     # invalid literal for base 10
     with pytest.raises(ValueError):
         convert_value('IS', self.tag)
 def test_read_bad_value_in_VR_enforce_valid_value(self,
                                                   enforce_valid_values):
     # found a conversion
     assert "1A" == convert_value("SH", self.tag)
     # invalid literal for base 10
     with pytest.raises(ValueError):
         convert_value("IS", self.tag)
    def test_read_bad_value_in_VR_default(self, allow_invalid_values):
        # found a conversion
        assert "1A" == convert_value("SH", self.tag)
        # converted with fallback vr "SH"
        assert "1A" == convert_value("IS", self.tag)

        pydicom.values.convert_retry_VR_order = ["FL", "UL"]
        # no fallback VR succeeded, returned original value untranslated
        assert b"1A" == convert_value("IS", self.tag)
Пример #4
0
    def test_read_bad_value_in_VR_default(self):
        # found a conversion
        assert '1A' == convert_value('SH', self.tag)
        # converted with fallback vr "SH"
        assert '1A' == convert_value('IS', self.tag)

        pydicom.values.convert_retry_VR_order = ['FL', 'UL']
        # no fallback VR succeeded, returned original value untranslated
        assert b'1A' == convert_value('IS', self.tag)
Пример #5
0
    def testReadBadValueInVRDefault(self):
        # found a conversion
        self.assertEqual('1A', convert_value('SH', self.tag))
        # converted with fallback vr "SH"
        self.assertEqual('1A', convert_value('IS', self.tag))

        pydicom.values.convert_retry_VR_order = ['FL', 'UL']
        # no fallback VR succeeded, returned original value untranslated
        self.assertEqual(b'1A', convert_value('IS', self.tag))
Пример #6
0
    def test_convert_value_raises(self):
        """Test convert_value raises exception if unsupported VR"""
        converter_func = converters['PN']
        del converters['PN']

        with pytest.raises(NotImplementedError,
                           match="Unknown Value Representation 'PN'"):
            convert_value('PN', None)

        # Fix converters
        converters['PN'] = converter_func
        assert 'PN' in converters
Пример #7
0
def fix_mismatch_callback(raw_elem, **kwargs):
    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 test_convert_value_raises(self):
        """Test convert_value raises exception if unsupported VR"""
        converter_func = converters['PN']
        del converters['PN']

        with pytest.raises(NotImplementedError,
                           match="Unknown Value Representation 'PN'"):
            convert_value('PN', None)

        # Fix converters
        converters['PN'] = converter_func
        assert 'PN' in converters
Пример #9
0
def fix_mismatch_callback(raw_elem, **kwargs):
    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
Пример #10
0
def fix_mismatch_callback(raw_elem, **kwargs):
    try:
        values.convert_value(raw_elem.VR, raw_elem)
    except TypeError:
        for vr in kwargs['with_VRs']:
            try:
                values.convert_value(vr, raw_elem)
            except TypeError:
                pass
            else:
                raw_elem = raw_elem._replace(VR=vr)
                break  # i want to exit immediately after change is applied 
    return raw_elem
Пример #11
0
    def testEmptyItem(self):
        """Read sequence with a single empty item..............................."""
        # This is fix for issue 27
        hexstr = (
            "08 00 32 10"    # (0008, 1032) SQ "Procedure Code Sequence"
            " 08 00 00 00"    # length 8
            " fe ff 00 e0"    # (fffe, e000) Item Tag
            " 00 00 00 00"    # length = 0
        ) + (             # --------------- end of Sequence
            " 08 00 3e 10"    # (0008, 103e) LO "Series Description"  nopep8
            " 0c 00 00 00"    # length     nopep8
            " 52 20 41 44 44 20 56 49 45 57 53 20"  # value     nopep8
        )
        # "\x08\x00\x32\x10\x08\x00\x00\x00\xfe\xff\x00\xe0\x00\x00\x00\x00" # from issue 27, procedure code sequence (0008,1032)
        # hexstr += "\x08\x00\x3e\x10\x0c\x00\x00\x00\x52\x20\x41\x44\x44\x20\x56\x49\x45\x57\x53\x20" # data element following

        fp = BytesIO(hex2bytes(hexstr))
        gen = data_element_generator(fp, is_implicit_VR=True, is_little_endian=True)
        raw_seq = next(gen)
        seq = convert_value("SQ", raw_seq)

        self.assertTrue(isinstance(seq, Sequence), "Did not get Sequence, got type {0}".format(str(type(seq))))
        self.assertTrue(len(seq) == 1, "Expected Sequence with single (empty) item, got {0:d} item(s)".format(len(seq)))
        self.assertTrue(len(seq[0]) == 0, "Expected the sequence item (dataset) to be empty")
        elem2 = next(gen)
        self.assertEqual(elem2.tag, 0x0008103e, "Expected a data element after empty sequence item")
Пример #12
0
    def testEmptyItem(self):
        """Read sequence with a single empty item..."""
        # This is fix for issue 27
        hexstr = (
            "08 00 32 10"  # (0008, 1032) SQ "Procedure Code Sequence"
            " 08 00 00 00"  # length 8
            " fe ff 00 e0"  # (fffe, e000) Item Tag
            " 00 00 00 00"  # length = 0
        ) + (  # --------------- end of Sequence
            " 08 00 3e 10"  # (0008, 103e) LO "Series Description"  nopep8
            " 0c 00 00 00"  # length     nopep8
            " 52 20 41 44 44 20 56 49 45 57 53 20"  # value     nopep8
        )
        # "\x08\x00\x32\x10\x08\x00\x00\x00\xfe\xff\x00\xe0\x00\x00\x00\x00"
        # from issue 27, procedure code sequence (0008,1032)
        # hexstr += "\x08\x00\x3e\x10\x0c\x00\x00\x00\x52\x20
        # \x41\x44\x44\x20\x56\x49\x45\x57\x53\x20"
        # data element following

        fp = BytesIO(hex2bytes(hexstr))
        gen = data_element_generator(fp,
                                     is_implicit_VR=True,
                                     is_little_endian=True)
        raw_seq = next(gen)
        seq = convert_value("SQ", raw_seq)
        assert isinstance(seq, Sequence)
        assert 1 == len(seq)
        assert 0 == len(seq[0])
        elem2 = next(gen)
        assert 0x0008103e == elem2.tag
Пример #13
0
def DataElement_from_raw(raw_data_element, encoding=None):
    """Return a DataElement from a RawDataElement"""
    from pydicom.values import convert_value  # XXX buried here to avoid circular import filereader->Dataset->convert_value->filereader (for SQ parsing)
    raw = raw_data_element

    # If user has hooked into conversion of raw values, call his/her routine
    if config.data_element_callback:
        raw = config.data_element_callback(
            raw_data_element, **config.data_element_callback_kwargs)
    VR = raw.VR
    if VR is None:  # Can be if was implicit VR
        try:
            VR = dictionaryVR(raw.tag)
        except KeyError:
            if raw.tag.is_private:
                VR = 'OB'  # just read the bytes, no way to know what they mean
            elif raw.tag.element == 0:  # group length tag implied in versions < 3.0
                VR = 'UL'
            else:
                raise KeyError(
                    "Unknown DICOM tag {0:s} - can't look up VR".format(
                        str(raw.tag)))
    try:
        value = convert_value(VR, raw, encoding)
    except NotImplementedError as e:
        raise NotImplementedError("{0:s} in tag {1!r}".format(str(e), raw.tag))
    return DataElement(raw.tag,
                       VR,
                       value,
                       raw.value_tell,
                       raw.length == 0xFFFFFFFF,
                       already_converted=True)
Пример #14
0
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
Пример #15
0
def DataElement_from_raw(raw_data_element, encoding=None):
    """Return a DataElement from a RawDataElement"""
    from pydicom.values import convert_value  # XXX buried here to avoid circular import filereader->Dataset->convert_value->filereader (for SQ parsing)
    raw = raw_data_element

    # If user has hooked into conversion of raw values, call his/her routine
    if config.data_element_callback:
        raw = config.data_element_callback(raw_data_element,
                                           **config.data_element_callback_kwargs)
    VR = raw.VR
    if VR is None:  # Can be if was implicit VR
        try:
            VR = dictionaryVR(raw.tag)
        except KeyError:
            if raw.tag.is_private:
                VR = 'OB'  # just read the bytes, no way to know what they mean
            elif raw.tag.element == 0:  # group length tag implied in versions < 3.0
                VR = 'UL'
            else:
                raise KeyError("Unknown DICOM tag {0:s} - can't look up VR".format(str(raw.tag)))
    try:
        value = convert_value(VR, raw, encoding)
    except NotImplementedError as e:
        raise NotImplementedError("{0:s} in tag {1!r}".format(str(e), raw.tag))
    return DataElement(raw.tag, VR, value, raw.value_tell,
                       raw.length == 0xFFFFFFFF, already_converted=True)
Пример #16
0
def DataElement_from_raw(raw_data_element, encoding=None):
    """Return a :class:`DataElement` created from `raw_data_element`.

    Parameters
    ----------
    raw_data_element : RawDataElement namedtuple
        The raw data to convert to a :class:`DataElement`.
    encoding : str, optional
        The character encoding of the raw data.

    Returns
    -------
    DataElement
    """
    # XXX buried here to avoid circular import
    # filereader->Dataset->convert_value->filereader
    # (for SQ parsing)

    if in_py2:
        encoding = encoding or default_encoding
    from pydicom.values import convert_value
    raw = raw_data_element

    # If user has hooked into conversion of raw values, call his/her routine
    if config.data_element_callback:
        data_elem = config.data_element_callback
        raw = data_elem(raw_data_element,
                        **config.data_element_callback_kwargs)
    VR = raw.VR
    if VR is None:  # Can be if was implicit VR
        try:
            VR = dictionary_VR(raw.tag)
        except KeyError:
            # just read the bytes, no way to know what they mean
            if raw.tag.is_private:
                # for VR for private tags see PS3.5, 6.2.2
                if raw.tag.is_private_creator:
                    VR = 'LO'
                else:
                    VR = 'UN'

            # group length tag implied in versions < 3.0
            elif raw.tag.element == 0:
                VR = 'UL'
            else:
                msg = "Unknown DICOM tag {0:s}".format(str(raw.tag))
                msg += " can't look up VR"
                raise KeyError(msg)
    try:
        value = convert_value(VR, raw, encoding)
    except NotImplementedError as e:
        raise NotImplementedError("{0:s} in tag {1!r}".format(str(e), raw.tag))

    if raw.tag in _LUT_DESCRIPTOR_TAGS and value[0] < 0:
        # We only fix the first value as the third value is 8 or 16
        value[0] += 65536

    return DataElement(raw.tag, VR, value, raw.value_tell,
                       raw.length == 0xFFFFFFFF, already_converted=True)
Пример #17
0
def fix_mismatch_callback(raw_elem, **kwargs):
    try:
        if raw_elem.VR:
            values.convert_value(raw_elem.VR, raw_elem)
    except TypeError as err:
        logging.error(err)
    except BaseException as err:
        for vr in kwargs['with_VRs']:
            try:
                values.convert_value(vr, raw_elem)
            except ValueError:
                pass
            except TypeError:
                continue
            else:
                raw_elem = raw_elem._replace(VR=vr)
    return raw_elem
Пример #18
0
def DataElement_from_raw(raw_data_element, encoding=None):
    """Return a DataElement created from the data in `raw_data_element`.

    Parameters
    ----------
    raw_data_element : RawDataElement namedtuple
        The raw data to convert to a DataElement
    encoding : str
        The encoding of the raw data

    Returns
    -------
    pydicom.dataelem.DataElement
    """
    # XXX buried here to avoid circular import
    # filereader->Dataset->convert_value->filereader
    # (for SQ parsing)

    if in_py2:
        encoding = encoding or default_encoding
    from pydicom.values import convert_value
    raw = raw_data_element

    # If user has hooked into conversion of raw values, call his/her routine
    if config.data_element_callback:
        data_elem = config.data_element_callback
        raw = data_elem(raw_data_element,
                        **config.data_element_callback_kwargs)
    VR = raw.VR
    if VR is None:  # Can be if was implicit VR
        try:
            VR = dictionary_VR(raw.tag)
        except KeyError:

            # just read the bytes, no way to know what they mean
            if raw.tag.is_private:
                VR = 'OB'

            # group length tag implied in versions < 3.0
            elif raw.tag.element == 0:
                VR = 'UL'
            else:
                msg = "Unknown DICOM tag {0:s}".format(str(raw.tag))
                msg += " can't look up VR"
                raise KeyError(msg)
    try:
        value = convert_value(VR, raw, encoding)
    except NotImplementedError as e:
        raise NotImplementedError("{0:s} in tag {1!r}".format(str(e), raw.tag))
    return DataElement(raw.tag,
                       VR,
                       value,
                       raw.value_tell,
                       raw.length == 0xFFFFFFFF,
                       already_converted=True)
Пример #19
0
def DataElement_from_raw(raw_data_element, encoding=None):
    """Return a DataElement created from the data in `raw_data_element`.

    Parameters
    ----------
    raw_data_element : RawDataElement namedtuple
        The raw data to convert to a DataElement
    encoding : str
        The encoding of the raw data

    Returns
    -------
    pydicom.dataelem.DataElement
    """
    # XXX buried here to avoid circular import
    # filereader->Dataset->convert_value->filereader
    # (for SQ parsing)

    if in_py2:
        encoding = encoding or default_encoding
    from pydicom.values import convert_value
    raw = raw_data_element

    # If user has hooked into conversion of raw values, call his/her routine
    if config.data_element_callback:
        data_elem = config.data_element_callback
        raw = data_elem(raw_data_element,
                        **config.data_element_callback_kwargs)
    VR = raw.VR
    if VR is None:  # Can be if was implicit VR
        try:
            VR = dictionary_VR(raw.tag)
        except KeyError:
            # just read the bytes, no way to know what they mean
            if raw.tag.is_private:
                # for VR for private tags see PS3.5, 6.2.2
                if raw.tag.is_private_creator:
                    VR = 'LO'
                else:
                    VR = 'UN'

            # group length tag implied in versions < 3.0
            elif raw.tag.element == 0:
                VR = 'UL'
            else:
                msg = "Unknown DICOM tag {0:s}".format(str(raw.tag))
                msg += " can't look up VR"
                raise KeyError(msg)
    try:
        value = convert_value(VR, raw, encoding)
    except NotImplementedError as e:
        raise NotImplementedError("{0:s} in tag {1!r}".format(str(e), raw.tag))
    return DataElement(raw.tag, VR, value, raw.value_tell,
                       raw.length == 0xFFFFFFFF, already_converted=True)
Пример #20
0
    def testImplVRBigEndian_ExplicitLengthSeq(self):
        """Raw read: ImplVR BigEndian SQ with explicit lengths..."""
        # Create a fictional sequence with bytes directly,
        #    similar to PS 3.5-2008 Table 7.5-1 p42
        hexstr = (
            "30 0a 00 B0"    # (300a, 00b0) Beam Sequence
            " 00 00 00 40"    # length
            " ff fe e0 00"    # (fffe, e000) Item Tag
            " 00 00 00 18"    # Item (dataset) Length
            " 30 0a 00 c0"    # (300A, 00C0) Beam Number
            " 00 00 00 02"    # length
            " 31 20"          # value '1 '
            " 30 0a 00 c2"    # (300A, 00C2) Beam Name
            " 00 00 00 06"    # length
            " 42 65 61 6d 20 31"  # value 'Beam 1'
            # -------------
            " ff fe e0 00"    # (fffe, e000) Item Tag
            " 00 00 00 18"    # Item (dataset) Length
            " 30 0a 00 c0"    # (300A, 00C0) Beam Number
            " 00 00 00 02"    # length
            " 32 20"          # value '2 '
            " 30 0a 00 c2"    # (300A, 00C2) Beam Name
            " 00 00 00 06"    # length
            " 42 65 61 6d 20 32"  # value 'Beam 2'
        )

        infile = BytesIO(hex2bytes(hexstr))
        de_gen = data_element_generator(infile,
                                        is_implicit_VR=True,
                                        is_little_endian=False)
        raw_seq = next(de_gen)
        seq = convert_value("SQ", raw_seq)

        # The sequence is parsed, but only into raw data elements.
        # They will be converted when asked for. Check some:
        got = seq[0].BeamNumber
        self.assertTrue(got == 1,
                        "Expected Beam Number 1, got {0!r}".format(got))
        got = seq[1].BeamName
        self.assertTrue(got == 'Beam 2',
                        "Expected Beam Name 'Beam 2', got {0:s}".format(got))
Пример #21
0
    def testImplVRBigEndian_ExplicitLengthSeq(self):
        """Raw read: ImplVR BigEndian SQ with explicit lengths..."""
        # Create a fictional sequence with bytes directly,
        #    similar to PS 3.5-2008 Table 7.5-1 p42
        hexstr = (
            "30 0a 00 B0"  # (300a, 00b0) Beam Sequence
            " 00 00 00 40"  # length
            " ff fe e0 00"  # (fffe, e000) Item Tag
            " 00 00 00 18"  # Item (dataset) Length
            " 30 0a 00 c0"  # (300A, 00C0) Beam Number
            " 00 00 00 02"  # length
            " 31 20"  # value '1 '
            " 30 0a 00 c2"  # (300A, 00C2) Beam Name
            " 00 00 00 06"  # length
            " 42 65 61 6d 20 31"  # value 'Beam 1'
            # -------------
            " ff fe e0 00"  # (fffe, e000) Item Tag
            " 00 00 00 18"  # Item (dataset) Length
            " 30 0a 00 c0"  # (300A, 00C0) Beam Number
            " 00 00 00 02"  # length
            " 32 20"  # value '2 '
            " 30 0a 00 c2"  # (300A, 00C2) Beam Name
            " 00 00 00 06"  # length
            " 42 65 61 6d 20 32"  # value 'Beam 2'
        )

        infile = BytesIO(hex2bytes(hexstr))
        de_gen = data_element_generator(infile,
                                        is_implicit_VR=True,
                                        is_little_endian=False)
        raw_seq = next(de_gen)
        seq = convert_value("SQ", raw_seq)

        # The sequence is parsed, but only into raw data elements.
        # They will be converted when asked for. Check some:
        got = seq[0].BeamNumber
        self.assertTrue(got == 1,
                        "Expected Beam Number 1, got {0!r}".format(got))
        got = seq[1].BeamName
        self.assertTrue(got == 'Beam 2',
                        "Expected Beam Name 'Beam 2', got {0:s}".format(got))
Пример #22
0
    def testImplVRLittleEndian_ExplicitLengthSeq(self):
        """Raw read: ImplVR Little Endian SQ with explicit lengths..."""
        # Create a fictional sequence with bytes directly,
        #    similar to PS 3.5-2008 Table 7.5-1 p42
        hexstr = (
            "0a 30 B0 00"  # (300a, 00b0) Beam Sequence
            " 40 00 00 00"  # length
            " fe ff 00 e0"  # (fffe, e000) Item Tag
            " 18 00 00 00"  # Item (dataset) Length
            " 0a 30 c0 00"  # (300A, 00C0) Beam Number
            " 02 00 00 00"  # length
            " 31 20"  # value '1 '
            " 0a 30 c2 00"  # (300A, 00C2) Beam Name
            " 06 00 00 00"  # length
            " 42 65 61 6d 20 31"  # value 'Beam 1'
            # -------------
            " fe ff 00 e0"  # (fffe, e000) Item Tag
            " 18 00 00 00"  # Item (dataset) Length
            " 0a 30 c0 00"  # (300A, 00C0) Beam Number
            " 02 00 00 00"  # length
            " 32 20"  # value '2 '
            " 0a 30 c2 00"  # (300A, 00C2) Beam Name
            " 06 00 00 00"  # length
            " 42 65 61 6d 20 32"  # value 'Beam 2'
        )

        infile = BytesIO(hex2bytes(hexstr))
        de_gen = data_element_generator(infile,
                                        is_implicit_VR=True,
                                        is_little_endian=True)
        raw_seq = next(de_gen)
        seq = convert_value("SQ", raw_seq)

        # The sequence is parsed, but only into raw data elements.
        # They will be converted when asked for. Check some:
        assert 1 == seq[0].BeamNumber
        assert 'Beam 2' == seq[1].BeamName
Пример #23
0
    def testEmptyItem(self):
        """Read sequence with a single empty item..."""
        # This is fix for issue 27
        hexstr = (
            "08 00 32 10"  # (0008, 1032) SQ "Procedure Code Sequence"
            " 08 00 00 00"  # length 8
            " fe ff 00 e0"  # (fffe, e000) Item Tag
            " 00 00 00 00"  # length = 0
        ) + (  # --------------- end of Sequence
            " 08 00 3e 10"  # (0008, 103e) LO "Series Description"  nopep8
            " 0c 00 00 00"  # length     nopep8
            " 52 20 41 44 44 20 56 49 45 57 53 20"  # value     nopep8
        )
        # "\x08\x00\x32\x10\x08\x00\x00\x00\xfe\xff\x00\xe0\x00\x00\x00\x00"
        # from issue 27, procedure code sequence (0008,1032)
        # hexstr += "\x08\x00\x3e\x10\x0c\x00\x00\x00\x52\x20
        # \x41\x44\x44\x20\x56\x49\x45\x57\x53\x20"
        # data element following

        fp = BytesIO(hex2bytes(hexstr))
        gen = data_element_generator(fp,
                                     is_implicit_VR=True,
                                     is_little_endian=True)
        raw_seq = next(gen)
        seq = convert_value("SQ", raw_seq)

        got_type = "got type {0}".format(str(type(seq)))
        self.assertTrue(isinstance(seq, Sequence),
                        "Did not get Sequence, %s" % got_type)
        expected = "Expected Sequence with single (empty) item"
        got = "got {0:d} item(s)".format(len(seq))
        self.assertTrue(len(seq) == 1, "%s, %s" % (expected, got))
        msg = "Expected the sequence item (dataset) to be empty"
        self.assertTrue(len(seq[0]) == 0, msg)
        elem2 = next(gen)
        self.assertEqual(elem2.tag, 0x0008103e,
                         "Expected a data element after empty sequence item")
def DataElement_from_raw(raw_data_element: RawDataElement,
                         encoding: Optional[List[str]] = None) -> DataElement:
    """Return a :class:`DataElement` created from `raw_data_element`.

    Parameters
    ----------
    raw_data_element : RawDataElement
        The raw data to convert to a :class:`DataElement`.
    encoding : list of str, optional
        The character encoding of the raw data.

    Returns
    -------
    DataElement

    Raises
    ------
    KeyError
        If `raw_data_element` belongs to an unknown non-private tag and
        `config.enforce_valid_values` is set.
    """
    # XXX buried here to avoid circular import
    # filereader->Dataset->convert_value->filereader
    # (for SQ parsing)

    from pydicom.values import convert_value
    raw = raw_data_element

    # If user has hooked into conversion of raw values, call his/her routine
    if config.data_element_callback:
        raw = config.data_element_callback(
            raw_data_element,
            encoding=encoding,
            **config.data_element_callback_kwargs)

    VR = raw.VR
    if VR is None:  # Can be if was implicit VR
        try:
            VR = dictionary_VR(raw.tag)
        except KeyError:
            # just read the bytes, no way to know what they mean
            if raw.tag.is_private:
                # for VR for private tags see PS3.5, 6.2.2
                if raw.tag.is_private_creator:
                    VR = 'LO'
                else:
                    VR = 'UN'

            # group length tag implied in versions < 3.0
            elif raw.tag.element == 0:
                VR = 'UL'
            else:
                msg = "Unknown DICOM tag {0:s}".format(str(raw.tag))
                if config.enforce_valid_values:
                    msg += " can't look up VR"
                    raise KeyError(msg)
                else:
                    VR = 'UN'
                    msg += " - setting VR to 'UN'"
                    warnings.warn(msg)
    elif (VR == 'UN' and not raw.tag.is_private
          and config.replace_un_with_known_vr):
        # handle rare case of incorrectly set 'UN' in explicit encoding
        # see also DataElement.__init__()
        if (raw.length == 0xffffffff or raw.value is None
                or len(raw.value) < 0xffff):
            try:
                VR = dictionary_VR(raw.tag)
            except KeyError:
                pass
    try:
        value = convert_value(VR, raw, encoding)
    except NotImplementedError as e:
        raise NotImplementedError("{0:s} in tag {1!r}".format(str(e), raw.tag))

    if raw.tag in _LUT_DESCRIPTOR_TAGS and value:
        # We only fix the first value as the third value is 8 or 16
        try:
            if value[0] < 0:
                value[0] += 65536
        except TypeError:
            pass

    return DataElement(raw.tag,
                       VR,
                       value,
                       raw.value_tell,
                       raw.length == 0xFFFFFFFF,
                       already_converted=True)
Пример #25
0
 def testReadBadValueInVREnforceValidValue(self):
     pydicom.config.enforce_valid_values = True
     # found a conversion
     self.assertEqual('1A', convert_value('SH', self.tag))
     # invalid literal for base 10
     self.assertRaises(ValueError, convert_value, 'IS', self.tag)
Пример #26
0
def DataElement_from_raw(raw_data_element: RawDataElement,
                         encoding: Optional[Union[
                             str, MutableSequence[str]]] = None,
                         dataset: Optional["Dataset"] = None) -> DataElement:
    """Return a :class:`DataElement` created from `raw_data_element`.

    Parameters
    ----------
    raw_data_element : RawDataElement
        The raw data to convert to a :class:`DataElement`.
    encoding : str or list of str, optional
        The character encoding of the raw data.
    dataset : Dataset, optional
        If given, used to resolve the VR for known private tags.

    Returns
    -------
    DataElement

    Raises
    ------
    KeyError
        If `raw_data_element` belongs to an unknown non-private tag and
        :attr:`~pydicom.config.settings.reading_validation_mode` is set
        to ``RAISE``.
    """
    # XXX buried here to avoid circular import
    # filereader->Dataset->convert_value->filereader
    # (for SQ parsing)

    from pydicom.values import convert_value
    raw = raw_data_element

    # If user has hooked into conversion of raw values, call his/her routine
    if config.data_element_callback:
        raw = config.data_element_callback(
            raw_data_element,
            encoding=encoding,
            **config.data_element_callback_kwargs)

    vr = raw.VR
    if vr is None:  # Can be if was implicit VR
        try:
            vr = dictionary_VR(raw.tag)
        except KeyError:
            # just read the bytes, no way to know what they mean
            if raw.tag.is_private:
                # for VR for private tags see PS3.5, 6.2.2
                vr = _private_vr_for_tag(dataset, raw.tag)

            # group length tag implied in versions < 3.0
            elif raw.tag.element == 0:
                vr = VR_.UL
            else:
                msg = f"Unknown DICOM tag {str(raw.tag)}"
                if config.settings.reading_validation_mode == config.RAISE:
                    raise KeyError(msg + " can't look up VR")

                vr = VR_.UN
                warnings.warn(msg + " - setting VR to 'UN'")
    elif vr == VR_.UN and config.replace_un_with_known_vr:
        # handle rare case of incorrectly set 'UN' in explicit encoding
        # see also DataElement.__init__()
        if raw.tag.is_private:
            vr = _private_vr_for_tag(dataset, raw.tag)
        elif raw.value is None or len(raw.value) < 0xffff:
            try:
                vr = dictionary_VR(raw.tag)
            except KeyError:
                pass
    try:
        value = convert_value(vr, raw, encoding)
    except NotImplementedError as e:
        raise NotImplementedError(f"{str(e)} in tag {raw.tag!r}")
    except BytesLengthException as e:
        message = (
            f"{e} This occurred while trying to parse {raw.tag} according "
            f"to VR '{vr}'.")
        if config.convert_wrong_length_to_UN:
            warnings.warn(f"{message} Setting VR to 'UN'.")
            vr = VR_.UN
            value = raw.value
        else:
            raise BytesLengthException(
                f"{message} To replace this error with a warning set "
                "pydicom.config.convert_wrong_length_to_UN = True.")

    if raw.tag in _LUT_DESCRIPTOR_TAGS and value:
        # We only fix the first value as the third value is 8 or 16
        try:
            if value[0] < 0:
                value[0] += 65536
        except TypeError:
            pass

    return DataElement(
        raw.tag,
        vr,
        value,
        raw.value_tell,
        raw.length == 0xFFFFFFFF,
        already_converted=True,
    )