Ejemplo n.º 1
0
    def test_japanese_multi_byte_personname(self):
        """Test japanese person name which has multi byte strings are
        correctly encoded."""
        file_path = get_charset_files('chrH32.dcm')[0]
        ds = dcmread(file_path)
        ds.decode()

        if hasattr(ds.PatientName, 'original_string'):
            original_string = ds.PatientName.original_string
            ds.PatientName.original_string = None
            fp = DicomBytesIO()
            fp.is_implicit_VR = False
            fp.is_little_endian = True
            ds.save_as(fp, write_like_original=False)
            fp.seek(0)
            ds_out = dcmread(fp)
            assert original_string == ds_out.PatientName.original_string

        japanese_pn = PersonName(u"Mori^Ogai=森^鷗外=もり^おうがい")
        pyencs = pydicom.charset.convert_encodings(
            ["ISO 2022 IR 6", "ISO 2022 IR 87", "ISO 2022 IR 159"])
        actual_encoded = bytes(japanese_pn.encode(pyencs))
        expect_encoded = (
            b"\x4d\x6f\x72\x69\x5e\x4f\x67\x61\x69\x3d\x1b\x24\x42\x3f"
            b"\x39\x1b\x28\x42\x5e\x1b\x24\x28\x44\x6c\x3f\x1b\x24\x42"
            b"\x33\x30\x1b\x28\x42\x3d\x1b\x24\x42\x24\x62\x24\x6a\x1b"
            b"\x28\x42\x5e\x1b\x24\x42\x24\x2a\x24\x26\x24\x2c\x24\x24"
            b"\x1b\x28\x42")
        assert expect_encoded == actual_encoded
Ejemplo n.º 2
0
def convert_PN(byte_string, is_little_endian, struct_format=None, encoding=None):
    """Read and return string(s) as PersonName instance(s)"""

    # XXX - We have to replicate MultiString functionality here because we can't decode
    # easily here since that is performed in PersonNameUnicode
    if byte_string and (byte_string.endswith(b' ') or byte_string.endswith(b'\x00')):
        byte_string = byte_string[:-1]

    splitup = byte_string.split(b"\\")

    if encoding and not in_py2:
        args = (encoding,)
    else:
        args = ()

    # We would like to return string literals
    if not in_py2:
        valtype = lambda x: PersonName(x, *args).decode()
    else:
        valtype = lambda x: PersonName(x, *args)

    if len(splitup) == 1:
        return valtype(splitup[0])
    else:
        return MultiValue(valtype, splitup)
Ejemplo n.º 3
0
    def test_next(self):
        """Test that the next function works on it's own"""
        # Test getting the first character
        pn1 = PersonName("John^Doe^^Dr", encodings=default_encoding)
        pn1_itr = iter(pn1)
        assert next(pn1_itr) == "J"

        # Test getting multiple characters
        pn2 = PersonName("Yamada^Tarou=山田^太郎=やまだ^たろう",
                         [default_encoding, "iso2022_jp"])
        pn2_itr = iter(pn2)
        assert next(pn2_itr) == "Y"
        assert next(pn2_itr) == "a"

        # Test getting all characters
        pn3 = PersonName("SomeName")
        pn3_itr = iter(pn3)
        assert next(pn3_itr) == "S"
        assert next(pn3_itr) == "o"
        assert next(pn3_itr) == "m"
        assert next(pn3_itr) == "e"
        assert next(pn3_itr) == "N"
        assert next(pn3_itr) == "a"
        assert next(pn3_itr) == "m"
        assert next(pn3_itr) == "e"

        # Attempting to get next characeter should stop the iteration
        # I.e. next can only start once
        with pytest.raises(StopIteration):
            next(pn3_itr)

        # Test that next() doesn't work without instantiating an iterator
        pn4 = PersonName("SomeName")
        with pytest.raises(AttributeError):
            next(pn4)
