pydicom - Read, modify and write DICOM files with python code

Overview

CircleCI codecov Python version PyPI version DOI Gitter

pydicom

pydicom is a pure Python package for working with DICOM files. It lets you read, modify and write DICOM data in an easy "pythonic" way.

As a pure Python package, pydicom can run anywhere Python runs without any other requirements, although if you're working with Pixel Data then we recommend you also install NumPy.

If you're looking for a Python library for DICOM networking then you might be interested in another of our projects: pynetdicom.

Installation

Using pip:

pip install pydicom

Using conda:

conda install -c conda-forge pydicom

For more information, including installation instructions for the development version, see the installation guide.

Documentation

The pydicom user guide, tutorials, examples and API reference documentation is available for both the current release and the development version on GitHub Pages.

Pixel Data

Compressed and uncompressed Pixel Data is always available to be read, changed and written as bytes:

>> ds = dcmread(path) >>> type(ds.PixelData) >>> len(ds.PixelData) 32768 >>> ds.PixelData[:2] b'\xaf\x00' ">
>>> from pydicom import dcmread
>>> from pydicom.data import get_testdata_file
>>> path = get_testdata_file("CT_small.dcm")
>>> ds = dcmread(path)
>>> type(ds.PixelData)
<class 'bytes'>
>>> len(ds.PixelData)
32768
>>> ds.PixelData[:2]
b'\xaf\x00'

If NumPy is installed, Pixel Data can be converted to an ndarray using the Dataset.pixel_array property:

>>> arr = ds.pixel_array
>>> arr.shape
(128, 128)
>>> arr
array([[175, 180, 166, ..., 203, 207, 216],
       [186, 183, 157, ..., 181, 190, 239],
       [184, 180, 171, ..., 152, 164, 235],
       ...,
       [906, 910, 923, ..., 922, 929, 927],
       [914, 954, 938, ..., 942, 925, 905],
       [959, 955, 916, ..., 911, 904, 909]], dtype=int16)

Compressed Pixel Data

JPEG, JPEG-LS and JPEG 2000

Converting JPEG compressed Pixel Data to an ndarray requires installing one or more additional Python libraries. For information on which libraries are required, see the pixel data handler documentation.

Compressing data into one of the JPEG formats is not currently supported.

RLE

Encoding and decoding RLE Pixel Data only requires NumPy, however it can be quite slow. You may want to consider installing one or more additional Python libraries to speed up the process.

Examples

More examples are available in the documentation.

Change a patient's ID

from pydicom import dcmread

ds = dcmread("/path/to/file.dcm")
# Edit the (0010,0020) 'Patient ID' element
ds.PatientID = "12345678"
ds.save_as("/path/to/file_updated.dcm")

Display the Pixel Data

With NumPy and matplotlib

import matplotlib.pyplot as plt
from pydicom import dcmread
from pydicom.data import get_testdata_file

# The path to a pydicom test dataset
path = get_testdata_file("CT_small.dcm")
ds = dcmread(path)
# `arr` is a numpy.ndarray
arr = ds.pixel_array

plt.imshow(arr, cmap="gray")
plt.show()

Contributing

To contribute to pydicom, read our contribution guide.

To contribute an example or extension of pydicom that doesn't belong with the core software, see our contribution repository: contrib-pydicom.

