def add_label_stats_to_dataframe(input_dataframe: pd.DataFrame, dataset_root_directory: Path, target_label_names: List[str]) -> pd.DataFrame: """ Loops through all available subject IDs, generates ground-truth label statistics and updates input dataframe with the computed stats by adding new columns. In particular, it checks the overlapping regions between different structures and volume of labels. :param input_dataframe: Input Pandas dataframe object containing subjectIds and label names :param dataset_root_directory: Path to dataset root directory :param target_label_names: A list of label names that are used in label stat computations """ dataset_sources = load_dataset_sources(input_dataframe, local_dataset_root_folder=dataset_root_directory, image_channels=["ct"], ground_truth_channels=target_label_names, mask_channel=None) # Iterate over subjects and check overlapping labels for subject_id in [*dataset_sources.keys()]: labels = io_util.load_labels_from_dataset_source(dataset_sources[subject_id]) overlap_stats = metrics_util.get_label_overlap_stats(labels=labels[1:, ...], label_names=target_label_names) header = io_util.load_nifti_image(dataset_sources[subject_id].ground_truth_channels[0]).header volume_stats = metrics_util.get_label_volume(labels=labels[1:, ...], label_names=target_label_names, label_spacing=header.spacing) # Log the extracted label statistics for col_name, col_stats in zip(("LabelOverlap", "LabelVolume (mL)"), (overlap_stats, volume_stats)): input_dataframe.loc[input_dataframe.subject == subject_id, col_name] = \ input_dataframe.loc[input_dataframe.subject == subject_id, "channel"].map(col_stats) return input_dataframe
def test_get_label_volume() -> None: """ Tests computation of label volumes. """ test_data = {'spleen': np.array([[0, 1, 0], [1, 1, 0]]), 'liver': np.array([[0, 0, 0], [0, 0, 0]])} label_overlap_stats = get_label_volume(labels=np.stack(test_data.values()), label_names=list(test_data.keys()), label_spacing=(1.00, 2.00, 3.00)) assert label_overlap_stats['spleen'] == pytest.approx(3 * 6 / 1000.0, 1e-6) assert label_overlap_stats['liver'] == pytest.approx(0.0, 1e-6)