Ejemplo n.º 4
0
 def testFormatting(self):
     """PN: Formatting works..."""
     pn = PersonName("Family^Given")
     expected = "Family, Given"
     got = pn.family_comma_given()
     msg = ("PN: expected '%s', got '%s' for formatted Family, Given"
            % (expected, got))
     self.assertEqual(got, expected, msg)
Ejemplo n.º 5
0
 def test_encoding_carried(self):
     """Test encoding is carried over to a new PN3 object"""
     # Issue 466
     from pydicom.valuerep import PersonName
     pn = PersonName("John^Doe", encodings='iso_ir_126')
     assert pn.encodings == ('iso_ir_126', )
     pn2 = PersonName(pn)
     assert pn2.encodings == ('iso_ir_126', )
Ejemplo n.º 6
0
 def test_from_named_components_with_separator_from_bytes(self):
     # If the names already include separator chars
     # a ValueError should be raised
     with pytest.raises(ValueError):
         PersonName.from_named_components(
             family_name_ideographic=b'\033$B;3ED\033(B^\033$BB@O:\033(B',
             encodings=[default_encoding, 'iso2022_jp'],
         )
Ejemplo n.º 7
0
 def test_unicode_jp_from_bytes_comp_delimiter(self):
     """The example encoding without the escape sequence before '='"""
     pn = PersonName(
         b'Yamada^Tarou='
         b'\033$B;3ED\033(B^\033$BB@O:='
         b'\033$B$d$^$@\033(B^\033$B$?$m$&\033(B',
         [default_encoding, 'iso2022_jp'])
     pn = pn.decode()
     assert (u'Yamada', u'Tarou') == (pn.family_name, pn.given_name)
     assert u'山田^太郎' == pn.ideographic
     assert u'やまだ^たろう' == pn.phonetic
 def test_unicode_jp_from_bytes_comp_delimiter(self):
     """The example encoding without the escape sequence before '='"""
     pn = PersonName(
         b"Yamada^Tarou="
         b"\033$B;3ED\033(B^\033$BB@O:="
         b"\033$B$d$^$@\033(B^\033$B$?$m$&\033(B",
         [default_encoding, "iso2022_jp"],
     )
     pn = pn.decode()
     assert ("Yamada", "Tarou") == (pn.family_name, pn.given_name)
     assert "山田^太郎" == pn.ideographic
     assert "やまだ^たろう" == pn.phonetic
Ejemplo n.º 9
0
 def test_unicode_jp_from_bytes_caret_delimiter(self):
     """PN: 3component in unicode works (Japanese)..."""
     # Example name from PS3.5-2008 section H  p. 98
     pn = PersonName(
         b'Yamada^Tarou='
         b'\033$B;3ED\033(B^\033$BB@O:\033(B='
         b'\033$B$d$^$@\033(B^\033$B$?$m$&\033(B',
         [default_encoding, 'iso2022_jp'])
     pn = pn.decode()
     assert (u'Yamada', u'Tarou') == (pn.family_name, pn.given_name)
     assert u'山田^太郎' == pn.ideographic
     assert u'やまだ^たろう' == pn.phonetic
 def test_unicode_jp_from_bytes_caret_delimiter(self):
     """PN: 3component in unicode works (Japanese)..."""
     # Example name from PS3.5-2008 section H  p. 98
     pn = PersonName(
         b"Yamada^Tarou="
         b"\033$B;3ED\033(B^\033$BB@O:\033(B="
         b"\033$B$d$^$@\033(B^\033$B$?$m$&\033(B",
         [default_encoding, "iso2022_jp"],
     )
     pn = pn.decode()
     assert ("Yamada", "Tarou") == (pn.family_name, pn.given_name)
     assert "山田^太郎" == pn.ideographic
     assert "やまだ^たろう" == pn.phonetic
    def test_iterator(self):
        """Test that iterators can be corretly constructed"""
        name_str = "John^Doe^^Dr"
        pn1 = PersonName(name_str)

        for i, c in enumerate(pn1):
            assert name_str[i] == c

        # Ensure that multiple iterators can be created on the same variable
        for i, c in enumerate(pn1):
            assert name_str[i] == c

        for s in iter(PersonName(name_str)):
            pass
