Exemple #1
0
def open_dicom(filename, force=False):
    """Iterate over data elements for full control of the reading process.
    
    **Note**: This function is possibly unstable, as it uses the DicomFile class,
    which has been removed in other parts of pydicom in favor of simple files. It
    needs to be updated (or may be removed in future versions of pydicom).
    
    Use ``read_file`` or ``read_partial`` for most purposes. This function 
    is only needed if finer control of the reading process is required.
    
    :param filename: A string containing the file path/name.
    :returns: an iterator which yields one data element each call.
        First, the file_meta data elements are returned, then the data elements
        for the DICOM dataset stored in the file.

    Similar to opening a file using python open() and iterating by line, 
    for example like this::

        from dicom.filereader import open_dicom
        from dicom.dataset import Dataset
        ds = Dataset()
        for data_element in open_dicom("CT_small.dcm"):
            if meets_some_condition(data_element):
                ds.add(data_element)
            if some_other_condition(data_element):
                break
    
    """

    return DicomIter(DicomFile(filename,'rb'), force=force)
Exemple #2
0
def read_file_meta_info(filename):
    """Read and return the DICOM file meta information only.

    This function is meant to be used in user code, for quickly going through
    a series of files to find one which is referenced to a particular SOP,
    without having to read the entire files.
    """
    fp = DicomFile(filename, 'rb')
    preamble = read_preamble(fp, False)  # if no header, raise exception
    return _read_file_meta_info(fp)
Exemple #3
0
def write_file(filename, dataset, WriteLikeOriginal=True):
    """Store a Dataset to the filename specified.
    
    Set dataset.preamble if you want something other than 128 0-bytes.
    If the dataset was read from an existing dicom file, then its preamble
    was stored at read time. It is up to you to ensure the preamble is still
    correct for its purposes.
    If there is no Transfer Syntax tag in the dataset,
       Set dataset.is_implicit_VR, and .is_little_endian
       to determine the transfer syntax used to write the file.
    WriteLikeOriginal -- True if want to preserve the following for each sequence 
        within this dataset:
        - preamble -- if no preamble in read file, than not used here
        - dataset.hasFileMeta -- if writer did not do file meta information,
            then don't write here either
        - seq.is_undefined_length -- if original had delimiters, write them now too,
            instead of the more sensible length characters
        - <dataset>.is_undefined_length_sequence_item -- for datasets that belong to a 
            sequence, write the undefined length delimiters if that is 
            what the original had
        Set WriteLikeOriginal = False to produce a "nicer" DICOM file for other readers,
            where all lengths are explicit.
    """

    # Decide whether to write DICOM preamble. Should always do so unless trying to mimic the original file read in
    preamble = getattr(dataset, "preamble", None)
    if not preamble and not WriteLikeOriginal:
        preamble = "\0" * 128

    file_meta = dataset.file_meta
    if file_meta is None:
        file_meta = Dataset()
    if "TransferSyntaxUID" not in file_meta:
        if dataset.is_little_endian and dataset.is_implicit_VR:
            file_meta.add_new((2, 0x10), "UI", ImplicitVRLittleEndian)
        elif dataset.is_little_endian and not dataset.is_implicit_VR:
            file_meta.add_new((2, 0x10), "UI", ExplicitVRLittleEndian)
        elif dataset.is_big_endian and not dataset.is_implicit_VR:
            file_meta.add_new((2, 0x10), "UI", ExplicitVRBigEndian)
        else:
            raise NotImplementedError, "pydicom has not been verified for Big Endian with Implicit VR"

    fp = DicomFile(filename, "wb")
    try:
        if preamble:
            fp.write(preamble)  # blank 128 byte preamble
            _write_file_meta_info(fp, file_meta)

        # Set file VR, endian. MUST BE AFTER writing META INFO (which changes to Explict LittleEndian)
        fp.is_implicit_VR = dataset.is_implicit_VR
        fp.is_little_endian = dataset.is_little_endian

        write_dataset(fp, dataset)
    finally:
        fp.close()
Exemple #4
0
def write_file(filename, dataset, write_like_original=True):
    """Store a Dataset to the filename specified.

    Set dataset.preamble if you want something other than 128 0-bytes.
    If the dataset was read from an existing dicom file, then its preamble
    was stored at read time. It is up to you to ensure the preamble is still
    correct for its purposes.
    If there is no Transfer Syntax tag in the dataset,
       Set dataset.is_implicit_VR, and .is_little_endian
       to determine the transfer syntax used to write the file.
    write_like_original -- True if want to preserve the following for each sequence
        within this dataset:
        - preamble -- if no preamble in read file, than not used here
        - dataset.hasFileMeta -- if writer did not do file meta information,
            then don't write here either
        - seq.is_undefined_length -- if original had delimiters, write them now too,
            instead of the more sensible length characters
        - <dataset>.is_undefined_length_sequence_item -- for datasets that belong to a
            sequence, write the undefined length delimiters if that is
            what the original had
        Set write_like_original = False to produce a "nicer" DICOM file for other readers,
            where all lengths are explicit.
    """

    # Decide whether to write DICOM preamble. Should always do so unless trying to mimic the original file read in
    preamble = getattr(dataset, "preamble", None)
    if not preamble and not write_like_original:
        preamble = b"\0" * 128
    file_meta = dataset.file_meta
    if file_meta is None:
        file_meta = Dataset()
    if 'TransferSyntaxUID' not in file_meta:
        if dataset.is_little_endian and dataset.is_implicit_VR:
            file_meta.add_new((2, 0x10), 'UI', ImplicitVRLittleEndian)
        elif dataset.is_little_endian and not dataset.is_implicit_VR:
            file_meta.add_new((2, 0x10), 'UI', ExplicitVRLittleEndian)
        elif not dataset.is_little_endian and not dataset.is_implicit_VR:
            file_meta.add_new((2, 0x10), 'UI', ExplicitVRBigEndian)
        else:
            raise NotImplementedError(
                "pydicom has not been verified for Big Endian with Implicit VR"
            )

    caller_owns_file = True
    # Open file if not already a file object
    if isinstance(filename, str):
        fp = DicomFile(filename, 'wb')
        # caller provided a file name; we own the file handle
        caller_owns_file = False
    else:
        fp = DicomFileLike(filename)

    try:
        if preamble:
            fp.write(preamble)  # blank 128 byte preamble
            _write_file_meta_info(fp, file_meta)

        # Set file VR, endian. MUST BE AFTER writing META INFO (which changes to Explicit LittleEndian)
        fp.is_implicit_VR = dataset.is_implicit_VR
        fp.is_little_endian = dataset.is_little_endian

        write_dataset(fp, dataset)
    finally:
        if not caller_owns_file:
            fp.close()