inference.nnunet.runner

nnUNet Inference Runner

Provides functionalities related to running the nnUNet inference on the input data.

  1"""
  2### nnUNet Inference Runner
  3
  4Provides functionalities related to running the nnUNet inference on the input data.
  5"""
  6
  7
  8import subprocess
  9from tqdm import tqdm
 10import os
 11from pathlib import Path
 12import argparse
 13from typing import List, Tuple, Dict, Optional
 14
 15
 16def maybe_make_dir(path: str) -> str:
 17    """
 18    Creates a directory at the specified path if it does not exist.
 19
 20    Args:
 21        path (str): Path to the directory to be created.
 22
 23    Returns:
 24        str: The path to the created or existing directory.
 25    """
 26    os.makedirs(path, exist_ok=True)
 27    return path
 28
 29
 30def set_env_paths(input_path: str, path: str) -> str:
 31    """
 32    Sets environment paths required for nnUNet predictions.
 33
 34    Args:
 35        input_path (str): Path to the input data.
 36        path (str): Path to the output directory.
 37
 38    Returns:
 39        str: A string containing environment variables for nnUNet.
 40    """
 41    # Define the path for preprocessed data
 42    preprocessed = maybe_make_dir(str(Path('/tmp/') / 'nnUNet_preprocessed'))
 43    
 44    # Return environment variable settings as a single string
 45    return f"nnUNet_raw='{input_path}' nnUNet_preprocessed='{preprocessed}' nnUNet_results='/tmp/'"
 46
 47
 48def get_dataset_info(challenge_name: str) -> Tuple[str, str, str, str]:
 49    """
 50    Returns the corresponding dataset name, trainer, plans, and configuration based on the provided challenge name.
 51
 52    Args:
 53        challenge_name (str): Name of the challenge (e.g., BraTS-PED, BraTS-MET).
 54
 55    Returns:
 56        Tuple[str, str, str, str]: 
 57            - dataset_name: Name of the dataset.
 58            - trainer: Trainer configuration.
 59            - plans: Plans configuration.
 60            - configuration: nnUNet configuration.
 61
 62    Raises:
 63        Exception: If the challenge name is not compatible.
 64    """
 65    if challenge_name == "BraTS-PED":
 66        dataset_name = "Dataset021_BraTS2024-PED"
 67        trainer = "nnUNetTrainer_200epochs"
 68        plans = "nnUNetPlans"
 69        configuration = "3d_fullres"
 70    elif challenge_name == "BraTS-SSA":
 71        dataset_name = "Dataset022_BraTS2024-SSA"
 72        trainer = "nnUNetTrainer_150epochs_CustomSplit_stratified_pretrained_GLI"
 73        plans = "nnUNetPlans_pretrained_GLI"
 74        configuration = "3d_fullres"
 75    elif challenge_name == "BraTS-GLI":
 76        dataset_name = "Dataset023_BraTS2024-GLI"
 77        trainer = "nnUNetTrainer_200epochs"
 78        plans = "nnUNetPlans"
 79        configuration = "3d_fullres"
 80    elif challenge_name == "BraTS-MEN-RT":
 81        dataset_name = "Dataset024_BraTS2024-MEN-RT"
 82        trainer = "nnUNetTrainer_200epochs"
 83        plans = "nnUNetPlans"
 84        configuration = "3d_fullres"
 85    elif challenge_name == "BraTS-MET":
 86        dataset_name = "Dataset026_BraTS2024-MET"
 87        trainer = "nnUNetTrainer_200epochs"
 88        plans = "nnUNetPlans"
 89        configuration = "3d_fullres"
 90    else:
 91        raise Exception("Challenge name not compatible.")
 92    
 93    return dataset_name, trainer, plans, configuration
 94
 95
 96def run_infer_nnunet(
 97    input_folder: str,
 98    output_folder: str,
 99    challenge_name: str,
100    name: str,
101    folds: List[int] = [0, 1, 2, 3, 4],
102    save_npz: bool = True,
103    ensemble: bool = True
104) -> List[Path]:
105    """
106    Runs nnUNet inference on the provided input data.
107
108    This function executes the nnUNet inference command either as an ensemble
109    across all folds or individually per specified fold. It extracts the
110    predictions and saves them as .npz files.
111
112    Args:
113        input_folder (str): Path to the input folder containing prediction files.
114        output_folder (str): Path to the folder where output predictions will be stored.
115        challenge_name (str): Name of the challenge (e.g., BraTS-PED, BraTS-MET).
116        name (str): Base name for the output prediction files.
117        folds (List[int], optional): List of fold indices to process. Defaults to [0, 1, 2, 3, 4].
118        save_npz (bool, optional): Whether to save the prediction probabilities as .npz files. Defaults to True.
119        ensemble (bool, optional): Whether to perform ensemble prediction across all folds. Defaults to True.
120
121    Returns:
122        List[Path]: A list of paths to the saved .npz files from each fold.
123    """
124    # Retrieve dataset information based on the challenge name
125    dataset_name, trainer, plans, configuration = get_dataset_info(challenge_name)
126    
127    # Set environment paths required for nnUNet
128    env_set = set_env_paths(input_folder, output_folder)
129
130    if ensemble:
131        # Define the output directory for ensemble predictions
132        output_folder_fold = os.path.join(output_folder, "ens")
133        print(f"Running nnUNet inference with all folds (ensemble)..")
134        
135        # Construct the nnUNet inference command for ensemble
136        cmd = (
137            f"{env_set} nnUNetv2_predict "
138            f"-i '{input_folder}' "
139            f"-o '{output_folder_fold}' "
140            f"-d '{dataset_name}' "
141            f"-c '{configuration}' "
142            f"-tr '{trainer}' "
143            f"-p '{plans}'"
144        )
145        
146        if save_npz:
147            cmd += " --save_probabilities"
148        
149        # Execute the inference command
150        subprocess.run(cmd, shell=True)
151        
152        # Return the path to the ensemble .npz file
153        return [Path(os.path.join(output_folder_fold, f"{name}.npz"))]
154    else:
155        # Initialize a list to store paths to .npz files for each fold
156        npz_path_list: List[Path] = [] 
157        
158        # Iterate over each specified fold and perform inference
159        for fold in tqdm(folds, desc="Processing Folds"):
160            output_folder_fold = os.path.join(output_folder, f"fold_{fold}")
161            print(f"Running nnUNet inference for fold {fold}")
162            
163            # Construct the nnUNet inference command for the current fold
164            cmd = (
165                f"{env_set} nnUNetv2_predict "
166                f"-i '{input_folder}' "
167                f"-o '{output_folder_fold}' "
168                f"-d '{dataset_name}' "
169                f"-c '{configuration}' "
170                f"-tr '{trainer}' "
171                f"-p '{plans}' "
172                f"-f '{fold}'"
173            )
174            
175            if save_npz:
176                cmd += " --save_probabilities"
177            
178            # Execute the inference command for the current fold
179            subprocess.run(cmd, shell=True)  # Executes the command in the shell
180            
181            # Append the path to the saved .npz file
182            npz_path_list.append(Path(os.path.join(output_folder_fold, f"{name}.npz")))
183    
184        return npz_path_list
def maybe_make_dir(path: str) -> str:
17def maybe_make_dir(path: str) -> str:
18    """
19    Creates a directory at the specified path if it does not exist.
20
21    Args:
22        path (str): Path to the directory to be created.
23
24    Returns:
25        str: The path to the created or existing directory.
26    """
27    os.makedirs(path, exist_ok=True)
28    return path

