|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import shutil |
|
from typing import Tuple |
|
|
|
from batchgenerators.utilities.file_and_folder_operations import * |
|
from nnunet.configuration import default_num_threads |
|
from nnunet.evaluation.evaluator import aggregate_scores |
|
from nnunet.postprocessing.connected_components import determine_postprocessing |
|
import argparse |
|
|
|
|
|
def collect_cv_niftis(cv_folder: str, output_folder: str, validation_folder_name: str = 'validation_raw', |
|
folds: tuple = (0, 1, 2, 3, 4)): |
|
validation_raw_folders = [join(cv_folder, "fold_%d" % i, validation_folder_name) for i in folds] |
|
exist = [isdir(i) for i in validation_raw_folders] |
|
|
|
if not all(exist): |
|
raise RuntimeError("some folds are missing. Please run the full 5-fold cross-validation. " |
|
"The following folds seem to be missing: %s" % |
|
[i for j, i in enumerate(folds) if not exist[j]]) |
|
|
|
|
|
maybe_mkdir_p(output_folder) |
|
for f in folds: |
|
niftis = subfiles(validation_raw_folders[f], suffix=".nii.gz") |
|
for n in niftis: |
|
shutil.copy(n, join(output_folder)) |
|
|
|
|
|
def consolidate_folds(output_folder_base, validation_folder_name: str = 'validation_raw', |
|
advanced_postprocessing: bool = False, folds: Tuple[int] = (0, 1, 2, 3, 4)): |
|
""" |
|
Used to determine the postprocessing for an experiment after all five folds have been completed. In the validation of |
|
each fold, the postprocessing can only be determined on the cases within that fold. This can result in different |
|
postprocessing decisions for different folds. In the end, we can only decide for one postprocessing per experiment, |
|
so we have to rerun it |
|
:param folds: |
|
:param advanced_postprocessing: |
|
:param output_folder_base:experiment output folder (fold_0, fold_1, etc must be subfolders of the given folder) |
|
:param validation_folder_name: dont use this |
|
:return: |
|
""" |
|
output_folder_raw = join(output_folder_base, "cv_niftis_raw") |
|
if isdir(output_folder_raw): |
|
shutil.rmtree(output_folder_raw) |
|
|
|
output_folder_gt = join(output_folder_base, "gt_niftis") |
|
collect_cv_niftis(output_folder_base, output_folder_raw, validation_folder_name, |
|
folds) |
|
|
|
num_niftis_gt = len(subfiles(join(output_folder_base, "gt_niftis"), suffix='.nii.gz')) |
|
|
|
num_niftis = len(subfiles(output_folder_raw, suffix='.nii.gz')) |
|
if num_niftis != num_niftis_gt: |
|
raise AssertionError("If does not seem like you trained all the folds! Train all folds first!") |
|
|
|
|
|
summary_fold0 = load_json(join(output_folder_base, "fold_0", validation_folder_name, "summary.json"))['results'][ |
|
'mean'] |
|
classes = [int(i) for i in summary_fold0.keys()] |
|
niftis = subfiles(output_folder_raw, join=False, suffix=".nii.gz") |
|
test_pred_pairs = [(join(output_folder_raw, i), join(output_folder_gt, i)) for i in niftis] |
|
|
|
|
|
|
|
aggregate_scores(test_pred_pairs, labels=classes, json_output_file=join(output_folder_raw, "summary.json"), |
|
num_threads=default_num_threads) |
|
|
|
determine_postprocessing(output_folder_base, output_folder_gt, 'cv_niftis_raw', |
|
final_subf_name="cv_niftis_postprocessed", processes=default_num_threads, |
|
advanced_postprocessing=advanced_postprocessing) |
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
argparser = argparse.ArgumentParser() |
|
argparser.add_argument("-f", type=str, required=True, help="experiment output folder (fold_0, fold_1, " |
|
"etc must be subfolders of the given folder)") |
|
|
|
args = argparser.parse_args() |
|
|
|
folder = args.f |
|
|
|
consolidate_folds(folder) |
|
|