Comments
  • New Release

    New Release

    When can I expect a new release?

    I am looking for TM and DT VR's to be converted to date and timestamps. This was committed to the repo about 3 years ago but it is not in v0.9.9 for some reason?

    There are over 640 commits between v0.9.9 and master. As a recommendation, I would definitely try to release more versions...

    opened by addisonElliott 140
  • Implementation of structured reporting

    Implementation of structured reporting

    This pull request is intended to facilitate the creation of DICOM Structured Reports (SR).

    It adds the sr package, which implements

    A few things still need to be completed. However, I was hoping to already get your feedback on the approach in general and whether you would be interested in including this code into the pydicom package.

    I suggest @pieper, @fedorov, @seandoyle and @dclunie as reviewers. We had several discussions on how to implement SR at the 2019 NA-MIC project week and beyond.

    Below is an example for creating a SR document using pydicom.sr (the resulting DICOM PS3.10 file is also included in the repository: pydicom/data/test_files/SR_comprehensive3d.dcm:

    from pydicom.filereader import dcmread
    from pydicom.uid import generate_uid
    from pydicom.sr.context_groups.cid_4 import CERVICOTHORACIC_SPINE
    from pydicom.sr.context_groups.cid_100 import CT_UNSPECIFIED_BODY_REGION
    from pydicom.sr.context_groups.cid_218 import AREA_OF_DEFINED_REGION
    from pydicom.sr.context_groups.cid_220 import NOT_SIGNIFICANT
    from pydicom.sr.context_groups.cid_222 import NORMAL
    from pydicom.sr.context_groups.cid_270 import PERSON, DEVICE
    from pydicom.sr.context_groups.cid_6115 import VERTEBRAL_FORAMEN
    from pydicom.sr.context_groups.cid_7151 import SPINAL_CORD
    from pydicom.sr.context_groups.cid_7461 import SQUARE_CENTIMETER
    from pydicom.sr.document import Comprehensive3DSR
    from pydicom.sr.templates import (
        DeviceObserverIdentifyingAttributes,
        FindingSite,
        Measurement,
        MeasurementProperties,
        MeasurementReport,
        ObservationContext,
        ObserverContext,
        PersonObserverIdentifyingAttributes,
        PlanarROIMeasurementsAndQualitativeEvaluations,
        ReferencedRegion,
        ReferencedVolume,
        ROIMeasurements,
        SourceImageForRegion,
        SourceImageForSegmentation,
        SubjectContext,
        TrackingIdentifier,
        VolumetricROIMeasurementsAndQualitativeEvaluations,
    )
    from pydicom.sr.value_types import GraphicTypes
    
    if __name__ == '__main__':
    
        ref_filename = 'pydicom/data/test_files/CT_small.dcm'
        ref_dataset = dcmread(ref_filename)
    
        observer_person_context = ObserverContext(
            observer_type=PERSON,
            observer_identifying_attributes=PersonObserverIdentifyingAttributes(
                name='Foo'
            )
        )
        observer_device_context = ObserverContext(
            observer_type=DEVICE,
            observer_identifying_attributes=DeviceObserverIdentifyingAttributes(
                uid=generate_uid()
            )
        )
        observation_context = ObservationContext(
            observer_person_context=observer_person_context,
            observer_device_context=observer_device_context,
        )
    
        region_reference = ReferencedRegion(
            graphic_type=GraphicTypes.CIRCLE,
            graphic_data=((58.0, 52.0), (58.0, 41.0)),
            source_image=SourceImageForRegion(
                sop_class_uid=ref_dataset.SOPClassUID,
                sop_instance_uid=ref_dataset.SOPInstanceUID
            )
        )
        finding_sites = [
            FindingSite(
                anatomic_location=CERVICOTHORACIC_SPINE,
                topographical_modifier=VERTEBRAL_FORAMEN
            ),
        ]
        measurements = [
            Measurement(
                name=AREA_OF_DEFINED_REGION,
                tracking_identifier=TrackingIdentifier(uid=generate_uid()),
                value=1.7,
                unit=SQUARE_CENTIMETER,
                properties=MeasurementProperties(
                    normality=NORMAL,
                    level_of_significance=NOT_SIGNIFICANT
                )
            )
        ]
        region_measurements = ROIMeasurements(
            measurements=measurements,
            finding_sites=finding_sites
        )
        imaging_measurements = PlanarROIMeasurementsAndQualitativeEvaluations(
            tracking_identifier=TrackingIdentifier(
                uid=generate_uid(),
                identifier='Planar ROI Measurements'
            ),
            referenced_region=region_reference,
            finding_type=SPINAL_CORD,
            measurements=region_measurements
        )
        measurement_report = MeasurementReport(
            observation_context=observation_context,
            procedure_reported=CT_UNSPECIFIED_BODY_REGION,
            imaging_measurements=imaging_measurements
        )
    
        document = Comprehensive3DSR(
            evidence=[ref_dataset],
            content=measurement_report,
            series_instance_uid=generate_uid(),
            series_number=1,
            series_description='Measurement Reports',
            sop_instance_uid=generate_uid(),
            instance_number=1,
            institution_name='Institution',
            institution_department_name='Institution Department',
            manufacturer='Manufacturer'
        )
        document_filename = '/tmp/{}.dcm'.format(document.SOPInstanceUID)
        document.save_as(document_filename)
    
    opened by hackermd 133
  • Open JPEG Lossless image

    Open JPEG Lossless image

    Description

    Hello, I am trying to use pydicom to open images in a dicom directory. But when I try to open an image, I have this error : NotImplementedError: No available image handler could decode this transfer syntax JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1])

    Steps/Code to Reproduce

    I run this :

    for record in ds.DirectoryRecordSequence:
      if record.DirectoryRecordType == "IMAGE":
      # Extract the relative path to the DICOM file
            path = os.path.join(*record.ReferencedFileID)
            dcm = dicom.read_file(path)
            d = dcm.pixel_array
    

    and it output the NotImplemented Error

    Versions

    I have tried with pydicom 1.0.

    Do you have any idea how to solve this error or another package to open these images ?
    Thank you very much in advance.

    question 
    opened by alexattia 60
  • [MRG+2] Add data_files to setup.py

    [MRG+2] Add data_files to setup.py

    Reference Issue

    This PR will fix #430 by adding a data_files specification in the setup.py

    What does this implement/fix? Explain your changes.

    We basically needed to define the variable data_files as a list of tuples, each with a relative path to a folder, and then a list of files.

    Any other comments?

    Special shout outs to avocados, and stack overflow!

    opened by vsoch 56
  • [RFC] best practices

    [RFC] best practices

    from @scaramallion 's comment I would like to start a discussion regarding best practices.

    contributing guide:

    Do you have any objection to adopting this contributing guide from scikit-learn (either partially or fully)

    Merge policy:

    I would propose a policy of MRG+2. Maybe we should rework the pydicom rights. We could keep that only @darcymason, @scaramallion and @vsoch could merge to master (as it is, right now) but allow other people from pydicom edit the issue tracker (to +1 PR, close Issues, manage tags, etc..). Maybe we could also add @rhaxton and @glemaitre in such category, if they want to.

    RFC 
    opened by massich 46
  • Provide PixelData decompression (JPEG, RLE, MPEG, etc)

    Provide PixelData decompression (JPEG, RLE, MPEG, etc)

    From [email protected] on October 07, 2008 20:40:33

    pydicom can read JPEG files, but the pixel data remains compressed. Should investigate incorporating JPEG code to allow at least decompression of read images.

    Original issue: http://code.google.com/p/pydicom/issues/detail?id=16

    enhancement imported Difficulty-Hard 
    opened by darcymason 39
  • Pydicom release 1.4

    Pydicom release 1.4

    The 1.4 release is scheduled for December, so we may start to prepare it, especially regarding the issues to be fixed for the release.

    Release check list (more information)

    • [x] go through issues and close, assign to this version, or assign to future versions
    • [x] go through PRs to see which can be pulled in before release
    • [x] update Release Notes by going through revision history
    • [x] update the version in pydicom/_version.py to release
    • [x] check in the changes and create a branch and a GitHub release
    • [x] get the new DOI at https://zenodo.org/account/settings/github/repository/pydicom/pydicom), and update the README.md in the release branch
    • [x] publish on PyPi
    • [x] update documentation version on GitHub Pages
    • [x] update the version in pydicom/_version.py in master to next development version (major.minor.0.dev0), and update the DOI in the README.md
    • [x] merge auto-generated PR in conda-forge pydicom-feedstock
    • [ ] announce on pydicom google group

    List of issues tagged for 1.4 release

    (with my usual 2 € cents added)

    • [x] ~#881 File_meta - there is ongoing work on that in #885 by @darcymason~ v2.0
    • [x] ~#148 Error when write dicom with Ironpython: this is difficult without pytest working there, not sure who can handle this~ - closed as not a bug
    • [x] #277 Programmatically Find Corrupt Files: this is about propagating an EOF exception in strict mode, trivial fix if wanted :heavy_check_mark:
    • [x] #285 Document use of Datasets without files: probably just another small example in the documentation, can be easily done :heavy_check_mark:
    • [x] #456 performance/time_tests has hardcoded paths: not really important, best done by @darcymason as he uses this code, but milestone can easily be moved :heavy_check_mark:
    • [x] #483 Difference of data_element_generator in filereader and util.leandread: this needs only a docstring update, so can be done easily :heavy_check_mark:
    • [x] #537 Choose image handlers explicitly: given the trouble with different handlers, this would be helpful, I think - @darcymason, can you check if your last suggestion is still valid? :heavy_check_mark:
    • [x] #685 Generators in encaps don't handle single fragment per frame correctly with no BOT value - there is a rather old PR #688 - handled by @scaramallion - new PR #997 ✔️
    • [x] #693 Wrong jpeg 2000 image from pillow handler - PR #1001 ✔️
    • [x] ~#790 Clarify pydicom-contrib versus examples in pydicom: this is a request for discussion, that makes sense, but is not relevant for the release IMHO~ - removed milestone
    • [x] #822 Handling DICOMDIR files with records in reverse-hierarchical order: trivial fix, ~I actually did this some time ago~ - confused this with another issue, but the fix has been provided, it is merely a matter of finding/generating test data, maybe I will have a look :heavy_check_mark:
    • [x] ~#826 Wrong RGB values when using pixel_array: unclear, probably a Pillow issue, and missing feedback - would remove this from the list~ addressed via documentation - s
    • [x] #848 Dicomdir should warn if not explicit VR little endian - easily done :heavy_check_mark:
    • [x] PR #824 / #1012 Implementation of structured reporting ✔️
    housekeeping 
    opened by mrbean-bremen 36
  • save as the dicom but doesn't show in dicompyler or other software

    save as the dicom but doesn't show in dicompyler or other software

    Description

    I created a dicom file in pydicom,
    I used the code to write. I wrote the dicom file in pydicom as that message and it is showed in pydicom as follow: The dicom file just 79 kb, I don't know how to get a correct format. Please help me,thanks code:

        file_meta = Dataset()
        file_meta.MediaStorageSOPClassUID = RS_SOPInstanceUID
        file_meta.MediaStorageSOPInstanceUID = "RT Structure Set Storage"
        file_meta.TransferSyntaUID='Explicit VR Little Endian'
        file_meta.ImplementationClassUID = "1.2.250.1.59.3.0.3.3.1"
        RT_imageStorage = FileDataset(save_path, {},
                     file_meta=file_meta, preamble=b"\0" * 128)
        RT_imageStorage.SpecificCharacterSet=CT.SpecificCharacterSet
        RT_imageStorage.InstanceCreationDate=InstanceCreationDate
        RT_imageStorage.InstanceCreationTime=InstanceCreationTime
        RT_imageStorage.SOPClassUID='RT Structure Set Storage'
        RT_imageStorage.SOPInstanceUID= RS_SOPInstanceUID
        RT_imageStorage.StudyDate=CT.StudyDate
        RT_imageStorage.StudyTime=CT.StudyTime
        RT_imageStorage.AccessionNumber=''
        RT_imageStorage.Modality='RTSTRUCT
        RT_imageStorage.is_little_endian = False
        RT_imageStorage.is_implicit_VR = False
        RT_imageStorage.save_as('/public/home/write2dcm/123/test/1234.dcm')'
    

    (3006, 002a) ROI Display Color IS: ['0', '147', '0'] (3006, 0040) Contour Sequence 12 item(s) ---- (3006, 0016) Contour Image Sequence 1 item(s) ---- (0008, 1150) Referenced SOP Class UID UI: CT Image Storage (0008, 1155) Referenced SOP Instance UID UI: 1.3.6.1.4.1.2452.6.3054396209.xxxxxxxx.1983321519.xxxxxxxxx --------- (3006, 0042) Contour Geometric Type CS: 'CLOSED_PLANAR' (3006, 0046) Number of Contour Points IS: "58" (3006, 0048) Contour Number IS: "1" (3006, 0050) Contour Data DS: ['24.671679', '-57.148172', '31.000000', '25.532824', '-57.054517', '31.000000', '26.378794', '-56.868305', '31.000000', '27.199673', '-56.591719', '31.000000', '27.985835', '-56.228001', '31.000000', '28.728064', '-55.781417', '31.000000', '29.417658', '-55.257201', '31.000000', '30.046531', '-54.661501', '31.000000', '30.607312', '-54.001299', '31.000000', '31.093425', '-53.284336', '31.000000', '31.499171', '-52.519018', '31.000000', '31.819793', '-51.714317', '31.000000', '32.051532', '-50.879669', '31.000000', '32.191671', '-50.024857', '31.000000', '32.238568', '-49.159905', '31.000000', '32.191671', '-48.294953', '31.000000', '32.051532', '-47.440141', '31.000000', '31.819793', '-46.605493', '31.000000', '31.499171', '-45.800792', '31.000000', '31.093425', '-45.035474', '31.000000', '30.607312', '-44.318511', '31.000000', '30.046531', '-43.658309', '31.000000', '29.417658', '-43.062609', '31.000000', '28.728064', '-42.538393', '31.000000', '27.985835', '-42.091809', '31.000000', '27.199673', '-41.728091', '31.000000', '26.378794', '-41.451505', '31.000000', '25.532824', '-41.265293', '31.000000', '24.671679', '-41.171638', '31.000000', '23.805456', '-41.171638', '31.000000', '22.944312', '-41.265293', '31.000000', '22.098341', '-41.451505', '31.000000', '21.277462', '-41.728091', '31.000000', '20.491300', '-42.091809', '31.000000', '19.749071', '-42.538393', '31.000000', '19.059477', '-43.062609', '31.000000', '18.430604', '-43.658309', '31.000000', '17.869823', '-44.318511', '31.000000', '17.383710', '-45.035474', '31.000000', '16.977964', '-45.800792', '31.000000', '16.657342', '-46.605493', '31.000000', '16.425603', '-47.440141', '31.000000', '16.285464', '-48.294953', '31.000000', '16.238568', '-49.159905', '31.000000', '16.285464', '-50.024857', '31.000000', '16.425603', '-50.879669', '31.000000', '16.657342', '-51.714317', '31.000000', '16.977964', '-52.519018', '31.000000', '17.383710', '-53.284336', '31.000000', '17.869823', '-54.001299', '31.000000', '18.430604', '-54.661501', '31.000000', '19.059477', '-55.257201', '31.000000', '19.749071', '-55.781417', '31.000000', '20.491300', '-56.228001', '31.000000', '21.277462', '-56.591719', '31.000000', '22.098341', '-56.868305', '31.000000', '22.944312', '-57.054517', '31.000000', '23.805456', '-57.148172', '31.000000']

    Steps/Code to Reproduce

    Expected Results

    Actual Results

    Versions

    question 
    opened by wangjiangyuan 36
  • pypi release with new package name

    pypi release with new package name

    Can we get a pypi release of pydicom with the new package name? The fact you cannot install from pypi with the new package name is causing issues like: https://github.com/patmun/pynetdicom/pull/43.

    opened by cancan101 36
  • [MRG] Refactoring documentation

    [MRG] Refactoring documentation

    related to #383 closes #366

    This PR intends:

    • [x] Build with Circle CI
    • [x] Automatic examples generation using sphinx-gallery
    • [x] Use numpydoc
    • [x] Clean the install with only the necessary packages
    • [ ] Generate and add pair of SSH keys for deploying doc
    • [x] Initialize the gh-pages with the folder structure. #389
    opened by glemaitre 34
  • Extracting ROI pixel Value from a directory

    Extracting ROI pixel Value from a directory

    Hi Everyone,

    i have a directory with 189 DICOM data and i want to extract all the pixel Value in a specific ROI from all the DICOM Images , i used to do this for one image and that´s working. i tried to open the directory and to switch it into numpy Array but i couldnt have any results.

    This how looks my first try:

    import os import pydicom import matplotlib.pyplot as plt import numpy as np

    dirname = 'C:\Python27\DICOM\ST000000\SE000013/' files = os.listdir(dirname) ds_list = [pydicom.dcmread(os.path.join(dirname, filename) ) for filename in files]

    Thanks !

    question 
    opened by nature01 33
  • Extract jpg file from dicom without decoding

    Extract jpg file from dicom without decoding

    Is your feature request related to a problem? Please describe. The problem is that using pixel_array is very slow with very large images. GPU based Libraries like nvjpeg and nvjpeg2000 https://developer.nvidia.com/nvjpeg exist which speed up this process immensely. It'd be great to have an api with pydicom which can extract the underlying jpg file directly to a stream or to a file which can be loaded via tools like dali. https://developer.nvidia.com/dali

    Describe the solution you'd like something like ds.to_underlying_jpg("file.jpg") without doing any handler decoding.

    enhancement 
    opened by blazespinnaker 2
  • TestFileSet test failures on i686 architecture

    TestFileSet test failures on i686 architecture

    Describe the bug

    2 TestFileSet tests fail on i686 (32-bit x86) architecture with an OverflowError. FAILED pydicom/tests/test_fileset.py::TestFileSet_Modify::test_write_file_id FAILED pydicom/tests/test_fileset.py::TestFileSet_Copy::test_file_id

    Expected behavior

    Test behavior should be consistent across architectures.

    Steps To Reproduce

    Run

    pytest pydicom/tests/test_fileset.py 
    

    in the pydicom directory on an i686 machine. Virtualizing i686 using QEMU also reproduces the issue.

    =================================== FAILURES ===================================
    ____________________ TestFileSet_Modify.test_write_file_id _____________________
    
    self = <pydicom.tests.test_fileset.TestFileSet_Modify object at 0xe87f1430>
    tiny = Dataset.file_meta -------------------------------
    (0002, 0000) File Meta Information Group Length  UL: 200
    (0002, 0001...Syntax UID in F UI: Explicit VR Little Endian
       (0020, 0013) Instance Number                     IS: '49'
       ---------
    
        def test_write_file_id(self, tiny):
            """Test that the File IDs character sets switch correctly."""
            tdir, ds = temporary_fs(tiny)
        
            def my_len(self):
                return 10**6 + 1
        
            FileSet.__len__ = my_len
            fs = FileSet(ds)
            assert 10**6 + 1 == len(fs)
            ds, paths = write_fs(fs)
            instance = fs._instances[-1]
            # Was written with alphanumeric File IDs
            assert "IM00001D" in instance.path
        
            def my_len(self):
                return 36**6 + 1
        
            FileSet.__len__ = my_len
            fs = FileSet(ds)
    >       assert 36**6 + 1 == len(fs)
    E       OverflowError: cannot fit 'int' into an index-sized integer
    
    pydicom/tests/test_fileset.py:2249: OverflowError
    ________________________ TestFileSet_Copy.test_file_id _________________________
    
    self = <pydicom.tests.test_fileset.TestFileSet_Copy object at 0xe837f370>
    tiny = Dataset.file_meta -------------------------------
    (0002, 0000) File Meta Information Group Length  UL: 200
    (0002, 0001...Syntax UID in F UI: Explicit VR Little Endian
       (0020, 0013) Instance Number                     IS: '49'
       ---------
    tdir = <TemporaryDirectory '/tmp/guix-build-python-pydicom-2.3.1.drv-0/tmpcki9joul'>
    
        def test_file_id(self, tiny, tdir):
            """Test that the File IDs character sets switch correctly."""
            def my_len(self):
                return 10**6 + 1
        
            FileSet.__len__ = my_len
            fs = FileSet(tiny)
            assert 10**6 + 1 == len(fs)
            fs, ds, paths = copy_fs(fs, tdir.name)
            instance = fs._instances[-1]
            # Was written with alphanumeric File IDs
            assert "IM00001D" in instance.path
        
            def my_len(self):
                return 36**6 + 1
        
            FileSet.__len__ = my_len
            fs = FileSet(tiny)
    >       assert 36**6 + 1 == len(fs)
    E       OverflowError: cannot fit 'int' into an index-sized integer
    
    pydicom/tests/test_fileset.py:2580: OverflowError
    

    Your environment

    module       | version
    ------       | -------
    platform     | Linux-6.0.7-i686-with-glibc2.33
    Python       | 3.9.9 (main, Jan  1 1970, 00:00:01)  [GCC 10.3.0]
    pydicom      | 2.3.1
    gdcm         | _module not found_
    jpeg_ls      | _module not found_
    numpy        | 1.21.6
    PIL          | 9.2.0
    pylibjpeg    | _module not found_
    openjpeg     | _module not found_
    libjpeg      | _module not found_
    
    opened by antero-0 1
  • Tags duplication in meta and in DCM body

    Tags duplication in meta and in DCM body

    Hello! I came across this problem with a particular DICOM file. The 0002,0010 tag occurs twice in the dataset.

    image

    If you do:

    ds = pydicom.dcmread('badTSUID.dcm')
    print(ds.file_meta.TransferSyntaxUID)
    

    The output will be:

    1.2.840.10008.1.2.1
    

    If you do:

    del ds.file_meta.TransferSyntaxUID
    

    Both of the tags are deleted.

    In this particular case the one that's in the file meta should be trusted. I could use the del to delete them both and rewrite, but to do that I need to know the value of the tag in Meta to write the correct one. I am not sure how to deal with this kind of cases correctly. I've attached the anonymized dataset to this message. Thank you! badTSUID.zip

    opened by alipairon 5
  • DS.save_as after ds.decode() exception

    DS.save_as after ds.decode() exception

    Describe the bug There is a file = filename The filename tag SpecificCharacterSet = ISO_IR 144

    ds = dcmread(filename) ds.decode() ds['SpecificCharacterSet'].value = 'ISO_IR 192' ds.save_as(fileout)

    Causes an exception: UnicodeEncodeError: 'latin-1' codec can't encode character '\u044d' in position 0: ordinal not in range(256)

    I understand that there is the wrong symbol somewhere in the tags causing the exception but I dunno where.

    Doing:

    ds = dcmread(filename) ds.save_as(fileout)

    Causes no error.

    What is the best way to catch exceptions like this one? It's totally unpredictable in my datasets.

    opened by alipairon 8
  • Codify incorrect AT values

    Codify incorrect AT values

    The codify engine will produce code with incorrect AT values:

    from pydicom import Dataset
    from pydicom.util.codify import code_dataset
    
    ds = Dataset()
    ds.OffendingElement = (0x00aa, 0x00bb)
    
    print(code_dataset(ds))
    

    gives output:

    ds = Dataset()
    ds.OffendingElement = (00aa, 00bb)
    

    It is missing the leading "0x" on each value to indicate they are hex. In this case, it generates a syntax error; in some cases it could pass but be incorrect, if there were no leading 00's and no letter characters in the hex numbers.

    bug Difficulty-Easy 
    opened by darcymason 0
  • Circular import while using pydicom with multiprocessing

    Circular import while using pydicom with multiprocessing

    Describe the bug When importing pydicom with a multi process program, a circular import happens. The stack trace is the following:

    multiprocessing.managers.RemoteError: 
    ---------------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python3.8/multiprocessing/managers.py", line 243, in serve_client
        request = recv()
      File "/usr/lib/python3.8/multiprocessing/connection.py", line 251, in recv
        return _ForkingPickler.loads(buf.getbuffer())
      File "/home/romain/Documents/.env/lib/python3.8/site-packages/pydicom/__init__.py", line 35, in <module>
        from pydicom.filewriter import dcmwrite, write_file
      File "/home/romain/Documents/.env/lib/python3.8/site-packages/pydicom/filewriter.py", line 23, in <module>
        from pydicom.values import convert_numbers
      File "/home/romain/Documents/.env/lib/python3.8/site-packages/pydicom/values.py", line 621, in <module>
        ) -> Union[pydicom.uid.UID, SequenceType[pydicom.uid.UID]]:
    AttributeError: partially initialized module 'pydicom' has no attribute 'uid' (most likely due to a circular import)
    ---------------------------------------------------------------------------
    

    The error occurs in multiple process, sometimes with the following:

      File "/home/romain/Documents/.env/lib/python3.8/site-packages/pydicom/dataelem.py", line 31, in <module>
        from pydicom.valuerep import PersonName
    ImportError: cannot import name 'PersonName' from partially initialized module 'pydicom.valuerep' (most likely due to a circular import)
    

    Expected behavior The import should take place without error.

    Steps To Reproduce The bug is hard to reproduce, I'm using a library that I can't share, but we only do a import pydicom. I have not been able to reproduce the bug in a simple way for it to happen every time, it can be random or occur every time when changing an unrelated file. If anyone has an idea to reproduce it, I'm willing to try.

    Your environment module | version ------ | ------- platform | Linux-5.10.16.3-microsoft-standard-WSL2-x86_64-with-glibc2.29 Python | 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0] pydicom | 2.1.2 gdcm | module not found jpeg_ls | module not found numpy | 1.22.3 PIL | 9.0.1

    opened by romainhild-ge 2
