Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update: pydicom v3 #273

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ jobs:
formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup black environment
run: conda create --quiet --name black black
@@ -26,14 +26,13 @@ jobs:
testing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup conda environment
run: |
conda create --quiet --name testing
export PATH="/usr/share/miniconda/bin:$PATH"
source activate testing
pip install matplotlib
pip install .

- name: Test deid
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are:
Referenced versions in headers are tagged on Github, in parentheses are for pypi.

## [vxx](https://github.com/pydicom/deid/tree/master) (master)
- Update to use pydicom 3 [#267](https://github.com/pydicom/deid/pull/267) (0.4.0)
- Refactor INCLUDE_REQUIRES and provide max pydicom version [#267](https://github.com/pydicom/deid/pull/267) (0.3.25)
- Support pydicom.Dataset objects created from BytesIO [#265](https://github.com/pydicom/deid/pull/265) (0.3.24)
- Exception with missing filters for non-string VR [#256](https://github.com/pydicom/deid/issues/256) (0.3.23)
2 changes: 1 addition & 1 deletion deid/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

from deid.config.standards import actions, formats, sections
2 changes: 1 addition & 1 deletion deid/config/standards.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

# Supported formats
2 changes: 1 addition & 1 deletion deid/config/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

# pylint: skip-file
2 changes: 1 addition & 1 deletion deid/data/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import os
2 changes: 1 addition & 1 deletion deid/dicom/actions/jitter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

from deid.logger import bot
2 changes: 1 addition & 1 deletion deid/dicom/actions/uids.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import uuid
2 changes: 1 addition & 1 deletion deid/dicom/fields.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import re
4 changes: 2 additions & 2 deletions deid/dicom/filter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import re
@@ -23,7 +23,7 @@ def apply_filter(dicom, field, filter_name, value):

Parameters
==========
dicom: the pydicom.dataset Dataset (pydicom.read_file)
dicom: the pydicom.dataset Dataset
field: the name of the field to apply the filter to,
or the tag number as a string '0xGGGGEEEE'
filer_name: the name of the filter to apply (e.g., contains)
2 changes: 1 addition & 1 deletion deid/dicom/groups.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"


7 changes: 3 additions & 4 deletions deid/dicom/header.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"


import os

from pydicom import read_file

import deid.dicom.utils as utils
from deid.dicom.parser import DicomParser
from deid.dicom.utils import save_dicom
from deid.logger import bot
@@ -68,7 +67,7 @@ def remove_private_identifiers(
dicom_files = [dicom_files]

for dicom_file in dicom_files:
dicom = read_file(dicom_file, force=force)
dicom = utils.dcmread(dicom_file, force=force)
dicom.remove_private_tags()
dicom_name = os.path.basename(dicom_file)
bot.debug("Removed private identifiers for %s" % dicom_name)
6 changes: 3 additions & 3 deletions deid/dicom/parser.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import os
import re
from copy import deepcopy
from io import BytesIO

from pydicom import read_file
from pydicom.dataelem import DataElement
from pydicom.dataset import Dataset
from pydicom.tag import Tag

import deid.dicom.utils as utils
from deid.config import DeidRecipe
from deid.config.standards import actions as valid_actions
from deid.dicom.actions import deid_funcs, jitter_timestamp
@@ -99,7 +99,7 @@ def load(self, dicom_file, force=True):
# If we must read the file, the path must exist
if not os.path.exists(dicom_file):
bot.exit("%s does not exist." % dicom_file)
self.dicom = read_file(dicom_file, force=force)
self.dicom = utils.dcmread(dicom_file, force=force)

# Set class variables that might be helpful later
df = self.dicom.get("filename")
5 changes: 2 additions & 3 deletions deid/dicom/pixels/clean.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"


@@ -13,7 +13,6 @@
import matplotlib
import numpy
from numpy.typing import NDArray
from pydicom import read_file
from pydicom.pixel_data_handlers.util import get_expected_length

from deid.config import DeidRecipe
@@ -245,7 +244,7 @@ def save_dicom(self, output_folder=None, image_type="cleaned"):
# Having clean also means has dicom image
if hasattr(self, image_type):
dicom_name = self._get_clean_name(output_folder)
dicom = read_file(self.dicom_file, force=True)
dicom = utils.dcmread(self.dicom_file, force=True)
# If going from compressed, change TransferSyntax
if dicom.file_meta.TransferSyntaxUID.is_compressed is True:
dicom.decompress()
10 changes: 4 additions & 6 deletions deid/dicom/pixels/detect.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"


from typing import List, Optional, Union

from pydicom import FileDataset, read_file
from pydicom import FileDataset
from pydicom.sequence import Sequence

import deid.dicom.utils as utils
from deid.config import DeidRecipe
from deid.dicom.filter import apply_filter
from deid.logger import bot
@@ -111,10 +112,7 @@ def _has_burned_pixels_single(dicom_file, force: bool, deid):
]
}
"""
if isinstance(dicom_file, FileDataset):
dicom = dicom_file
else:
dicom = read_file(dicom_file, force=force)
dicom = utils.load_dicom(dicom_file, force=force)

# Return list with lookup as dicom_file
results = []
8 changes: 4 additions & 4 deletions deid/dicom/tags.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import re
@@ -123,7 +123,7 @@ def update_tag(dicom, field, value):

Parameters
==========
dicom: the pydicom.dataset Dataset (pydicom.read_file)
dicom: the pydicom.dataset Dataset
field: the name of the field to update
value: the value to set, if name is a valid tag

@@ -157,7 +157,7 @@ def get_private(dicom):

Parameters
==========
dicom: the pydicom.dataset Dataset (pydicom.read_file)
dicom: the pydicom.dataset Dataset
"""
datasets = [dicom]
private_tags = []
@@ -188,7 +188,7 @@ def has_private(dicom):

Parameters
==========
dicom: the pydicom.dataset Dataset (pydicom.read_file)
dicom: the pydicom.dataset Dataset

"""
private_tags = len(get_private(dicom))
10 changes: 7 additions & 3 deletions deid/dicom/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import os
@@ -106,8 +106,12 @@ def save_dicom(dicom, dicom_file, output_folder=None, overwrite=False):
return output_dicom


def load_dicom(dcm_file):
def load_dicom(dcm_file, force=True):
if isinstance(dcm_file, FileDataset):
return dcm_file
else:
return pydicom.read_file(dcm_file, force=True)
return pydicom.dcmread(dcm_file, force=force)


def dcmread(filename, **kwargs):
return pydicom.dcmread(filename, **kwargs)
7 changes: 3 additions & 4 deletions deid/dicom/validate.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

from pydicom import read_file

import deid.dicom.utils as utils
from deid.logger import bot


@@ -28,7 +27,7 @@ def validate_dicoms(dcm_files, force=False):
for dcm_file in dcm_files:
try:
with open(dcm_file, "rb") as filey:
read_file(filey, force=force)
utils.dcmread(filey, force=force)
valids.append(dcm_file)
except Exception:
bot.warning("Cannot read input file {0!s}, skipping.".format(dcm_file))
2 changes: 1 addition & 1 deletion deid/logger/message.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"


2 changes: 1 addition & 1 deletion deid/main/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3

__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import argparse
2 changes: 1 addition & 1 deletion deid/main/identifiers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3

__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"


2 changes: 1 addition & 1 deletion deid/main/inspect.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3

__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
__license__ = "MIT"

import datetime
14 changes: 4 additions & 10 deletions deid/tests/Xtest_dicom_header.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
#!/usr/bin/env python

__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2016-2023, Vanessa Sochat"
__license__ = "MIT"


import os
import shutil
import tempfile
import unittest

from deid.data import get_dataset
from deid.dicom import utils
from deid.utils import get_installdir


@@ -47,15 +43,14 @@ def test_get_identifiers(self):

def test_replace_identifiers(self):
print("Testing deid.dicom replace_identifiers")
from pydicom import read_file

from deid.dicom import get_identifiers, replace_identifiers

dicom_files = get_dicom(self.dataset, return_dir=True)
ids = get_identifiers(dicom_files)

# Before blanking, 28 fields don't have blanks
notblanked = read_file(dicom_files[0])
notblanked = utils.dcmread(dicom_files[0])
notblanked_fields = [
x for x in notblanked.dir() if notblanked.get(x) != ""
] # 28
@@ -64,21 +59,20 @@ def test_replace_identifiers(self):
updated_files = replace_identifiers(dicom_files, ids, output_folder=self.tmpdir)

# After replacing only 9 don't have blanks
blanked = read_file(updated_files[0])
blanked = utils.dcmread(updated_files[0])
blanked_fields = [x for x in blanked.dir() if blanked.get(x) != ""]
self.assertTrue(len(blanked_fields) == 9)


def get_dicom(dataset, return_dir=False):
"""helper function to load a dicom"""
from pydicom import read_file

from deid.dicom import get_files

dicom_files = get_files(dataset)
if return_dir:
return list(dicom_files)
return read_file(next(dicom_files))
return utils.dcmread(next(dicom_files))


if __name__ == "__main__":
Loading