Ejemplo n.º 12
0
    def test_unicode_kr(self):
        """PN: 3component in unicode works (Korean)..."""
        # Example name from PS3.5-2008 section I.2 p. 101
        pn = PersonName(
            b'Hong^Gildong='
            b'\033$)C\373\363^\033$)C\321\316\324\327='
            b'\033$)C\310\253^\033$)C\261\346\265\277',
            [default_encoding, 'euc_kr'])

        # PersonName does not decode the components automatically
        pn = pn.decode()
        assert (u'Hong', u'Gildong') == (pn.family_name, pn.given_name)
        assert u'洪^吉洞' == pn.ideographic
        assert u'홍^길동' == pn.phonetic
    def test_hash(self):
        """Test that the same name creates the same hash."""
        # Regression test for #785
        pn1 = PersonName("John^Doe^^Dr", encodings=default_encoding)
        pn2 = PersonName("John^Doe^^Dr", encodings=default_encoding)
        assert hash(pn1) == hash(pn2)
        pn3 = PersonName("John^Doe", encodings=default_encoding)
        assert hash(pn1) != hash(pn3)

        pn1 = PersonName("Yamada^Tarou=山田^太郎=やまだ^たろう",
                         [default_encoding, "iso2022_jp"])
        pn2 = PersonName("Yamada^Tarou=山田^太郎=やまだ^たろう",
                         [default_encoding, "iso2022_jp"])
        assert hash(pn1) == hash(pn2)
    def test_unicode_kr(self):
        """PN: 3component in unicode works (Korean)..."""
        # Example name from PS3.5-2008 section I.2 p. 101
        pn = PersonName(
            b"Hong^Gildong="
            b"\033$)C\373\363^\033$)C\321\316\324\327="
            b"\033$)C\310\253^\033$)C\261\346\265\277",
            [default_encoding, "euc_kr"],
        )

        # PersonName does not decode the components automatically
        pn = pn.decode()
        assert ("Hong", "Gildong") == (pn.family_name, pn.given_name)
        assert "洪^吉洞" == pn.ideographic
        assert "홍^길동" == pn.phonetic
Ejemplo n.º 15
0
 def test_unicode_jp_from_unicode(self):
     """A person name initialized from unicode is already decoded"""
     pn = PersonName(u'Yamada^Tarou=山田^太郎=やまだ^たろう',
                     [default_encoding, 'iso2022_jp'])
     assert (u'Yamada', u'Tarou') == (pn.family_name, pn.given_name)
     assert u'山田^太郎' == pn.ideographic
     assert u'やまだ^たろう' == pn.phonetic
    def __init__(
        self,
        name: Union[Code, CodedConcept],
        value: Union[str, PersonName],
        relationship_type: Union[str, RelationshipTypeValues, None] = None
    ) -> None:
        """
        Parameters
        ----------
        name: Union[highdicom.sr.CodedConcept, pydicom.sr.coding.Code]
            concept name
        value: Union[str, pydicom.valuerep.PersonName]
            name of the person
        relationship_type: Union[highdicom.sr.RelationshipTypeValues, str]
            type of relationship with parent content item

        """  # noqa
        if relationship_type is None:
            warnings.warn(
                'A future release will require that relationship types be '
                f'provided for items of type {self.__class__.__name__}.',
                DeprecationWarning)
        super(PnameContentItem, self).__init__(ValueTypeValues.PNAME, name,
                                               relationship_type)
        check_person_name(value)
        self.PersonName = PersonName(value)
 def test_last_first(self):
     """PN: Simple Family-name^Given-name works..."""
     pn = PersonName("Family^Given")
     assert "Family" == pn.family_name
     assert "Given" == pn.given_name
     assert "" == pn.name_suffix
     assert "" == pn.phonetic