Creates a directory at the specified path if it does not exist.

Args: path (str): Path to the directory to be created.

Returns: str: The path to the created or existing directory.

def set_env_paths(input_path: str, path: str) -> str:
31def set_env_paths(input_path: str, path: str) -> str:
32    """
33    Sets environment paths required for nnUNet predictions.
34
35    Args:
36        input_path (str): Path to the input data.
37        path (str): Path to the output directory.
38
39    Returns:
40        str: A string containing environment variables for nnUNet.
41    """
42    # Define the path for preprocessed data
43    preprocessed = maybe_make_dir(str(Path('/tmp/') / 'nnUNet_preprocessed'))
44    
45    # Return environment variable settings as a single string
46    return f"nnUNet_raw='{input_path}' nnUNet_preprocessed='{preprocessed}' nnUNet_results='/tmp/'"

Sets environment paths required for nnUNet predictions.

Args: input_path (str): Path to the input data. path (str): Path to the output directory.

Returns: str: A string containing environment variables for nnUNet.

def get_dataset_info(challenge_name: str) -> Tuple[str, str, str, str]:
49def get_dataset_info(challenge_name: str) -> Tuple[str, str, str, str]:
50    """
51    Returns the corresponding dataset name, trainer, plans, and configuration based on the provided challenge name.
52
53    Args:
54        challenge_name (str): Name of the challenge (e.g., BraTS-PED, BraTS-MET).
55
56    Returns:
57        Tuple[str, str, str, str]: 
58            - dataset_name: Name of the dataset.
59            - trainer: Trainer configuration.
60            - plans: Plans configuration.
61            - configuration: nnUNet configuration.
62
63    Raises:
64        Exception: If the challenge name is not compatible.
65    """
66    if challenge_name == "BraTS-PED":
67        dataset_name = "Dataset021_BraTS2024-PED"
68        trainer = "nnUNetTrainer_200epochs"
69        plans = "nnUNetPlans"
70        configuration = "3d_fullres"
71    elif challenge_name == "BraTS-SSA":
72        dataset_name = "Dataset022_BraTS2024-SSA"
73        trainer = "nnUNetTrainer_150epochs_CustomSplit_stratified_pretrained_GLI"
74        plans = "nnUNetPlans_pretrained_GLI"
75        configuration = "3d_fullres"
76    elif challenge_name == "BraTS-GLI":
77        dataset_name = "Dataset023_BraTS2024-GLI"
78        trainer = "nnUNetTrainer_200epochs"
79        plans = "nnUNetPlans"
80        configuration = "3d_fullres"
81    elif challenge_name == "BraTS-MEN-RT":
82        dataset_name = "Dataset024_BraTS2024-MEN-RT"
83        trainer = "nnUNetTrainer_200epochs"
84        plans = "nnUNetPlans"
85        configuration = "3d_fullres"
86    elif challenge_name == "BraTS-MET":
87        dataset_name = "Dataset026_BraTS2024-MET"
88        trainer = "nnUNetTrainer_200epochs"
89        plans = "nnUNetPlans"
90        configuration = "3d_fullres"
91    else:
92        raise Exception("Challenge name not compatible.")
93    
94    return dataset_name, trainer, plans, configuration

