The BodyComposition package can be used to run different pipelines. Pipelines are registred in the pipeline_registry.py file. If a registred pipeline is run, the specific pipeline configuration is loaded from the pipelines directory.
Each pipeline is a sequence of stages that are executed in order as defined in the respective pipeline file.
Each stage is defined as action
, which are classes that are derived from the PipelineAction
class.
At the start of the pipeline, each action class is initialized. The pipeline selects all cases, where all required inputs (defined by the individual actions) are available. Then, for each case, all actions are executed in order. Outputs of actions are available to the next actions in the pipeline using a shared memory dictionary.
While pipelines can be customized by the user, the following methods are readily implemented:
- BodyCompositionFast (default): Segments vertebral bodies using an nnU-Net v2 (ResEncL) model, crops the image in cranio-caudal axis to L2-L4, segments tissue using TotalSegmentator, and exports slice-wise measures for each case as well as mean L3 measures for all cases.
- BodyComposition: Segments vertebral bodies using an nnU-Net v2 (ResEncM) model, segments tissue and bodytrunk using TotalSegmentator, and exports slice-wise measures for each case.
- SarcopeniaTotalSegmentatorFast: Segments the spine using TotalSegmentator, crops the image in cranio-caudal axis to L2-L4, segments tissue using TotalSegmentator, and exports slice-wise measures for each case as well as mean L3 measures for all cases.
- SarcopeniaTotalSegmentator: Segments spine, vertebral bodies, body trunk, tissue and psoas muscle using TotalSegmentator, reduces the labels to the vertebral bodies, and exports slice-wise measures for each case.
- SarcopeniaStanford: Segments the spine using the Comp2Comp Spine Segmentation model, segments vertebral bodies, body trunk and tissue using TotalSegmentator, reduces the labels to the vertebral bodies, and exports slice-wise measures for each case.
- SegmIntVertebrae: Segments the vertebral body using nnU-Net with models described here. Requires
image
being a NIfTI data container andmodel
being a string defining either theResEncM
orResEncL
model. Returns (and optionally saves) the segmentation as a NIfTI data container. - SegmStanfordSpine: Segments the vertebral body using the Comp2Comp Spine Segmentation model. Requires
image
being a NIfTI data container. Returns (and optionally saves) the segmentation as a NIfTI data container. - SegmTotalSegmentator: Segments any structures using the TotalSegmentator. Requires
image
being a NIfTI data container,task
being a string defining the task to be performed (e.g., spine, bodytrunk, tissue, vertebralbodies, iliospoas), andfast
being a boolean defining whether TotalSegmentator's fast function should be used. Before running this action, TotalSegmentator must be initialized using the SegmTotalSegmentatorConfig action. Returns (and optionally saves) the segmentation as a NIfTI data container.
- MasksTotalSegmentatorSpine: Maps the TotalSegmentator labels to the standard labels used in the pipeline. If
reduce_to_vb
is set toTrue
, the labels are reduced to the vertebral bodies using TotalSegmentator'svertebral_body
segmentation. Returns the remapped masks as a NIfTI data container. - MasksStanfordSpine: Maps the Comp2Comp Spine labels to the standard labels used in the pipeline. If
reduce_to_vb
is set toTrue
, the labels are reduced to the vertebral bodies using TotalSegmentator'svertebral_body
segmentation. Returns the remapped masks as a NIfTI data container.
During the processing of tissue masks, filters based on Hounsfield units and 2D or 3D size properties are applied to subsegment labels
and generate masks
as explained here and defined in the pipeline's configuration.
- MasksTotalSegmentatorTissue: Maps the TotalSegmentator labels to the standard labels used in the pipeline. If
iliopsoas
is set toTrue
, the a separate label of the iliopsoas muscle is returned using TotalSegmentator'siliopsoas
segmentation. Ifbodytrunk
is set toTrue
, the labels are reduced to the body trunk using TotalSegmentator'sbodytrunk
segmentation. Returns the remapped masks as a NIfTI data container.
- CreateBoundingBox: Creates bounding boxes around specific labels. The segmentation
label
must be provided as a NIfTI data container. The bounding box is defined in the pipeline's configuration, and the specifictask
must be defined as argument. The function then creates a bounding box around the specific label and saves it (bbox
) to the memory dictionary. - ApplyBoundingBox: Applies a bounding box to a image, label or mask. The segmentation
label
must be provided as NIfTI data containers, and the bounding boxbbox
must be available within the memory dictionary. If the NIfTI data container should not be changed, but saved separately, define its name using theoutput
argument. The function then applies the bounding box to the input NIfTI. If the changed NIfTI data container is used later on, only values within the bounding box are returned, changed or saved.
- CalcVertebralLevel: Calculates the vertebral levels based based on a (reorientated)
mask
refering to a NIfTI data container containing the (postprocessed) vertebral body segmentations. For each slice, the dominating vertebral body (most pixels) is determined using settings as defined in the pipeline's configuration. Returns a numpy array containing the vertebral levels (tmp/vertebrae_values
) to the memory dictionary. - CalcCSA: Calculates the cross-sectional area (CSA) of the tissues based on a (reorientated)
mask
refering to a NIfTI data container containing the (postprocessed) tissue segmentations. The CSA is calculated for each label in cm², considering the settings as defined in the pipeline's configuration. Returns a numpy array containing the CSA values (tmp/tissue_values
) to the memory dictionary.
- LoadMetadata: Trys to load metadata. The path is given as an argument, with the placeholder
{caseid}
being replaced by the current cases id. Can be both, a *csv (containing DICOM metadata) or a *dcm file. The metadata is saved to the memory dictionary astmp/metadata
. - DataCombine: Trys to combine tissue measurements (CSA) and vertebral levels. Checks whether affine, spacing and other metadata match. Returns a pandas dataframe containing the combined data (
tmp/bodycomposition
) to the memory dictionary. - DataSubset: Can be used to create a subset of
tmp/bodycomposition
(or an other df as defined asinput_df
argument) for later aggregation. The subset is defined by a reference (Center, Level, Centroid, Tag) corresponding to the vertebral levels created by CalcVertebralLevel and a specific vertebral level (ALL
for all vertebrae,L
for all lumbar vertebrae, or a string or list defining specific vertebrae). The subset is saved to the memory dictionary astmp/bodycomposition
or a specific name defined by theoutput_df
argument. - DataAggregate: Aggregates the data in
tmp/bodycomposition
(or an other df as defined asinput_df
argument). Groups are defined by a referenceref
(Center, Level, Centroid, Tag) corresponding to the vertebral levels created by CalcVertebralLevel. If individual groups are required, individual groups can be defined using thetag_mapping
dictionary that should map the values fromref
to new, individual groups "tags". The method of aggregation is defined bymethod
, currently mean, median and sum are supported. The aggregated data is saved to the memory dictionary astmp/bodycomposition
or a specific name defined by theoutput_df
argument. - DataExport: Saves data from a pandas dataframe (defined as argument
input
) to a csv file (defined as argumentfile
, using placeholder{caseid}
). Ifadd_metadata
is set toTrue
, the metadata imported by LoadMetadata is concatenated. Ifappend
is set toTrue
, the data is appended to the file which can be useful to generate summary files of multiple cases. Ifadd_header
is set toTrue
, the header is added to the exported data. Ifadd_index
is set toTrue
, the index is added to the exported data.