Skip to content

Distance Transform

distance transform module:

module for computing distance transform on segmented masks

This module consists of one main functions:
  • calculate_distance_tranform

calculate_distance_tranform(data_path, stack_size=100)

Wrapper function that calculates the distance transform on the segmented blood vessels masks. Due to the size of the data it calculated the distance transform using overlapping cubes.

Parameters

data_path: (pathlib.PosixPath) relative path for the segmented masks to be used for the distance transform

stack_size: (int) For the HPC setting we used stack size of 100. For local PC we recommend smaller stack size. HERE

Returns

output_directory: *(pathlib.PosixPath) outputs relative path for the folders with calculated distance transform.

Results are stored on the disk.

Example Usage

>>>from src.distance_tranform import calculate_distance_tranform
>>>segmented_vessels_path = Path('ppdm/data/5IT_DUMMY_STUDY/results/segmentation/vessel/segment___unet___model_file-model')

>>>calculate_distance_tranform(study_paths)

>>>output:
Path('ppdm/data/5IT_DUMMY_STUDY/results/distance_transform/vessel/distance_tranform___segment___unet___model_file-model')
Source code in src/distance_transform.py
@log_step
def calculate_distance_tranform(
    data_path: pathlib.PosixPath, stack_size: int = 100
) -> pathlib.PosixPath:

    """
    Wrapper function that calculates the distance transform on the segmented blood vessels masks. Due to the size of the data it calculated the distance transform using overlapping cubes.

    Parameters
    ----------

    **data_path**: *(pathlib.PosixPath)* relative path for the segmented masks to be used for the distance transform

    **stack_size**: *(int)* For the HPC setting we used stack size of 100. For local PC we recommend smaller stack size. [HERE](Code use pre-requisites and Installation instructions.md)

    Returns
    ------
    **output_directory**: *(pathlib.PosixPath) outputs relative path for the folders with calculated distance transform.

    Results are stored on the disk.

    Example Usage
    --------------
    ```python

    >>>from src.distance_tranform import calculate_distance_tranform
    >>>segmented_vessels_path = Path('ppdm/data/5IT_DUMMY_STUDY/results/segmentation/vessel/segment___unet___model_file-model')

    >>>calculate_distance_tranform(study_paths)

    >>>output:
    Path('ppdm/data/5IT_DUMMY_STUDY/results/distance_transform/vessel/distance_tranform___segment___unet___model_file-model')

    ```
    """

    module_results_path = "results/distance_transform"
    module_name = "distance_tranform"
    output_folder_name = join_to_string([module_name, data_path.stem])

    output_directory = create_relative_path(
        data_path,
        module_results_path,
        output_folder_name,
        _infer_root_based_on="results",
    )

    directory_ok = check_content_of_two_directories(
        data_path, output_directory
    )

    if directory_ok is False:
        if output_directory.exists():
            remove_content(output_directory)
        # step1 - create overlapping bricks
        submodule_name = "tmp_overlapping_bricks"
        output_folder_name = join_to_string([submodule_name, data_path.stem])

        output_directory = create_relative_path(
            data_path,
            module_results_path,
            output_folder_name,
            _infer_root_based_on="results",
        )
        if output_directory.exists():
            remove_content(output_directory)

        overlapping_bricks = _merge_with_overlap(
            data_path, output_directory, stack_size=stack_size
        )
        # step2 - calculate distance transform on overlapping brikcs
        submodule_name = "tmp_dt_overlapping_bricks"
        output_folder_name = join_to_string([submodule_name, data_path.stem])

        output_directory = create_relative_path(
            data_path,
            module_results_path,
            output_folder_name,
            _infer_root_based_on="results",
        )
        if output_directory.exists():
            remove_content(output_directory)

        overlapping_bricks_dt = _compute_distance_transform(
            overlapping_bricks, output_directory
        )
        # step3 - aggregate information from overlapping bricks
        submodule_name = "tmp_dt_aggregated_bricks"
        output_folder_name = join_to_string([submodule_name, data_path.stem])

        output_directory = create_relative_path(
            data_path,
            module_results_path,
            output_folder_name,
            _infer_root_based_on="results",
        )
        if output_directory.exists():
            remove_content(output_directory)

        aggregated_bricks_dt = _aggregate(
            overlapping_bricks_dt, output_directory
        )
        # final step4 - slice bricks back into individual layers
        output_folder_name = join_to_string([module_name, data_path.stem])

        output_directory = create_relative_path(
            data_path,
            module_results_path,
            output_folder_name,
            _infer_root_based_on="results",
        )
        if output_directory.exists():
            remove_content(output_directory)
        names_of_individual_layers = data_path
        _split(
            aggregated_bricks_dt, output_directory, names_of_individual_layers
        )
    return output_directory