Reading Header Information¶
django_dicom uses the dicom_parser package to read header information and
store it as an Header
instance. Some
information is already available to us directly through the values stored in
the associated
Image
,
Series
,
Patient
, and
Study
instances. However,
Header
instances are collections of
DataElement
instances, each
storing a queryable reference to both the raw and parsed values of a given
data element.
By defualt, django_dicom will store all official DICOM tags, skipping any private data elements. These will still be easily readable, however, we will not be able to query them from the database. For more information about import modes, see Import Modes.
Reading a Single Image’s Header¶
To read a single Image
instance’s header,
we can simply use the instance
property
to retrieve dicom_parser’s representation of a DICOM image (
Image
):
>>> from django_dicom.models import Image
>>> image = Image.objects.first()
>>> image.instance.header
Keyword VR VM Value
Tag
(0008, 0005) SpecificCharacterSet Code String 1 ISO_IR 100
(0008, 0008) ImageType Code String 5 ['ORIGINAL', 'PRIMARY', ...
(0008, 0012) InstanceCreationDate Date 1 2019-12-18
(0008, 0013) InstanceCreationTime Time 1 08:54:41.479000
(0008, 0016) SOPClassUID Unique Identifer 1 1.2.840.10008.5.1.4.1.1.4
(0008, 0018) SOPInstanceUID Unique Identifer 1 1.3.12.2.1107.5.2.43.660...
(0008, 0020) StudyDate Date 1 2019-12-18
...
Private Data Elements
=====================
Keyword VR VM Value
Tag
(0019, 0010) Long String 1 SIEMENS MR HEADER
(0019, 1008) CsaImageHeaderType Unknown 1 b'IMAGE NUM 4 '
(0019, 1009) CsaImageHeaderVersion?? Unknown 1 b'1.0 '
(0019, 100b) SliceMeasurementDuration Unknown 1 3535
...
>>> image.instance.header.get('PixelSpacing')
[0.48828125, 0.48828125]
For more information on dicom_parser’s classes and functionality, see the documentation.
Querying the Database¶
According to the chosen import mode,
no, some, or all of the saved images’ data elements will be serialized to the
database as DataElement
instances.
Each DataElement
represents a single
tag within a single header, however, the actual information is available its
definition
and
value
attributes.
These attributes associate the
DataElement
instance with reusable
DataElementDefinition
and DataElementValue
instances,
thereby preventing data duplication simplifying queries.
To better understand the way header information is serialized in the database,
let’s query all the Series
instances in
which the underlying image headers contain a data element named ImageType
which contains a value of MOSAIC.
First, we’ll have a look at the relevant
DataElementDefinition
instance:
>>> from django_dicom.models import DataElementDefinition
>>> definition = DataElementDefinition.objects.get(keyword="ImageType")
>>> definition
<DataElementDefinition:
Tag (0008, 0008)
Keyword ImageType
Value Representation CS
Description Image Type>
Now, let’s select any
DataElementValue
instances
satisfying our condition:
>>> from django_dicom.models import CodeString
>>> values = CodeString.objects.filter(value="MOSAIC")
>>> values.count()
9
This means there are 9 different distinct ImageType values that contain the
string MOSAIC. If we want all the related
DataElement
instances, we could:
>>> from django_dicom.models import DataElement
>>> data_elements = DataElement.objects.filter(definition=definition, _values__in=values)
>>> data_elements.count()
42236
Two important things to note here:
- We used the
_values
attribute to access the raw relationship between theDataElement
and its associatedDataElementValue
s.- We used __in to query this ManyToMany relationship and retrieve data elements containing any of the desired values. This is necessary because DICOM elements may have multiple values (for more information see value multiplicity).
Now, if we would like to query all the images to which these data elements belong:
>>> image_ids = data_elements.values_list('header__image', flat=True)
>>> images = Image.objects.filter(id__in=image_ids)
or the series:
>>> from django_dicom.models import Series
>>> series_ids = images.values_list('series', flat=True)
>>> series = Series.objects.filter(id__in=series_ids)
>>> series.count()
409
>>> series.first().description
'IR-DTI_30dir_3iso'