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

Add properties and methods to SR content items and templates #69

Closed
wants to merge 114 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
d9784a7
Fix recording of evidence in structured reports
hackermd Apr 29, 2021
f2e8ddf
Increase package version
hackermd Apr 29, 2021
c91d00b
Assert that evidence is provided for references
hackermd May 1, 2021
8e6ad62
Use sets for comparison and avoid duplicates
hackermd May 2, 2021
58351d6
Fix mypy errors
hackermd May 2, 2021
dbe4c77
Add test for report referencing multiple studies
hackermd May 2, 2021
7284f0c
Remove import statement for unused variable
hackermd May 2, 2021
c24d0e0
Add properties to content items
hackermd May 7, 2021
466819c
Fix recording of evidence in structured reports
hackermd Apr 29, 2021
68af856
Use sets for comparison and avoid duplicates
hackermd May 2, 2021
0665672
Fix mypy errors
hackermd May 2, 2021
1e0bb4f
Add test for report referencing multiple studies
hackermd May 2, 2021
9205175
Add properties to content items
hackermd May 7, 2021
da95df2
Merge branch 'feat/sr-content-decoding' of github:mghcomputationalpat…
hackermd May 7, 2021
97622c7
Use datetime workaround for python 3.6 support
hackermd May 7, 2021
0bb3660
Incomplete implementation of image library
hackermd May 9, 2021
0be93c3
Add proporties and methods on SR templates
hackermd May 11, 2021
d3b1fde
Update type of content item property return value
hackermd May 11, 2021
ce92631
Fix alternative construction of sr documents
hackermd May 15, 2021
7ac37ab
Typo in exception message
May 19, 2021
82f8520
Fix recording of evidence in structured reports
hackermd Apr 29, 2021
7340f25
Use sets for comparison and avoid duplicates
hackermd May 2, 2021
e67a7a0
Fix mypy errors
hackermd May 2, 2021
503118c
Add test for report referencing multiple studies
hackermd May 2, 2021
76eb2e8
Add properties to content items
hackermd May 7, 2021
cda1d75
Fix recording of evidence in structured reports
hackermd Apr 29, 2021
0344ea2
Use sets for comparison and avoid duplicates
hackermd May 2, 2021
56b674e
Fix mypy errors
hackermd May 2, 2021
9986b3e
Add test for report referencing multiple studies
hackermd May 2, 2021
ea1aacc
Use datetime workaround for python 3.6 support
hackermd May 7, 2021
8ad116f
Incomplete implementation of image library
hackermd May 9, 2021
625d08b
Add proporties and methods on SR templates
hackermd May 11, 2021
284882d
Update type of content item property return value
hackermd May 11, 2021
682fa4e
Fix alternative construction of sr documents
hackermd May 15, 2021
dd2ce5d
Update package version
hackermd May 19, 2021
8187f5f
Merge branch 'feat/sr-content-decoding' of github:mghcomputationalpat…
hackermd May 19, 2021
a8158ff
Feat/image library entries (#77)
seandoyle Jun 2, 2021
c722722
Fix handling of library entry descriptors
hackermd Jun 3, 2021
81e3cb7
Fix default value for Pixel Origin Intepretation
hackermd Jun 4, 2021
b607a3b
Rename methods for parsing measurement groups
hackermd Jul 1, 2021
da9f066
Fix implementation of content property on SR documents
hackermd Jul 1, 2021
28f804a
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
fbcd5d0
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
fb502ac
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
a6ba143
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
1ff4dc8
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
abf591f
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
909dc49
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
65494fe
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
eac61df
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
9f58e0f
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
a822a2f
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
c7b2a95
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
dc641b4
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
52f63ac
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
1c65b8e
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
d59788b
Fix typo in method name
hackermd Jul 2, 2021
453660c
Merge branch 'feat/sr-content-decoding' of github:mghcomputationalpat…
hackermd Jul 2, 2021
8b6a3c6
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
473cd54
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
12e1e8f
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
aaef0a5
Update tests/test_content.py
hackermd Jul 2, 2021
06d0570
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
bd53fb5
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
3b930aa
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
e2777fd
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
1fa5b8a
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
c40b58f
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
af97b2c
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
20e56ff
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
359f440
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
57c8b77
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
1415660
Update src/highdicom/sr/value_types.py
hackermd Jul 2, 2021
02d455f
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
70a7912
Use constant for code missing in pydicom
hackermd Jul 2, 2021
bdd39ba
Update src/highdicom/sr/templates.py
hackermd Jul 2, 2021
be5c830
Use constant for code missing in pydicom
hackermd Jul 2, 2021
2d448c2
Fix alternative construction of template instances
hackermd Jul 2, 2021
f615e4e
Merge branch 'feat/sr-content-decoding' of github:mghcomputationalpat…
hackermd Jul 2, 2021
f34cfc1
Make value and unit required for NUM content items
hackermd Jul 2, 2021
19dad8f
Update tests for NUM content items
hackermd Jul 2, 2021
8c96ec9
Fix return value type of properties of NUM content item
hackermd Jul 2, 2021
22a54b7
Add qualifier property to NUM content item
hackermd Jul 2, 2021
005fc3d
Return uids of type UID instead of str
hackermd Jul 2, 2021
e8d50a4
Clarify array dimensions in property docstring
hackermd Jul 2, 2021
b5b3f7e
Simplify reshaping of graphic data array
hackermd Jul 2, 2021
d5438cc
Merge branch 'master' into feat/sr-content-decoding
hackermd Jul 2, 2021
bb9fd8e
Add is_root parameter to alternative constructor
hackermd Jul 2, 2021
e1f7caa
Fix unit tests
hackermd Jul 2, 2021
cad8120
Reuse CodedConcept.from_dataset method
hackermd Jul 2, 2021
9297638
Allow constructor of UID to accept a value
hackermd Jul 2, 2021
979e3ae
Return UID instead of str instances
hackermd Jul 2, 2021
7f9f7f4
Return empty list instead of None
hackermd Jul 2, 2021
ed4383b
Fix filtering logic of template methods
hackermd Jul 2, 2021
2ee628b
Refactor detection of measurement groups
hackermd Jul 6, 2021
8ca64c6
Apply suggestions from code review
hackermd Jul 6, 2021
4475f05
Log warning if wrong number of content items
hackermd Jul 6, 2021
ee8baee
Merge branch 'feat/sr-content-decoding' of github:mghcomputationalpat…
hackermd Jul 6, 2021
4824abb
Fix construction of content item from dataset
hackermd Jul 6, 2021
4ff586e
Fix construction of code content item from dataset
hackermd Jul 6, 2021
7c2981f
Add property for temporal range type
hackermd Jul 6, 2021
fc6c95c
Update src/highdicom/sr/templates.py
hackermd Jul 6, 2021
6adbf6a
Use image pixel description instead of pixel data
hackermd Jul 6, 2021
505ea88
Update summary in docstrings
hackermd Jul 8, 2021
9a78df3
Apply suggestions from code review
hackermd Jul 8, 2021
5217b32
Improve docstring of methods
hackermd Jul 8, 2021
0b5ae3d
Move QualitativeEvaluation from content to templates
hackermd Jul 12, 2021
e1c07cd
Fix type of return value of template methods
hackermd Jul 12, 2021
5d5b435
Handle measurements without child items
hackermd Jul 14, 2021
e3f86ad
Remove print statement
hackermd Jul 14, 2021
36a3f70
Add query filters for report methods
hackermd Jul 15, 2021
c9fd35b
Add unit tests for measurement group queries
hackermd Jul 15, 2021
d0ca793
Fix parsing of sr documents
hackermd Jul 15, 2021
3133e70
Remove code for special frame decoding
hackermd Jul 19, 2021
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
135 changes: 132 additions & 3 deletions src/highdicom/sr/value_types.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""DICOM structured reporting content item value types."""
import datetime
from typing import Any, List, Optional, Sequence, Union
from typing import Any, List, Optional, Sequence, Tuple, Union

import numpy as np
from pydicom.dataset import Dataset
Expand Down Expand Up @@ -72,7 +72,7 @@ def name(self) -> CodedConcept:
@property
def value_type(self) -> str:
"""str: type of the content item
(see `highdicom.sr.value_types.ValueTypeValues`)
(see `highdicom.sr.enum.ValueTypeValues`)

"""
return self.ValueType
Expand Down Expand Up @@ -204,6 +204,11 @@ def __init__(
value = CodedConcept(*value)
self.ConceptCodeSequence = [value]

@property
def value(self) -> CodedConcept:
"""highdicom.sr.coding.CodedConcept: coded concept"""
hackermd marked this conversation as resolved.
Show resolved Hide resolved
return self.ConceptCodeSequence[0]


class PnameContentItem(ContentItem):

Expand Down Expand Up @@ -233,6 +238,11 @@ def __init__(
)
self.PersonName = PersonName(value)

@property
def value(self) -> str:
hackermd marked this conversation as resolved.
Show resolved Hide resolved
"""str: person name"""
return self.PersonName


class TextContentItem(ContentItem):

Expand Down Expand Up @@ -262,6 +272,11 @@ def __init__(
)
self.TextValue = str(value)

@property
def value(self) -> str:
"""str: text value"""
return self.TextValue


class TimeContentItem(ContentItem):

Expand Down Expand Up @@ -291,6 +306,23 @@ def __init__(
)
self.Time = TM(value)

@property
def value(self) -> datetime.time:
"""datetime.time: time"""
allowed_formats = [
'%H:%M:%S.%f',
'%H:%M:%S',
'%H:%M',
'%H',
]
for fmt in allowed_formats:
try:
dt = datetime.datetime.strptime(self.Time.isoformat(), fmt)
return dt.time()
except ValueError:
continue
raise ValueError(f'Could not decode time value "{self.Time}"')


class DateContentItem(ContentItem):

Expand Down Expand Up @@ -320,6 +352,12 @@ def __init__(
)
self.Date = DA(value)

@property
def value(self) -> datetime.date:
"""datetime.date: date"""
fmt = '%Y-%m-%d'
return datetime.datetime.strptime(self.Date.isoformat(), fmt).date()


class DateTimeContentItem(ContentItem):

Expand Down Expand Up @@ -349,6 +387,30 @@ def __init__(
)
self.DateTime = DT(value)

@property
def value(self) -> datetime.datetime:
"""datetime.datetime: datetime"""
allowed_formats = [
'%Y-%m-%dT%H:%M:%S.%f%z',
'%Y-%m-%dT%H:%M:%S.%f',
'%Y-%m-%dT%H:%M:%S',
'%Y-%m-%dT%H:%M:%S%z',
'%Y-%m-%dT%H:%M',
'%Y-%m-%dT%H:%M%z',
'%Y-%m-%dT%H',
'%Y-%m-%dT%H%z',
'%Y-%m-%d',
'%Y-%m',
'%Y',
]
for fmt in allowed_formats:
try:
dt = datetime.datetime.strptime(self.DateTime.isoformat(), fmt)
return dt
except ValueError:
continue
raise ValueError(f'Could not decode datetime value "{self.DateTime}"')


class UIDRefContentItem(ContentItem):

Expand Down Expand Up @@ -378,6 +440,11 @@ def __init__(
)
self.UID = value

@property
def value(self) -> str:
hackermd marked this conversation as resolved.
Show resolved Hide resolved
"""str: UID"""
return str(self.UID)


class NumContentItem(ContentItem):

Expand Down Expand Up @@ -452,6 +519,21 @@ def __init__(
'upon creation of NumContentItem.'
)

@property
def value(self) -> Union[int, float]:
"""Union[int, float]: measured value"""
item = self.MeasuredValueSequence[0]
try:
return float(item.FloatingPointValue)
except AttributeError:
return item.NumericValue
hackermd marked this conversation as resolved.
Show resolved Hide resolved

@property
def unit(self) -> CodedConcept:
"""highdicom.sr.coding.CodedConcept: unit"""
item = self.MeasuredValueSequence[0]
return item.MeasurementUnitsCodeSequence[0]
hackermd marked this conversation as resolved.
Show resolved Hide resolved

hackermd marked this conversation as resolved.
Show resolved Hide resolved

class ContainerContentItem(ContentItem):

Expand Down Expand Up @@ -493,6 +575,15 @@ def __init__(
item.TemplateIdentifier = str(template_id)
self.ContentTemplateSequence = [item]

@property
def template_id(self) -> Union[str, None]:
"""Union[str, None]: template identifier"""
try:
item = self.ContentTemplateSequence[0]
return item.TemplateIdentifier
except (AttributeError, IndexError):
return None


class CompositeContentItem(ContentItem):

Expand Down Expand Up @@ -528,6 +619,12 @@ def __init__(
item.ReferencedSOPInstanceUID = str(referenced_sop_instance_uid)
self.ReferencedSOPSequence = [item]

@property
def value(self) -> Tuple[str, str]:
"""Tuple[str, str]: referenced SOP Class UID and SOP Instance UID"""
item = self.ReferencedSOPSequence[0]
return (item.ReferencedSOPClassUID, item.ReferencedSOPInstanceUID)
hackermd marked this conversation as resolved.
Show resolved Hide resolved


class ImageContentItem(ContentItem):

Expand Down Expand Up @@ -579,6 +676,12 @@ def __init__(
item.ReferencedSegmentNumber = referenced_segment_numbers
self.ReferencedSOPSequence = [item]

@property
def value(self) -> Tuple[str, str]:
"""Tuple[str, str]: referenced SOP Class UID and SOP Instance UID"""
item = self.ReferencedSOPSequence[0]
return (item.ReferencedSOPClassUID, item.ReferencedSOPInstanceUID)
hackermd marked this conversation as resolved.
Show resolved Hide resolved


class ScoordContentItem(ContentItem):

Expand Down Expand Up @@ -639,7 +742,7 @@ def __init__(
if graphic_data.shape[0] != 1 or not graphic_data.shape[1] == 2:
raise ValueError(
'Graphic data of a scoord of graphic type "POINT" '
'must be a single (column row) pair in two-dimensional '
'must be a single (column, row) pair in two-dimensional '
'image coordinate space.'
)
elif graphic_type == GraphicTypeValues.CIRCLE:
Expand Down Expand Up @@ -676,6 +779,13 @@ def __init__(
if fiducial_uid is not None:
self.FiducialUID = fiducial_uid

@property
def value(self) -> np.ndarray:
"""numpy.ndarray: spatial coordinates"""
hackermd marked this conversation as resolved.
Show resolved Hide resolved
graphic_data = np.array(self.GraphicData)
n_points = len(graphic_data) / 2
return np.array(np.array_split(graphic_data, n_points))
hackermd marked this conversation as resolved.
Show resolved Hide resolved


class Scoord3DContentItem(ContentItem):

Expand Down Expand Up @@ -758,6 +868,13 @@ def __init__(
if fiducial_uid is not None:
self.FiducialUID = fiducial_uid

@property
def value(self) -> np.ndarray:
"""numpy.ndarray: spatial coordinates"""
graphic_data = np.array(self.GraphicData)
n_points = len(graphic_data) / 3
return np.array(np.array_split(graphic_data, n_points))
hackermd marked this conversation as resolved.
Show resolved Hide resolved


class TcoordContentItem(ContentItem):

Expand Down Expand Up @@ -817,3 +934,15 @@ def __init__(
])
)
)

@property
def value(self) -> Union[List[int], List[float], List[datetime.datetime]]:
"""Union[List[int], List[float], List[datetime.datetime]]: time points
"""
try:
return self.ReferencedSamplePositions
except AttributeError:
try:
return self.ReferencedTimeOffsets
except AttributeError:
return self.ReferencedDateTime
Loading