Skip to content

Commit 908914f

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent bb68687 commit 908914f

2 files changed

Lines changed: 43 additions & 55 deletions

File tree

monai/apps/nnunet/nnunetv2_runner.py

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
import shlex
2020
import shutil
2121
import subprocess
22-
from tempfile import NamedTemporaryFile, TemporaryDirectory
2322
import warnings
2423
from concurrent.futures import ThreadPoolExecutor
24+
from tempfile import NamedTemporaryFile, TemporaryDirectory
2525
from typing import Any
2626

2727
import monai
@@ -30,11 +30,10 @@
3030
analyze_data,
3131
create_new_data_copy,
3232
create_new_dataset_json,
33-
glob_to_datalist,
34-
check_existing_data_indices,
35-
get_next_available_index,
3633
get_info_from_dataset_json,
37-
move_predictions
34+
get_next_available_index,
35+
glob_to_datalist,
36+
move_predictions,
3837
)
3938
from monai.bundle import ConfigParser
4039
from monai.utils import ensure_tuple, optional_import
@@ -212,8 +211,8 @@ def __init__(
212211
os.environ["OMP_NUM_THREADS"] = str(1)
213212

214213
# dataset_name_or_id has to be a string
215-
if 'dataset_name_or_id' in self.input_info:
216-
self.dataset_name_or_id = str(self.input_info['dataset_name_or_id'])
214+
if "dataset_name_or_id" in self.input_info:
215+
self.dataset_name_or_id = str(self.input_info["dataset_name_or_id"])
217216
else:
218217
# we get the next available index
219218
self.dataset_name_or_id = str(get_next_available_index(self.nnunet_raw))
@@ -285,7 +284,9 @@ def convert_dataset(self, testing=False):
285284
if isinstance(datalist_json[test_key][0], dict) and "label" in datalist_json[test_key][0]:
286285
os.makedirs(os.path.join(raw_data_foldername, "labelsTs"))
287286

288-
num_input_channels, num_foreground_classes = self.input_info.get('num_input_channels'), self.input_info.get('num_foreground_classes')
287+
num_input_channels, num_foreground_classes = self.input_info.get("num_input_channels"), self.input_info.get(
288+
"num_foreground_classes"
289+
)
289290

290291
if num_input_channels is None or num_foreground_classes is None:
291292
# can't get num_foreground classes from the data, so should be inserted by user
@@ -296,7 +297,7 @@ def convert_dataset(self, testing=False):
296297
modality = [modality]
297298

298299
create_new_dataset_json(
299-
# pyrefly: ignore [bad-argument-type]
300+
# pyrefly: ignore [bad-argument-type]
300301
modality=modality,
301302
num_foreground_classes=num_foreground_classes,
302303
num_input_channels=num_input_channels,
@@ -439,13 +440,7 @@ def preprocess(
439440
logger.info("Preprocessing...")
440441

441442
plans_name = overwrite_plans_name if overwrite_plans_name is not None else self.plans_identifier
442-
preprocess(
443-
[int(self.dataset_name_or_id)],
444-
plans_name,
445-
configurations=c,
446-
num_processes=n_proc,
447-
verbose=verbose,
448-
)
443+
preprocess([int(self.dataset_name_or_id)], plans_name, configurations=c, num_processes=n_proc, verbose=verbose)
449444
self.plans_identifier = plans_name
450445

451446
def plan_and_process(
@@ -1058,7 +1053,7 @@ def predict_datalist(
10581053
modality: str = "CT",
10591054
num_foreground_classes: int | None = None,
10601055
num_input_channels: int | None = None,
1061-
work_dir: str = 'work_dir',
1056+
work_dir: str = "work_dir",
10621057
):
10631058
"""Method to run inference on a datalist using a model trained by this runner.
10641059
Handles all nnUNet boilerplate, instantiation of the runner, etc.
@@ -1112,17 +1107,13 @@ def predict_datalist(
11121107
# these things are hardcoded upstream
11131108
raw_data_foldername_prefix = str(int(runner.dataset_name_or_id) + 1000)
11141109
raw_data_foldername_prefix = "Dataset" + raw_data_foldername_prefix[-3:]
1115-
raw_data_foldername = raw_data_foldername_prefix + "_" + input_config['dataroot'].split(os.sep)[-1]
1116-
raw_data_foldername = os.path.join(input_config['nnunet_raw'], raw_data_foldername)
1110+
raw_data_foldername = raw_data_foldername_prefix + "_" + input_config["dataroot"].split(os.sep)[-1]
1111+
raw_data_foldername = os.path.join(input_config["nnunet_raw"], raw_data_foldername)
11171112

11181113
with TemporaryDirectory() as pred_work_folder:
11191114
test_images_dir = os.path.join(raw_data_foldername, "imagesTs") # Also hardcoded upstream
11201115

1121-
runner.predict(
1122-
test_images_dir,
1123-
output_folder=pred_work_folder,
1124-
model_training_output_dir=model_dir,
1125-
)
1116+
runner.predict(test_images_dir, output_folder=pred_work_folder, model_training_output_dir=model_dir)
11261117
move_predictions(raw_data_foldername, pred_work_folder, output_dir)
11271118

11281119
# now we can delete the raw data folder too
@@ -1141,18 +1132,18 @@ def predict_files_glob(
11411132
modality: str = "CT",
11421133
):
11431134
"""Method to run inference on a glob of files using a model trained by this runner.
1144-
1135+
11451136
Creates a temporary datalist json file from the glob of files, and then calls predict_datalist.
1146-
1137+
11471138
Args:
11481139
input_files_glob: glob pattern to match input files (e.g., ``/path/to/images/*.nii.gz``)
11491140
input_files_root: root directory for the input files (e.g., ``/path/to/images``)
11501141
model_dir: path to the folder containing the trained model (full path inside the work_dir, e.g., ``work_dir/nnUNet_trained_models/Dataset001_data/nnUNetTrainer__nnUNetPlans__3d_fullres``)
11511142
output_dir: path to the output directory, predictions will be saved here under their original names.
1152-
work_dir: path to the work_dir created by the runner during training.
1143+
work_dir: path to the work_dir created by the runner during training.
11531144
modality: modality of the input data (default: "CT")
11541145
"""
1155-
with NamedTemporaryFile(mode='w+', delete=False, suffix='.json') as temp_json_file:
1146+
with NamedTemporaryFile(mode="w+", delete=False, suffix=".json") as temp_json_file:
11561147
temp_json_path = temp_json_file.name
11571148
glob_to_datalist(input_files_glob, output_json=temp_json_path, key="testing", dataroot=input_files_root)
11581149

@@ -1162,23 +1153,25 @@ def predict_files_glob(
11621153
model_dir=model_dir,
11631154
work_dir=work_dir,
11641155
output_dir=output_dir,
1165-
modality=modality
1156+
modality=modality,
11661157
)
11671158

11681159
def _determine_configs(self):
11691160
from nnunetv2.paths import nnUNet_preprocessed
11701161
from nnunetv2.utilities.dataset_name_id_conversion import maybe_convert_to_dataset_name
11711162

1172-
preprocessed_dataset_folder_base = join(nnUNet_preprocessed, maybe_convert_to_dataset_name(self.dataset_name_or_id))
1173-
plans_file = join(preprocessed_dataset_folder_base, self.plans_identifier + '.json')
1163+
preprocessed_dataset_folder_base = join(
1164+
nnUNet_preprocessed, maybe_convert_to_dataset_name(self.dataset_name_or_id)
1165+
)
1166+
plans_file = join(preprocessed_dataset_folder_base, self.plans_identifier + ".json")
11741167

1175-
with open(plans_file, 'r') as f:
1168+
with open(plans_file) as f:
11761169
plans = json.load(f)
11771170

1178-
configurations = plans.get('configurations', [])
1171+
configurations = plans.get("configurations", [])
11791172
if not configurations:
11801173
raise ValueError(f"No configurations found in plans file: {plans_file}")
1181-
1174+
11821175
config_names = list(configurations.keys())
11831176
return config_names
11841177

monai/apps/nnunet/utils.py

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -171,18 +171,12 @@ def create_new_dataset_json(
171171
new_json_data["file_ending"] = ".nii.gz"
172172

173173
ConfigParser.export_config_file(
174-
config=new_json_data,
175-
filepath=output_filepath,
176-
fmt="json",
177-
sort_keys=True,
178-
indent=4,
179-
ensure_ascii=False,
174+
config=new_json_data, filepath=output_filepath, fmt="json", sort_keys=True, indent=4, ensure_ascii=False
180175
)
181176

182177
return
183178

184179

185-
186180
def glob_to_datalist(glob_pattern, output_json="datalist.json", key="testing", dataroot=None):
187181
files = sorted(glob.glob(glob_pattern, recursive=True))
188182
if not files:
@@ -232,37 +226,37 @@ def get_info_from_dataset_json(model_dir):
232226
if not os.path.exists(dataset_json_path):
233227
raise FileNotFoundError(f"dataset.json not found in model directory '{model_dir}'")
234228

235-
with open(dataset_json_path, "r") as f:
229+
with open(dataset_json_path) as f:
236230
dataset_info = json.load(f)
237231

238232
channel_names = dataset_info.get("channel_names", [])
239233
num_input_channels = len(channel_names)
240234

241235
labels = dataset_info.get("labels", {})
242-
num_foreground_classes = len(labels) - 1 if 'background' in labels else len(labels) # Exclude background if present
236+
num_foreground_classes = len(labels) - 1 if "background" in labels else len(labels) # Exclude background if present
243237

244238
return num_input_channels, num_foreground_classes
245239

246240

247241
def move_predictions(raw_data_foldername, pred_work_folder, output_dir):
248-
# the output is now per 'case'. We need to use the generated datalist to map the output back to the original input files.
249-
# so we have the datalist
242+
# the output is now per 'case'. We need to use the generated datalist to map the output back to the original input files.
243+
# so we have the datalist
250244
datalist_path = os.path.join(raw_data_foldername, "datalist.json")
251-
with open(datalist_path, "r") as f:
245+
with open(datalist_path) as f:
252246
datalist = json.load(f)
253247

254-
if 'test' in datalist:
255-
key = 'test'
256-
elif 'testing' in datalist:
257-
key = 'testing'
248+
if "test" in datalist:
249+
key = "test"
250+
elif "testing" in datalist:
251+
key = "testing"
258252
else:
259253
raise ValueError(f"Warning: Neither 'test' nor 'testing' key found in datalist '{datalist_path}'")
260254

261255
test_cases = datalist[key]
262256
if not test_cases:
263257
raise ValueError(f"Warning: No test cases found in datalist '{datalist_path}'")
264-
265-
case_to_image_path = {item['new_name']: item['image'] for item in test_cases}
258+
259+
case_to_image_path = {item["new_name"]: item["image"] for item in test_cases}
266260

267261
os.makedirs(output_dir, exist_ok=True)
268262

@@ -273,11 +267,12 @@ def move_predictions(raw_data_foldername, pred_work_folder, output_dir):
273267
continue
274268

275269
# Copy the prediction file to the output directory with the original image name
276-
image_extension = os.path.split(image_path, '.', 1)[1] # assumes no periods in filename, supports .nii.gz
277-
output_prediction_path = os.path.join(output_dir, image_path.replace(image_extension, '_pred.nii.gz')) # nnunet outputs nii.gz
270+
image_extension = os.path.split(image_path, ".", 1)[1] # assumes no periods in filename, supports .nii.gz
271+
output_prediction_path = os.path.join(
272+
output_dir, image_path.replace(image_extension, "_pred.nii.gz")
273+
) # nnunet outputs nii.gz
278274
output_prediction_folder = os.path.dirname(output_prediction_path)
279275
os.makedirs(output_prediction_folder, exist_ok=True) # sometimes can be nested folders
280276

281277
shutil.move(prediction_file, output_prediction_path)
282278
print(f"Moved prediction for case '{case_name}' to '{output_prediction_path}'")
283-

0 commit comments

Comments
 (0)