Ejemplo n.º 18
0
def fill_patient_details_from_mwl(mwl_ds, worklist):
    patientname = worklist['patient']['last_name'] + '^' + worklist['patient'][
        'first_name']
    mwl_ds[0x10, 0x10].value = PersonName(str(patientname))
    mwl_ds[0x10, 0x20].value = worklist['patient']['patient_id']
    mwl_ds[0x10, 0x30].value = change_date_to_dicom_format(
        worklist['patient']['dob'])
    mwl_ds[
        0x10,
        0x40].value = 'M' if worklist['patient']['gender'] == 'Male' else 'F'
    mwl_ds[0x10, 0x2000].value = worklist['patient']['med_alerts']
    mwl_ds[0x10, 0x2110].value = worklist['patient']['allergies']
    if not 'PatientWeight' in mwl_ds:
        if worklist['patient']['weight'] != '':
            mwl_ds.add_new((0x10, 0x1030), 'DS',
                           float(worklist['patient']['weight']))
    else:
        if worklist['patient']['weight'] != '':
            mwl_ds[0x10, 0x1030].value = float(worklist['patient']['weight'])
    if not 'PatientSize' in mwl_ds:
        if worklist['patient']['patient_size'] != '':
            try:
                size_val = float(worklist['patient']['patient_size'])
                mwl_ds.add_new((0x10, 0x1020), 'DS', size_val)
            except:
                print('Error while parsing patient size')
    else:
        if worklist['patient']['patient_size'] != '':
            try:
                size_val = float(worklist['patient']['patient_size'])
                mwl_ds[0x10, 0x1020] = size_val
            except:
                print('Error while parsing patient size')
    def test_not_equal(self):
        """PN3: Not equal works correctly (issue 121)..."""
        # Meant to only be used in python 3 but doing simple check here
        from pydicom.valuerep import PersonName

        pn = PersonName("John^Doe")
        assert not pn != "John^Doe"
Ejemplo n.º 20
0
    def testLastFirst(self):
        """PN: Simple Family-name^Given-name works..."""
        pn = PersonName("Family^Given")
        expected = "Family"
        got = pn.family_name
        self.assertEqual(got, expected,
                         "PN: expected '%s', got '%s' for family name"
                         % (expected, got))

        expected = 'Given'
        got = pn.given_name
        self.assertEqual(got, expected,
                         "PN: expected '%s', got '%s' for given name"
                         % (expected, got))

        expected = ''
        got = pn.name_suffix
        self.assertEqual(got, expected,
                         "PN: expected '%s', got '%s' for name_suffix"
                         % (expected, got))

        expected = ''
        got = pn.phonetic
        self.assertEqual(got, expected,
                         "PN: expected '%s', got '%s' for phonetic component"
                         % (expected, got))
    def _convert(self, val: object) -> object:
        """Convert `val` to an appropriate type for the element's VR."""
        # If the value is a byte string and has a VR that can only be encoded
        # using the default character repertoire, we convert it to a string
        # here to allow for byte string input in these cases
        if _is_bytes(val) and self.VR in ('AE', 'AS', 'CS', 'DA', 'DS', 'DT',
                                          'IS', 'TM', 'UI', 'UR'):
            val = val.decode()

        if self.VR == 'IS':
            return pydicom.valuerep.IS(val)
        elif self.VR == 'DA' and config.datetime_conversion:
            return pydicom.valuerep.DA(val)
        elif self.VR == 'DS':
            return pydicom.valuerep.DS(val)
        elif self.VR == 'DT' and config.datetime_conversion:
            return pydicom.valuerep.DT(val)
        elif self.VR == 'TM' and config.datetime_conversion:
            return pydicom.valuerep.TM(val)
        elif self.VR == "UI":
            return UID(val) if val is not None else None
        elif self.VR == "PN":
            return PersonName(val)
        # Later may need this for PersonName as for UI,
        #    but needs more thought
        # elif self.VR == "PN":
        #    return PersonName(val)
        else:  # is either a string or a type 2 optionally blank string
            return val  # this means a "numeric" value could be empty string ""