Releases(v2.3.1)
Owner
DICOM in Python
development for software, modules, and containers for dicom applications that use Python
DICOM in Python
useful files for the Freenove Big Hexapod

FreenoveBigHexapod useful files for the Freenove Big Hexapod HexaDogPos is a utility for converting the Freenove xyz co-ordinate system to servo angle

Alex 2 May 28, 2022
Read and write TIFF files

Read and write TIFF files Tifffile is a Python library to store numpy arrays in TIFF (Tagged Image File Format) files, and read image and metadata fro

Christoph Gohlke 346 Dec 18, 2022
A wrapper for DVD file structure and ISO files.

vs-parsedvd DVDs were an error. A wrapper for DVD file structure and ISO files. You can find me in the IEW Discord server

7 Nov 17, 2022
Better directory iterator and faster os.walk(), now in the Python 3.5 stdlib

scandir, a better directory iterator and faster os.walk() scandir() is a directory iteration function like os.listdir(), except that instead of return

Ben Hoyt 506 Dec 29, 2022
An object-oriented approach to Python file/directory operations.

Unipath An object-oriented approach to file/directory operations Version: 1.1 Home page: https://github.com/mikeorr/Unipath Docs: https://github.com/m

Mike Orr 506 Dec 29, 2022
organize - The file management automation tool

