Skip to content

Commit d2ad159

Browse files
committed
Minor doc fixes
1 parent 08ac7d4 commit d2ad159

2 files changed

Lines changed: 33 additions & 31 deletions

File tree

docs/seg.rst

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ One particularly important characteristic of a segmentation image is its
146146
"Segmentation Type" (0062,0001). There are three options here, contained within
147147
the highdicom enum :class:`highdicom.seg.SegmentationTypeValues`:
148148

149-
- ``"BINARY"`` segmentations stores each segment in a separate set of frames.
149+
- ``"BINARY"`` segmentations store each segment in a separate set of frames.
150150
Within each segment, pixels can only take the value 0 (meaning that the pixel
151151
does not belong to the segment) or 1 (meaning that the pixel does belong to
152152
the segment). Note that although the name may suggest that only one segment
@@ -659,8 +659,9 @@ do:
659659
This removes from you the requirement to ensure that the frames of your
660660
segmentation array are correctly aligned with those from the source images,
661661
removing a common source of error. As long as the affine matrix of the volume
662-
you pass correctly describes the array, a correct segmentation will be
663-
produced regardless of the correspondence with the source images.
662+
you pass correctly describes the position of the pixel array in the
663+
frame-of-reference coordinate system, a correct segmentation will be produced
664+
regardless of the correspondence with the source images.
664665
* It *does not* change the way that the input array is encoded as frames in the
665666
segmentation. Regardless of whether or not you pass a volume or a "plain"
666667
NumPy array, each index down axis 0 of the input array becomes one frame in
@@ -672,11 +673,11 @@ do:
672673
"rearrange" the volume to match the layout of the source images.
673674

674675
Sometimes, you may wish to ensure that the "layout" (i.e. which spatial
675-
direction is used as the frame direction, which as the row direction and which
676+
direction is used as the frame direction, which as the row direction, and which
676677
as the column direction) matches that of the source images, and this may
677678
involve undoing various operations (flips, crops, dimension permutations) that
678679
were done in your analysis pipeline. One common reason for this is that some
679-
viewers will only display the segmentation if is aligned in this way (see
680+
viewers will only display the segmentation if it is aligned in this way (see
680681
:ref:`seg-viewers`). While the segmentation constructor does not handle this
681682
for you, you should be able to use the :meth:`highdicom.Volume.match_geometry`
682683
method to automatically crop/pad/flip/permute your segmentation volume back to
@@ -851,7 +852,7 @@ When creating a Segmentation, various per-frame metadata are placed within the
851852
"Per Frame Functional Groups Sequence" attribute, with one item of this
852853
sequence describing one frame of the Segmentation. Within each item, the
853854
"Derivation Image Sequence" is in particular worth discussing. This sequence
854-
specifies, which frame(s) of the source image (or image series) were used to
855+
specifies, which frames of the source image (or image series) were used to
855856
derive the segmentation frame. The "Derivation Image Sequence" should always be
856857
present but may have length zero.
857858

@@ -871,15 +872,15 @@ whenever it is possible to do so. If you pass a plain NumPy array aligned with
871872
the source images to the Segmentation constructor, this is straightforward. If
872873
instead you pass a :class:`highdicom.Volume` object to the ``pixel_array``
873874
argument, or manually specify the ``plane_positions``, ``plane_orientation``
874-
and/or ``pixel_measures`` argumentsm, ``highdicom`` will attempt to match the
875+
and/or ``pixel_measures`` arguments, ``highdicom`` will attempt to match the
875876
spatial location of the each segmentation frame to those of the source
876877
frames/images, using a small tolerance to allow for small numerical errors.
877878
There are three possibilities here:
878879

879880
- The orientation, spacing and positions of the frames all match. In this case,
880881
the "Derivation Image Sequence" will indicate the matched frames, and further
881-
use the "Spatial Locations Preserved" attribute that there is pixel-for-pixel
882-
alignment.
882+
use the "Spatial Locations Preserved" attribute to communicate that there is
883+
pixel-for-pixel alignment.
883884
- Segmentation frames are related to source frames by only in-plane rotations,
884885
flips, and or/scaling. There is still frame-by-frame correspondence, but no
885886
pixel-for-pixel correspondence. In this situation, the "Derivation Image
@@ -890,7 +891,7 @@ There are three possibilities here:
890891
and/or scaling between source frames and segmentation frames). In this
891892
situation, the "Derivation Image Sequence" is left empty.
892893

