Skip to content

Commit 4054cab

Browse files
committed
Set AnnotationAppliesToAllZPlanes only for 3D Annotation Groups
1 parent b2fe388 commit 4054cab

2 files changed

Lines changed: 106 additions & 1 deletion

File tree

src/highdicom/ann/content.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,8 @@ def __init__(
387387
])
388388
self.LongPrimitivePointIndexList = point_indices.tobytes()
389389

390-
self.AnnotationAppliesToAllZPlanes = 'NO'
390+
if coordinate_type == AnnotationCoordinateTypeValues.SCOORD3D:
391+
self.AnnotationAppliesToAllZPlanes = 'NO'
391392
self.AnnotationAppliesToAllOpticalPaths = 'YES'
392393

393394
if measurements is not None:

tests/test_ann.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ def test_construction(self):
185185
assert group.anatomic_regions[0] == self._anatomic_region
186186
assert len(group.PrimaryAnatomicStructureSequence) == 1
187187
assert group.primary_anatomic_structures[0] == self._anatomic_structure
188+
assert group.CommonZCoordinateValue == 0.0
189+
assert hasattr(group, 'AnnotationAppliesToAllZPlanes')
188190

189191
decoded_graphic_data = group.get_graphic_data(coordinate_type='3D')
190192
assert len(decoded_graphic_data) == len(graphic_data)
@@ -231,6 +233,108 @@ def test_construction(self):
231233
assert values.dtype == np.float32
232234
assert values.shape == (2, 0)
233235

236+
def test_construction_2d(self):
237+
number = 1
238+
label = 'first'
239+
uid = UID()
240+
graphic_type = GraphicTypeValues.POLYGON
241+
graphic_data = [
242+
np.array([
243+
[1.0, 1.0],
244+
[0.5, 3.0],
245+
[1.0, 3.0],
246+
]),
247+
np.array([
248+
[1.0, 1.0],
249+
[1.0, 2.0],
250+
[2.0, 2.0],
251+
[2.0, 1.0],
252+
]),
253+
]
254+
255+
measurement_values = np.array([[0.5], [1.0]])
256+
measurement_names = [codes.SCT.Area]
257+
measurement_units = [codes.UCUM.SquareMicrometer]
258+
measurements = [
259+
Measurements(
260+
name=measurement_names[0],
261+
unit=measurement_units[0],
262+
values=measurement_values
263+
),
264+
]
265+
266+
group = AnnotationGroup(
267+
number=number,
268+
uid=uid,
269+
label=label,
270+
annotated_property_category=self._property_category,
271+
annotated_property_type=self._property_type,
272+
graphic_type=graphic_type,
273+
graphic_data=graphic_data,
274+
algorithm_type=self._algorithm_type,
275+
algorithm_identification=self._algorithm_identification,
276+
measurements=measurements,
277+
description='annotation',
278+
anatomic_regions=[self._anatomic_region],
279+
primary_anatomic_structures=[self._anatomic_structure]
280+
)
281+
282+
assert group.graphic_type == graphic_type
283+
assert group.annotated_property_category == self._property_category
284+
assert group.annotated_property_type == self._property_type
285+
assert group.algorithm_type == self._algorithm_type
286+
assert group.algorithm_identification == self._algorithm_identification
287+
assert group.anatomic_regions[0] == self._anatomic_region
288+
assert len(group.PrimaryAnatomicStructureSequence) == 1
289+
assert group.primary_anatomic_structures[0] == self._anatomic_structure
290+
assert not hasattr(group, 'CommonZCoordinateValue')
291+
assert not hasattr(group, 'AnnotationAppliesToAllZPlanes')
292+
293+
decoded_graphic_data = group.get_graphic_data(coordinate_type='2D')
294+
assert len(decoded_graphic_data) == len(graphic_data)
295+
for i in range(len(decoded_graphic_data)):
296+
np.testing.assert_allclose(
297+
decoded_graphic_data[i],
298+
graphic_data[i]
299+
)
300+
np.testing.assert_allclose(
301+
group.get_coordinates(annotation_number=1, coordinate_type='2D'),
302+
graphic_data[0]
303+
)
304+
np.testing.assert_allclose(
305+
group.get_coordinates(annotation_number=2, coordinate_type='2D'),
306+
graphic_data[1]
307+
)
308+
309+
names, values, units = group.get_measurements()
310+
assert len(names) == 1
311+
assert names[0] == measurement_names[0]
312+
assert len(units) == 1
313+
assert units[0] == measurement_units[0]
314+
assert values.dtype == np.float32
315+
assert values.shape == (2, 1)
316+
np.testing.assert_allclose(values, measurement_values)
317+
318+
names, values, units = group.get_measurements(
319+
name=measurement_names[0]
320+
)
321+
assert len(names) == 1
322+
assert names[0] == measurement_names[0]
323+
assert len(units) == 1
324+
assert units[0] == measurement_units[0]
325+
assert values.dtype == np.float32
326+
assert values.shape == (2, 1)
327+
np.testing.assert_allclose(values, measurement_values)
328+
329+
names, values, units = group.get_measurements(
330+
name=codes.SCT.Volume
331+
)
332+
assert names == []
333+
assert units == []
334+
assert values.size == 0
335+
assert values.dtype == np.float32
336+
assert values.shape == (2, 0)
337+
234338
def test_alternative_construction_from_dataset(self):
235339
coordinates_data = np.array(
236340
[1.0, 1.0, 2.0, 2.0, 3.0, 3.0],

0 commit comments

Comments
 (0)