organize - The file management automation tool

Thomas Feldmann 1.5k Jan 01, 2023
Uproot is a library for reading and writing ROOT files in pure Python and NumPy.

Uproot is a library for reading and writing ROOT files in pure Python and NumPy. Unlike the standard C++ ROOT implementation, Uproot is only an I/O li

Scikit-HEP Project 164 Dec 31, 2022
Python codes for the server and client end that facilitates file transfers. (Using AWS EC2 instance as the server)

Server-and-Client-File-Transfer Python codes for the server and client end that facilitates file transfers. I will be using an AWS EC2 instance as the

Amal Farhad Shaji 2 Oct 13, 2021
Python library for reading and writing tabular data via streams.

tabulator-py A library for reading and writing tabular data (csv/xls/json/etc). [Important Notice] We have released Frictionless Framework. This frame

Frictionless Data 231 Dec 09, 2022
Organizer is a python program that organizes your downloads folder

Organizer Organizer is a python program that organizes your downloads folder, it can run as a service and so will start along with the system, and the

Gustavo 2 Oct 18, 2021
LightCSV - This CSV reader is implemented in just pure Python.

LightCSV Simple light CSV reader This CSV reader is implemented in just pure Python. It allows to specify a separator, a quote char and column titles

Jose Rodriguez 6 Mar 05, 2022
Maltego transforms to pivot between PE files based on their VirusTotal codeblocks