Ejemplo n.º 22
0
def fill_sps_details_from_mwl(mwl_ds, worklist):
    sps_seq = mwl_ds[0x40, 0x100][0]
    sps_seq[0x08, 0x60].value = worklist['sps']['modality']
    sps_seq[0x40, 0x01].value = worklist['sps']['station_aet']
    sps_seq[0x40, 0x10].value = worklist['sps']['station_name']
    if worklist['sps']['sps_id'] == '':
        alpha = string.ascii_uppercase
        num = string.digits
        id = ''.join(random.choice(alpha + num) for _ in range(7))
        sps_seq[0x40, 0x09].value = 'SPD' + id
    else:
        sps_seq[0x40, 0x09].value = worklist['sps']['sps_id']

    sps_seq[0x40, 0x07].value = worklist['proc_info']['requested_proc_desc']
    sps_seq[0x40, 0x02].value = change_date_to_dicom_format(
        worklist['sps']['start_date'])
    sps_seq[0x0032, 0x1070].value = worklist['sps']['contrast_agent']
    sps_seq[0x0040, 0x0400].value = worklist['sps']['comments']
    sps_seq[0x0040,
            0x0006].value = PersonName(str(worklist['sps']['operator']))
    sps_seq[0x0040, 0x0012].value = worklist['sps']['pre_meds']
    sps_seq[0x40, 0x03].value = worklist['sps']['start_time']
    if 'status' in worklist['sps'] and worklist['sps']['status'] != '':
        sps_seq.ScheduledProcedureStepStatus = worklist['sps']['status']
    if 'protocol_code' in worklist[
            'sps'] and worklist['sps']['protocol_code'] != '':
        protocol_seq = Dataset()
        protocol_seq.CodeValue = worklist['sps']['protocol_code']
        protocol_seq.CodingSchemeDesignator = worklist['sps'][
            'protocol_code_scheme_designator']
        protocol_seq.CodeMeaning = worklist['sps']['protocol_code_meaning']
        sps_seq.ScheduledProtocolCodeSequence = [protocol_seq]
 def test_unicode_jp_from_unicode(self):
     """A person name initialized from unicode is already decoded"""
     pn = PersonName("Yamada^Tarou=山田^太郎=やまだ^たろう",
                     [default_encoding, "iso2022_jp"])
     assert ("Yamada", "Tarou") == (pn.family_name, pn.given_name)
     assert "山田^太郎" == pn.ideographic
     assert "やまだ^たろう" == pn.phonetic
Ejemplo n.º 24
0
 def testThreeComponent(self):
     """PN: 3component (single-byte, ideographic, phonetic characters) works.."""
     # Example name from PS3.5-2008 section I.2 p. 108
     pn = PersonName("""Hong^Gildong=\033$)C\373\363^\033$)C\321\316\324\327=\033$)C\310\253^\033$)C\261\346\265\277""")
     expected = ("Hong", "Gildong")
     got = (pn.family_name, pn.given_name)
     self.assertEqual(got, expected, "PN: Expected single_byte name '%s', got '%s'" % (expected, got))
 def test_three_component(self):
     """PN: 3component (single-byte, ideographic,
     phonetic characters) works..."""
     # Example name from PS3.5-2008 section I.2 p. 108
     pn = PersonName("Hong^Gildong="
                     "\033$)C\373\363^\033$)C\321\316\324\327="
                     "\033$)C\310\253^\033$)C\261\346\265\277")
     assert ("Hong", "Gildong") == (pn.family_name, pn.given_name)
Ejemplo n.º 26
0
 def test_from_named_components(self):
     # Example from DICOM standard, part 5, sect 6.2.1.1
     pn = PersonName.from_named_components(family_name='Adams',
                                           given_name='John Robert Quincy',
                                           name_prefix='Rev.',
                                           name_suffix='B.A. M.Div.')
     assert pn == 'Adams^John Robert Quincy^^Rev.^B.A. M.Div.'
     assert pn.family_name == 'Adams'
     assert pn.given_name == 'John Robert Quincy'
     assert pn.name_prefix == 'Rev.'
     assert pn.name_suffix == 'B.A. M.Div.'
