Skip to content
Snippets Groups Projects
Commit e0d463db authored by Tamino Huxohl's avatar Tamino Huxohl
Browse files

move function of data/dicom_util to file/dicom

parent 47350717
No related branches found
No related tags found
No related merge requests found
from datetime import datetime
from enum import Enum
import pydicom
class DICOMTime(Enum):
Study = 1
Series = 2
Acquisition = 3
Content = 4
def date_field(self):
return f"{self.name}Date"
def time_field(self):
return f"{self.name}Time"
def to_datetime(self, dicom: pydicom.dataset.FileDataset) -> datetime:
_date = dicom[self.date_field()].value
_time = dicom[self.time_field()].value
return datetime(
year=int(_date[0:4]),
month=int(_date[4:6]),
day=int(_date[6:8]),
hour=int(_time[0:2]),
minute=int(_time[2:4]),
second=int(_time[4:6]),
# microsecond=int(_time.split(".")[1]),
)
def parse_age(patient_age: str) -> int:
"""
Parse an age string as defined in the DICOM standard into an integer representing the age in years.
:param patient_age: age string as defined in the DICOM standard
:return: the age in years as a number
"""
assert (
type(patient_age) == str
), f"patient age needs to be a string and not {type(patient_age)}"
assert (
len(patient_age) == 4
), f"patient age [{patient_age}] has to be four characters long"
_num, _format = patient_age[:3], patient_age[3]
assert (
_format == "Y"
), f"currently, only patient ages in years [Y] is supported, not [{_format}]"
return int(_num)
......@@ -8,7 +8,7 @@ import numpy as np
import pandas as pd
import pydicom
from mu_map.data.dicom_util import DICOMTime, parse_age
from mu_map.file.dicom import DICOMTime, parse_age
from mu_map.logging import add_logging_args, get_logger_by_args
......
from datetime import datetime
from enum import Enum
import random
from typing import Tuple
......@@ -29,6 +31,69 @@ Default extension of dicom files.
EXTENSION_DICOM = ".dcm"
class DICOMTime(Enum):
"""
Class for parsing dates and times defined in a DICOM header
into a python datetime type. It maps the four datetime fields
[Study, Series, Acquisition, Content] of the DICOM header into
an enumeration type.
Usage: DICOMTime.Series.to_datetime(dcm)
"""
Study = 1
Series = 2
Acquisition = 3
Content = 4
def date_field(self) -> str:
"""
Get the name of the date field according to this DICOMTime type.
"""
return f"{self.name}Date"
def time_field(self) -> str:
"""
Get the name of the time field according to this DICOMTime type.
"""
return f"{self.name}Time"
def to_datetime(self, dicom: dcm_type) -> datetime:
"""
Get the datetime according to this DICOMTime type.
"""
_date = dicom[self.date_field()].value
_time = dicom[self.time_field()].value
return datetime(
year=int(_date[0:4]),
month=int(_date[4:6]),
day=int(_date[6:8]),
hour=int(_time[0:2]),
minute=int(_time[2:4]),
second=int(_time[4:6]),
)
def parse_age(patient_age: str) -> int:
"""
Parse an age string as defined in the DICOM standard into an integer representing the age in years.
:param patient_age: age string as defined in the DICOM standard
:return: the age in years as a number
"""
assert (
type(patient_age) == str
), f"patient age needs to be a string and not {type(patient_age)}"
assert (
len(patient_age) == 4
), f"patient age [{patient_age}] has to be four characters long"
_num, _format = patient_age[:3], patient_age[3]
assert (
_format == "Y"
), f"currently, only patient ages in years [Y] is supported, not [{_format}]"
return int(_num)
def load_dcm(filename: str) -> Tuple[pydicom.dataset.FileDataset, np.ndarray]:
"""
Load a DICOM image, the data as a numpy array and apply normalization of the Siemens SPECT/CT
......@@ -69,7 +134,7 @@ def scale_image(image: np.ndarray, initial_scale=10000000) -> Tuple[np.ndarray,
is smaller than the maximum uint16 number
:return: the image scaled and converted to uint16 as well as the used scaling factor
"""
if image.min() < 0.0:
if image.min() < 0.0:
raise ValueError("Cannot scale images with negative values!")
scale = initial_scale
......@@ -121,15 +186,25 @@ def change_uid(dcm: pydicom.dataset.FileDataset) -> pydicom.dataset.FileDataset:
:param dcm: the DICOM file to be udpated
:return: the DICOM file with updated UIDs
"""
dcm.SeriesInstanceUID = UID_PREFIX + str(random.randint(10000000000000, 99999999999999))
dcm.SOPInstanceUID = UID_PREFIX + str(random.randint(10000000000000, 99999999999999))
dcm.SeriesInstanceUID = UID_PREFIX + str(
random.randint(10000000000000, 99999999999999)
)
dcm.SOPInstanceUID = UID_PREFIX + str(
random.randint(10000000000000, 99999999999999)
)
return dcm
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Dump the header of a DICOM image", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("file", type=str, help="the DICOM file of which the header is dumped")
parser = argparse.ArgumentParser(
description="Dump the header of a DICOM image",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"file", type=str, help="the DICOM file of which the header is dumped"
)
args = parser.parse_args()
dcm = pydicom.dcmread(args.file)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment