Exemplo n.º 1
0
def code_dataelem(dataelem,
                  dataset_name="ds",
                  exclude_size=None,
                  include_private=False):
    """Code lines for a single DICOM data element

    :arg dataelem: the DataElement instance to turn into code
    :arg dataset_name: variable name of the Dataset containing dataelem
    :arg exclude_size: if specified, values longer than this (in bytes)
                       will only have a commented string for a value,
                       causing a syntax error when the code is run,
                       and thus prompting the user to remove or fix that line.
    :return: a string containing code to recreate the data element
             If the data element is a sequence, calls code_sequence

    """

    if dataelem.VR == "SQ":
        return code_sequence(dataelem, dataset_name, exclude_size,
                             include_private)

    # If in DICOM dictionary, set using the keyword
    # If not (e.g. is private element), set using add_new method
    have_keyword = True
    try:
        keyword = dictionary_keyword(dataelem.tag)
    except KeyError:
        have_keyword = False

    valuerep = repr(dataelem.value)
    if exclude_size:
        if dataelem.VR in byte_VRs and len(dataelem.value) > exclude_size:
            valuerep = "# XXX Array of %d bytes excluded" % len(dataelem.value)

    if have_keyword:
        format_str = "{ds_name}.{keyword} = {valuerep}"
        line = format_str.format(ds_name=dataset_name,
                                 keyword=keyword,
                                 valuerep=valuerep)
    else:
        format_str = "{ds_name}.add_new({tag}, '{VR}', {valuerep})"
        line = format_str.format(ds_name=dataset_name,
                                 tag=tag_repr(dataelem.tag),
                                 VR=dataelem.VR,
                                 valuerep=valuerep)
    return line
Exemplo n.º 2
0
def code_dataelem(dataelem, dataset_name="ds", exclude_size=None,
                  include_private=False):
    """Code lines for a single DICOM data element

    :arg dataelem: the DataElement instance to turn into code
    :arg dataset_name: variable name of the Dataset containing dataelem
    :arg exclude_size: if specified, values longer than this (in bytes)
                       will only have a commented string for a value,
                       causing a syntax error when the code is run,
                       and thus prompting the user to remove or fix that line.
    :return: a string containing code to recreate the data element
             If the data element is a sequence, calls code_sequence

    """

    if dataelem.VR == "SQ":
        return code_sequence(dataelem, dataset_name, exclude_size,
                             include_private)

    # If in DICOM dictionary, set using the keyword
    # If not (e.g. is private element), set using add_new method
    have_keyword = True
    try:
        keyword = dictionary_keyword(dataelem.tag)
    except KeyError:
        have_keyword = False

    valuerep = repr(dataelem.value)
    if exclude_size:
        if dataelem.VR in byte_VRs and len(dataelem.value) > exclude_size:
            valuerep = "# XXX Array of %d bytes excluded" % len(dataelem.value)

    if have_keyword:
        format_str = "{ds_name}.{keyword} = {valuerep}"
        line = format_str.format(ds_name=dataset_name,
                                 keyword=keyword,
                                 valuerep=valuerep)
    else:
        format_str = "{ds_name}.add_new({tag}, '{VR}', {valuerep})"
        line = format_str.format(ds_name=dataset_name,
                                 tag=tag_repr(dataelem.tag),
                                 VR=dataelem.VR,
                                 valuerep=valuerep)
    return line