VirusTotal Codeblocks Maltego Transforms Introduction These Maltego transforms allow you to pivot between different PE files based on codeblocks they

Ariel Jungheit 18 Feb 03, 2022
Transforme rapidamente seu arquivo CSV (de qualquer tamanho) para SQL de forma rápida.

Transformador de CSV para SQL Transforme rapidamente seu arquivo CSV (de qualquer tamanho) para SQL de forma rápida, e com isso insira seus dados usan

William Rodrigues 4 Oct 17, 2022
CleverCSV is a Python package for handling messy CSV files.

CleverCSV is a Python package for handling messy CSV files. It provides a drop-in replacement for the builtin CSV module with improved dialect detection, and comes with a handy command line applicati

The Alan Turing Institute 1k Dec 19, 2022
A Python script to backup your favorite Discord gifs

About the project Discord recently felt like it would be a good idea to limit the favorites to 250, which made me lose most of my gifs... Luckily for

4 Aug 03, 2022
Python library and shell utilities to monitor filesystem events.

Watchdog Python API and shell utilities to monitor file system events. Works on 3.6+. If you want to use Python 2.6, you should stick with watchdog

Yesudeep Mangalapilly 5.6k Jan 04, 2023
Python function to construct a ZIP archive with on the fly - without having to store the entire ZIP in memory or disk

Python function to construct a ZIP archive with on the fly - without having to store the entire ZIP in memory or disk

Department for International Trade 34 Jan 05, 2023
Lumar - Smart File Creator

Lumar is a free tool for creating and managing files. With Lumar you can quickly create any type of file, add a file content and file size. With Lumar you can also find out if Photoshop or other imag

Paul - FloatDesign 3 Dec 10, 2021
Python Fstab Generator is a small Python script to write and generate /etc/fstab files based on yaml file on Unix-like systems.

PyFstab Generator PyFstab Generator is a small Python script to write and generate /etc/fstab files based on yaml file on Unix-like systems. NOTE : Th

Mahdi 2 Nov 09, 2021
File-manager - A basic file manager, written in Python

File Manager A basic file manager, written in Python. Installation Install Pytho

Samuel Ko 1 Feb 05, 2022