Ejemplo n.º 27
0
 def test_from_named_components_veterinary(self):
     # Example from DICOM standard, part 5, sect 6.2.1.1
     # A horse whose responsible organization is named ABC Farms, and whose
     # name is "Running On Water"
     pn = PersonName.from_named_components_veterinary(
         responsible_party_name='ABC Farms',
         patient_name='Running on Water',
     )
     assert pn == 'ABC Farms^Running on Water'
     assert pn.family_name == 'ABC Farms'
     assert pn.given_name == 'Running on Water'
Ejemplo n.º 28
0
def empty_value_for_VR(
    VR: Optional[str], raw: bool = False
) -> Union[bytes, List[str], str, None]:
    """Return the value for an empty element for `VR`.

    .. versionadded:: 1.4

    The behavior of this property depends on the setting of
    :attr:`config.use_none_as_empty_value`. If that is set to ``True``,
    an empty value is represented by ``None`` (except for VR 'SQ'), otherwise
    it depends on `VR`. For text VRs (this includes 'AE', 'AS', 'CS', 'DA',
    'DT', 'LO', 'LT', 'PN', 'SH', 'ST', 'TM', 'UC', 'UI', 'UR' and 'UT') an
    empty string is used as empty value representation, for all other VRs
    except 'SQ', ``None``. For empty sequence values (VR 'SQ') an empty list
    is used in all cases.
    Note that this is used only if decoding the element - it is always
    possible to set the value to another empty value representation,
    which will be preserved during the element object lifetime.

    Parameters
    ----------
    VR : str or None
        The VR of the corresponding element.
    raw : bool, optional
        If ``True``, returns the value for a :class:`RawDataElement`,
        otherwise for a :class:`DataElement`

    Returns
    -------
    str or bytes or None or list
        The value a data element with `VR` is assigned on decoding
        if it is empty.
    """
    if VR == 'SQ':
        return b'' if raw else []

    if config.use_none_as_empty_text_VR_value:
        return None

    if VR == 'PN':
        return b'' if raw else PersonName('')

    if VR in (
        'AE', 'AS', 'CS', 'DA', 'DT', 'LO', 'LT', 'SH', 'ST', 'TM',
        'UC', 'UI', 'UR', 'UT'
    ):
        return b'' if raw else ''

    return None
Ejemplo n.º 29
0
 def test_from_named_components_jp_from_unicode(self):
     # Example name from PS3.5-2008 section H  p. 98
     pn = PersonName.from_named_components(
         family_name='Yamada',
         given_name='Tarou',
         family_name_ideographic='山田',
         given_name_ideographic='太郎',
         family_name_phonetic='やまだ',
         given_name_phonetic='たろう',
         encodings=[default_encoding, 'iso2022_jp'],
     )
     pn = pn.decode()
     assert ("Yamada", "Tarou") == (pn.family_name, pn.given_name)
     assert "山田^太郎" == pn.ideographic
     assert "やまだ^たろう" == pn.phonetic
Ejemplo n.º 30
0
 def test_from_named_components_jp_from_bytes(self):
     # Example name from PS3.5-2008 section H  p. 98
     pn = PersonName.from_named_components(
         family_name='Yamada',
         given_name='Tarou',
         family_name_ideographic=b'\033$B;3ED\033(B',
         given_name_ideographic=b'\033$BB@O:\033(B',
         family_name_phonetic=b'\033$B$d$^$@\033(B',
         given_name_phonetic=b'\033$B$?$m$&\033(B',
         encodings=[default_encoding, 'iso2022_jp'],
     )
     pn = pn.decode()
     assert ("Yamada", "Tarou") == (pn.family_name, pn.given_name)
     assert "山田^太郎" == pn.ideographic
     assert "やまだ^たろう" == pn.phonetic
Ejemplo n.º 31
0
 def test_formatting(self):
     """PN: Formatting works..."""
     pn = PersonName("Family^Given")
     assert "Family, Given" == pn.family_comma_given()