Exemplo n.º 3
0
def code_sequence(dataelem, dataset_name="ds",
                  exclude_size=None, include_private=False,
                  name_filter=default_name_filter):
    """Code lines for recreating a Sequence data element

    :arg dataelem: the DataElement instance of the Sequence
    :arg dataset_name: variable name of the dataset containing the Sequence
    :arg exclude_size: if specified, values longer than this (in bytes)
                       will only have a commented string for a value,
                       causing a syntax error when the code is run,
                       and thus prompting the user to remove or fix that line.
    :arg include_private: If True, private data elements will be coded.
                          If False, private elements are skipped
    :arg name_filter: a callable taking a sequence name or sequence item name,
                      and returning a shorter name for easier code reading
    :return: a string containing code lines to recreate a DICOM sequence

    """
    lines = []
    seq = dataelem.value
    seq_name = dataelem.name
    seq_item_name = seq_name.replace(' Sequence', '')
    seq_keyword = dictionary_keyword(dataelem.tag)

    # Create comment line to document the start of Sequence
    lines.append('')
    lines.append("# " + seq_name)

    # Code line to create a new Sequence object
    if name_filter:
        seq_var = name_filter(seq_keyword)
    lines.append(seq_var + " = Sequence()")

    # Code line to add the sequence to its parent
    lines.append(dataset_name + "." + seq_keyword + " = " + seq_var)

    # Code lines to add sequence items to the Sequence
    for i, ds in enumerate(seq):
        # Determine index to use. If seq item has a data element with 'Index',
        #    use that; if one with 'Number', use that, else start at 1
        index_keyword = seq_keyword.replace("Sequence", "") + "Index"
        number_keyword = seq_keyword.replace("Sequence", "") + "Number"
        if index_keyword in ds:
            index_str = str(getattr(ds, index_keyword))
        elif number_keyword in ds:
            index_str = str(getattr(ds, number_keyword))
        else:
            index_str = str(i + 1)

        # Code comment line to mark start of sequence item
        lines.append('')
        lines.append("# " + seq_name + ": " + seq_item_name + " " + index_str)

        # Determine the variable name to use for the sequence item (dataset)
        ds_name = seq_var.replace("_sequence", "") + index_str

        # Code the sequence item
        code_item = code_dataset(ds, ds_name, exclude_size, include_private)
        lines.append(code_item)

        # Code the line to append the item to its parent sequence
        lines.append(seq_var + ".append(" + ds_name + ")")

    # Join the lines and return a single string
    return line_term.join(lines)
Exemplo n.º 4
0
def code_sequence(dataelem,
                  dataset_name="ds",
                  exclude_size=None,
                  include_private=False,
                  name_filter=default_name_filter):
    """Code lines for recreating a Sequence data element

    :arg dataelem: the DataElement instance of the Sequence
    :arg dataset_name: variable name of the dataset containing the Sequence
    :arg exclude_size: if specified, values longer than this (in bytes)
                       will only have a commented string for a value,
                       causing a syntax error when the code is run,
                       and thus prompting the user to remove or fix that line.
    :arg include_private: If True, private data elements will be coded.
                          If False, private elements are skipped
    :arg name_filter: a callable taking a sequence name or sequence item name,
                      and returning a shorter name for easier code reading
    :return: a string containing code lines to recreate a DICOM sequence

    """
    lines = []
    seq = dataelem.value
    seq_name = dataelem.name
    seq_item_name = seq_name.replace(' Sequence', '')
    seq_keyword = dictionary_keyword(dataelem.tag)

    # Create comment line to document the start of Sequence
    lines.append('')
    lines.append("# " + seq_name)

    # Code line to create a new Sequence object
    if name_filter:
        seq_var = name_filter(seq_keyword)
    lines.append(seq_var + " = Sequence()")

    # Code line to add the sequence to its parent
    lines.append(dataset_name + "." + seq_keyword + " = " + seq_var)

    # Code lines to add sequence items to the Sequence
    for i, ds in enumerate(seq):
        # Determine index to use. If seq item has a data element with 'Index',
        #    use that; if one with 'Number', use that, else start at 1
        index_keyword = seq_keyword.replace("Sequence", "") + "Index"
        number_keyword = seq_keyword.replace("Sequence", "") + "Number"
        if index_keyword in ds:
            index_str = str(getattr(ds, index_keyword))
        elif number_keyword in ds:
            index_str = str(getattr(ds, number_keyword))
        else:
            index_str = str(i + 1)

        # Code comment line to mark start of sequence item
        lines.append('')
        lines.append("# " + seq_name + ": " + seq_item_name + " " + index_str)

        # Determine the variable name to use for the sequence item (dataset)
        ds_name = seq_var.replace("_sequence", "") + index_str

        # Code the sequence item
        code_item = code_dataset(ds, ds_name, exclude_size, include_private)
        lines.append(code_item)

        # Code the line to append the item to its parent sequence
        lines.append(seq_var + ".append(" + ds_name + ")")

    # Join the lines and return a single string
    return line_term.join(lines)