893-
If you require the "Derivation Image Sequence" be populated and you are using a
894+
If you require the "Derivation Image Sequence" to be populated and you are using a
894895
:class:`highdicom.Volume` as input to the constructor, follow the method in the
895896
`seg-from-volume`_ section to match the geometry before passing to the constructor.
896897

@@ -1896,7 +1897,7 @@ you are experiencing problems:
18961897
in the documentation for the ``pixel_array`` argument of the
18971898
:class:`highdicom.seg.Segmentation` constructor. Alternatively, consider
18981899
passing a :class:`highdicom.Volume` instead, if that is appropriate in your
1899-
situation, to make this easier (and also check the following point).
1900+
situation, to make this easier (then also check the following point).
19001901
- If you are passing a :class:`highdicom.Volume` to the constructor, make
19011902
sure you use the :class:`highdicom.Volume.match_geometry` method on the
19021903
segmentation volume first, following the explanation in

src/highdicom/seg/sop.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -229,25 +229,26 @@ def __init__(
229229
be a 2D, 3D or 4D numpy array, or an instance of
230230
:class:`highdicom.Volume`.
231231
232-
**Arrangement:** If it is a 2D numpy array, it represents a single
233-
segmentation frame of a single frame image, such as a planar x-ray
234-
or single instance from a CT or MR series. Unless the
235-
``plane_positions`` parameter is specified, it must correspond
236-
pixel-for-pixel with the single source image and it is the caller's
237-
responsibility to ensure this is true.
238-
239-
If it is a 3D or 4D array, it consists of segmentation frames at
240-
multiple spatial positions stacked down the first dimension (axis
241-
0) of the array. If ``plane_positions`` is not specified, there
242-
must be pixel-for-pixel correspondence between frame
243-
``pixel_array[i]`` and ``source_images[i]`` if ``source_images`` is
244-
a series of single-frame images or between ``pixel_array[i]`` and
245-
the frame at ``source_images[0].pixel_array[i]`` if
246-
``source_images`` consists of a single multi-frame image. It is the
247-
caller's responsibility to ensure correct correspondences.
248-
249-
If it is a :class:`highdicom.Volume`, each slice down the first
250-
dimension (axis 0) of the volume's array (i.e.
232+
**Arrangement:** If ``pixel_array`` is a 2D numpy array, it
233+
represents a single segmentation frame of a single frame image,
234+
such as a planar x-ray or single instance from a CT or MR series.
235+
Unless the ``plane_positions`` parameter is specified, it must
236+
correspond pixel-for-pixel with the single source image and it is
237+
the caller's responsibility to ensure this is true.
238+
239+
If ``pixel_array`` is a 3D or 4D array, it consists of segmentation
240+
frames at multiple spatial positions stacked down the first
241+
dimension (axis 0) of the array. If ``plane_positions`` is not
242+
specified, there must be pixel-for-pixel correspondence between
243+
frame ``pixel_array[i]`` and ``source_images[i]`` if
244+
``source_images`` is a series of single-frame images or between
245+
``pixel_array[i]`` and the frame at
246+
``source_images[0].pixel_array[i]`` if ``source_images`` consists
247+
of a single multi-frame image. It is the caller's responsibility to
248+
ensure correct correspondences.
249+
250+
If ``pixel_array`` is a :class:`highdicom.Volume`, each slice down
251+
the first dimension (axis 0) of the volume's array (i.e.
251252
``pixel_array.array[i]`` for each index ``i``) will be included
252253
into the segmentation as a separate frame (or set of frames if
253254
there are multiple segments) but no spatial correspondence between
@@ -288,7 +289,7 @@ def __init__(
288289
singleton first dimension in order to give a 4D array.
289290
290291
For a ``"FRACTIONAL"`` segmentation, a *stacked segments* style
291-
``pixel_array`` may alternatively contain floating point
292+
``pixel_array`` may alternatively contain floating point
292293
values in the range 0.0 to 1.0 (an unsigned integer type
293294
with binary values is still allowed). These values either encode
294295
the probability of a given pixel belonging to the segment (if

0 commit comments

Comments
 (0)