Можно ли получить доступ к тегам pydicom посредством точечной нотации? - PullRequest
0 голосов
/ 21 марта 2019

Очень простые pydicom примеры включают чтение файла с последующим выводом Series Time:

import pydicom
info = pydicom.dcmread("file.dcm")
print(info.SeriesTime)

Так что для прочитанного объекта точечная нотация является рабочей альтернативой более сложным конструкциям, таким каккак print(info[pydicom.tag.Tag((0x0008, 0x0031))]) или print(info[0x0008, 0x0031]).Хорошо.

Теперь pydicom поддерживает чтение только некоторых тегов для повышения производительности:

info = pydicom.dcmread("file.dcm", specific_tags=['SeriesTime', ])

Мне не нравится использование строковых констант в коде.Так что же является читабельной альтернативой 'SeriesTime' в приведенном выше примере?specific_tags=[pydicom.tag.Tag((0x0008, 0x0031)), ] не особо удобочитаем.

В идеале я хотел бы получить доступ к словарю тегов с помощью точечной нотации, например pydicom.allTags.SeriesTime, но, похоже, я не могу этого найти.

Ответы [ 2 ]

1 голос
/ 23 марта 2019

Вот еще один относительно короткий способ получить точечный доступ к словарю pydicom:

from pydicom.datadict import tag_for_keyword
from pydicom.tag import Tag

class DottedDcmDict(object):
    def __getattr__(self, name):
        tag = tag_for_keyword(name)
        if tag:
            return Tag(tag)
        raise AttributeError("Not a valid DICOM identifier")

dd = DottedDcmDict()
print(dd.SeriesTime)
(0008, 0031)

1 голос
/ 22 марта 2019

То, что вы ищете, это словарь данных. В Pydicom вы можете найти его здесь: pydicom.datadict.DicomDictionary но это диктат кортежей, который на самом деле не подходит для доступа с помощью точечной нотации. Например, чтобы получить 'SeriesTime', вам нужно написать pydicom.datadict.DicomDictionary[524337][4], который не может быть прочитан или гарантированно останется действительным при обновлениях Pydicom (хотя я сомневаюсь, что он будет часто меняться, если вообще будет).

Вы можете реализовать это самостоятельно, используя именованный кортеж:

from collections import namedtuple
import pydicom

def get_dict_as_namedtuple(pdict):
    # some keywords are empty, check for those
    keywords_list = [pdict[i][4] for i in pdict if pdict[i][4].strip() != '']
    Keywords = namedtuple('Keywords', keywords_list)
    # unpack the list as positional arguments
    return Keywords(*keywords_list)

dicom_tags = get_dict_as_namedtuple(pydicom.datadict.DicomDictionary)

print(dicom_tags.SeriesTime)
# prints 'SeriesTime'

Или мое первоначальное, менее изящное решение (автозаполнение вкладок у меня не работает с этим решением):
(пример кода для AttributeDict из кодовой базы Fabric найден через этот ответ )

import pydicom
class AttributeDict(dict):

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            # to conform with __getattr__ spec
            raise AttributeError(key)

    def __setattr__(self, key, value):
        self[key] = value

    def first(self, *names):
        for name in names:
            value = self.get(name)
            if value:
                return value

def get_data_dict(pydicom_data_dict):
        data_dict = AttributeDict({})
        for entry in pydicom_data_dict:
            keyword = pydicom_data_dict[entry][4]
            data_dict[keyword] = keyword
        return data_dict

pydicom_data_dict = get_data_dict(pydicom.datadict.DicomDictionary)
print(pydicom_data_dict.SeriesTime)
#prints 'SeriesTime'
...