Returns the corresponding dataset name, trainer, plans, and configuration based on the provided challenge name.

Args: challenge_name (str): Name of the challenge (e.g., BraTS-PED, BraTS-MET).

Returns: Tuple[str, str, str, str]: - dataset_name: Name of the dataset. - trainer: Trainer configuration. - plans: Plans configuration. - configuration: nnUNet configuration.

Raises: Exception: If the challenge name is not compatible.

def run_infer_nnunet( input_folder: str, output_folder: str, challenge_name: str, name: str, folds: List[int] = [0, 1, 2, 3, 4], save_npz: bool = True, ensemble: bool = True) -> List[pathlib.Path]:
 97def run_infer_nnunet(
 98    input_folder: str,
 99    output_folder: str,
100    challenge_name: str,
101    name: str,
102    folds: List[int] = [0, 1, 2, 3, 4],
103    save_npz: bool = True,
104    ensemble: bool = True
105) -> List[Path]:
106    """
107    Runs nnUNet inference on the provided input data.
108
109    This function executes the nnUNet inference command either as an ensemble
110    across all folds or individually per specified fold. It extracts the
111    predictions and saves them as .npz files.
112
113    Args:
114        input_folder (str): Path to the input folder containing prediction files.
115        output_folder (str): Path to the folder where output predictions will be stored.
116        challenge_name (str): Name of the challenge (e.g., BraTS-PED, BraTS-MET).
117        name (str): Base name for the output prediction files.
118        folds (List[int], optional): List of fold indices to process. Defaults to [0, 1, 2, 3, 4].
119        save_npz (bool, optional): Whether to save the prediction probabilities as .npz files. Defaults to True.
120        ensemble (bool, optional): Whether to perform ensemble prediction across all folds. Defaults to True.
121
122    Returns:
123        List[Path]: A list of paths to the saved .npz files from each fold.
124    """
125    # Retrieve dataset information based on the challenge name
126    dataset_name, trainer, plans, configuration = get_dataset_info(challenge_name)
127    
128    # Set environment paths required for nnUNet
129    env_set = set_env_paths(input_folder, output_folder)
130
131    if ensemble:
132        # Define the output directory for ensemble predictions
133        output_folder_fold = os.path.join(output_folder, "ens")
134        print(f"Running nnUNet inference with all folds (ensemble)..")
135        
136        # Construct the nnUNet inference command for ensemble
137        cmd = (
138            f"{env_set} nnUNetv2_predict "
139            f"-i '{input_folder}' "
140            f"-o '{output_folder_fold}' "
141            f"-d '{dataset_name}' "
142            f"-c '{configuration}' "
143            f"-tr '{trainer}' "
144            f"-p '{plans}'"
145        )
146        
147        if save_npz:
148            cmd += " --save_probabilities"
149        
150        # Execute the inference command
151        subprocess.run(cmd, shell=True)
152        
153        # Return the path to the ensemble .npz file
154        return [Path(os.path.join(output_folder_fold, f"{name}.npz"))]
155    else:
156        # Initialize a list to store paths to .npz files for each fold
157        npz_path_list: List[Path] = [] 
158        
159        # Iterate over each specified fold and perform inference
160        for fold in tqdm(folds, desc="Processing Folds"):
161            output_folder_fold = os.path.join(output_folder, f"fold_{fold}")
162            print(f"Running nnUNet inference for fold {fold}")
163            
164            # Construct the nnUNet inference command for the current fold
165            cmd = (
166                f"{env_set} nnUNetv2_predict "
167                f"-i '{input_folder}' "
168                f"-o '{output_folder_fold}' "
169                f"-d '{dataset_name}' "
170                f"-c '{configuration}' "
171                f"-tr '{trainer}' "
172                f"-p '{plans}' "
173                f"-f '{fold}'"
174            )
175            
176            if save_npz:
177                cmd += " --save_probabilities"
178            
179            # Execute the inference command for the current fold
180            subprocess.run(cmd, shell=True)  # Executes the command in the shell
181            
182            # Append the path to the saved .npz file
183            npz_path_list.append(Path(os.path.join(output_folder_fold, f"{name}.npz")))
184    
185        return npz_path_list

Runs nnUNet inference on the provided input data.

This function executes the nnUNet inference command either as an ensemble across all folds or individually per specified fold. It extracts the predictions and saves them as .npz files.

Args: input_folder (str): Path to the input folder containing prediction files. output_folder (str): Path to the folder where output predictions will be stored. challenge_name (str): Name of the challenge (e.g., BraTS-PED, BraTS-MET). name (str): Base name for the output prediction files. folds (List[int], optional): List of fold indices to process. Defaults to [0, 1, 2, 3, 4]. save_npz (bool, optional): Whether to save the prediction probabilities as .npz files. Defaults to True. ensemble (bool, optional): Whether to perform ensemble prediction across all folds. Defaults to True.

Returns: List[Path]: A list of paths to the saved .npz files from each fold.