From 9f2f51c8d8dc797e937a6e9e63665d48f8ad3643 Mon Sep 17 00:00:00 2001 From: Alan Kuurstra Date: Wed, 18 Sep 2024 15:17:44 -0400 Subject: [PATCH] pass tox tests --- heudiconv/tests/test_utils.py | 4 ++-- heudiconv/utils.py | 36 +++++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/heudiconv/tests/test_utils.py b/heudiconv/tests/test_utils.py index bc7c0b40..d9083364 100644 --- a/heudiconv/tests/test_utils.py +++ b/heudiconv/tests/test_utils.py @@ -229,7 +229,7 @@ def test_strptime_dcm_da_tm(tm: str, tm_fmt: str, offset: str, offset_fmt: str) da_fmt = "%Y%m%d" target = datetime.strptime(da + tm + offset, da_fmt + tm_fmt + offset_fmt) ds = dcm.dataset.Dataset() - ds["AcquisitionDate"] = dcm.DataElement("AcquisitionDate","DA",da) + ds["AcquisitionDate"] = dcm.DataElement("AcquisitionDate", "DA", da) ds["AcquisitionTime"] = dcm.DataElement("AcquisitionTime", "TM", tm) if offset: ds[(0x0008, 0x0201)] = dcm.DataElement((0x0008, 0x0201), "SH", offset) @@ -269,7 +269,7 @@ def test_strptime_dcm_dt(dt: str, dt_fmt: str, offset: str, offset_fmt: str) -> else: target = datetime.strptime(dt + offset, dt_fmt + offset_fmt) ds = dcm.dataset.Dataset() - ds["AcquisitionDateTime"] = dcm.DataElement("AcquisitionDateTime","DT", dt) + ds["AcquisitionDateTime"] = dcm.DataElement("AcquisitionDateTime", "DT", dt) if offset: ds[(0x0008, 0x0201)] = dcm.DataElement((0x0008, 0x0201), "SH", offset) assert strptime_dcm_dt(ds, "AcquisitionDateTime") == target diff --git a/heudiconv/utils.py b/heudiconv/utils.py index 4e6661b4..92f3944b 100644 --- a/heudiconv/utils.py +++ b/heudiconv/utils.py @@ -670,7 +670,7 @@ def get_datetime(date: str, time: str, *, microseconds: bool = True) -> str: return datetime_str -def strptime_micr(date_string: str, fmt: str) -> datetime: +def strptime_micr(date_string: str, fmt: str) -> datetime.datetime: r""" Decorate strptime while supporting optional [.%f] in the format at the end @@ -691,15 +691,20 @@ def strptime_micr(date_string: str, fmt: str) -> datetime: return datetime.datetime.strptime(date_string, fmt) -def datetime_utc_offset(datetime_obj: datetime, utc_offset: str): +def datetime_utc_offset(datetime_obj: datetime.datetime, utc_offset: str) -> datetime.datetime: """set the datetime's tzinfo by parsing an utc offset string""" - sign, hours, minutes = re.match(r"([+\-]?)(\d{2})(\d{2})", utc_offset).groups() + # https://dicom.innolitics.com/ciods/electromyogram/sop-common/00080201 + extract_offset = re.match(r"([+\-]?)(\d{2})(\d{2})", utc_offset) + if extract_offset is None: + raise ValueError(f"utc offset {utc_offset} is not valid") + sign, hours, minutes = extract_offset.groups() sign = -1 if sign == '-' else 1 hours, minutes = int(hours), int(minutes) tzinfo = datetime.timezone(sign * datetime.timedelta(hours=hours, minutes=minutes)) return datetime_obj.replace(tzinfo=tzinfo) -def strptime(datetime_string: str, fmts: list[str]) -> datetime: + +def strptime(datetime_string: str, fmts: list[str]) -> datetime.datetime: r""" Try datetime.strptime on a list of formats returning the first successful attempt. @@ -718,7 +723,8 @@ def strptime(datetime_string: str, fmts: list[str]) -> datetime: pass raise ValueError(f"Unable to parse datetime string: {datetime_str}") -def strptime_bids(datetime_string: str) -> datetime: + +def strptime_bids(datetime_string: str) -> datetime.datetime: r""" Create a datetime object from a bids datetime string. @@ -732,7 +738,8 @@ def strptime_bids(datetime_string: str) -> datetime: datetime_obj = strptime(datetime_string, fmts) return datetime_obj -def strptime_dcm_da_tm(dcm_data: dcm.Dataset, da_tag: TagType, tm_tag: TagType) -> datetime: + +def strptime_dcm_da_tm(dcm_data: dcm.Dataset, da_tag: TagType, tm_tag: TagType) -> datetime.datetime: r""" Create a datetime object from a dicom DA tag and TM tag. @@ -756,12 +763,13 @@ def strptime_dcm_da_tm(dcm_data: dcm.Dataset, da_tag: TagType, tm_tag: TagType) datetime_obj = datetime.datetime.combine(date.date(), time.time()) - if utc_offset_dcm := dcm_data.get([0x0008, 0x0201]): + if utc_offset_dcm := dcm_data.get((0x0008, 0x0201)): utc_offset = utc_offset_dcm.value.strip() datetime_obj = datetime_utc_offset(datetime_obj, utc_offset) if utc_offset else datetime_obj return datetime_obj -def strptime_dcm_dt(dcm_data: dcm.Dataset, dt_tag: TagType) -> datetime: + +def strptime_dcm_dt(dcm_data: dcm.Dataset, dt_tag: TagType) -> datetime.datetime: r""" Create a datetime object from a dicom DT tag. @@ -779,13 +787,13 @@ def strptime_dcm_dt(dcm_data: dcm.Dataset, dt_tag: TagType) -> datetime: "%Y", "%Y%m", "%Y%m%d", "%Y%m%d%H", "%Y%m%d%H%M", "%Y%m%d%H%M%S", "%Y%m%d%H%M%S.%f"] datetime_obj = strptime(datetime_str, fmts) - if utc_offset_dcm := dcm_data.get([0x0008, 0x0201]): + if utc_offset_dcm := dcm_data.get((0x0008, 0x0201)): if utc_offset := utc_offset_dcm.value.strip(): - datetime_obj2 = datetime_utc_offset(datetime_obj, utc_offset) - if datetime_obj.tzinfo and datetime_obj2 != datetime_obj: - lgr.warning("Unexpectedly previously parsed datetime %s contains zoneinfo which is different from the one obtained from DICOMs UTFOffset field: %s", datetime_obj, datetime_obj2) - else: - datetime_obj = datetime_obj2 + datetime_obj2 = datetime_utc_offset(datetime_obj, utc_offset) + if datetime_obj.tzinfo and datetime_obj2 != datetime_obj: + lgr.warning("Unexpectedly previously parsed datetime %s contains zoneinfo which is different from the one obtained from DICOMs UTFOffset field: %s", datetime_obj, datetime_obj2) + else: + datetime_obj = datetime_obj2 return datetime_obj