parse_utils#

Geometry metrics (IoU, F1, precision, recall), measurement metrics (MAE, MRE), and the helpers that extract numeric answers from raw model output.

Parsing and metric utilities for the MedVision benchmark.

This module collects helpers used when parsing model outputs and scoring them against ground truth, including:

  • Bounding-box overlap metrics (IoU, F1/Dice, Precision, Recall).

  • Extraction of the last k numbers from free-form text, optionally scoped to an <answer> block.

  • Loading a 2D slice (and its in-plane pixel spacing) from a 3D NIfTI volume.

  • Converting NumPy values to native Python types for JSON serialization.

  • Grouping parsed results by anatomy/label, imaging modality, slice orientation, or box-to-image area ratio for stratified reporting.

medvision_bm.utils.parse_utils.get_subfolders(task_dir)[source]#

Return the paths of all immediate subdirectories of a directory.

Parameters:

task_dir – Directory to scan for subfolders.

Returns:

Path of each immediate subdirectory (typically one per model).

Return type:

list[str]

medvision_bm.utils.parse_utils.load_nifti_2d(img_path, slice_dim, slice_idx)[source]#

Load a single 2D slice and its in-plane pixel spacing from a 3D NIfTI image.

Parameters:
  • img_path – Path to the NIfTI (.nii / .nii.gz) file.

  • slice_dim – Axis to slice along; must be 0, 1 or 2.

  • slice_idx – Index of the slice to extract along slice_dim.

Returns:

(pixel_size, image_2d) where pixel_size is the in-plane voxel spacing (the two voxel dimensions not sliced along) and image_2d is the extracted 2D slice as a float32 array.

Return type:

tuple

Raises:

ValueError – If slice_dim is not 0, 1 or 2.

medvision_bm.utils.parse_utils.extract_last_k_nums(text, k)[source]#

Extract the last k numbers found in a text string.

Numbers are matched with an internal regex that accepts an optional sign, optional thousands separators, a decimal part and an exponent. Thousands separators are stripped so the comma-joined result splits back into the same numbers downstream.

Parameters:
  • text – Text to search for numbers.

  • k – Number of trailing numbers to return.

Returns:

A comma-separated string of the last k numbers, or an empty string if fewer than k numbers are present.

Return type:

str

medvision_bm.utils.parse_utils.extract_last_k_nums_within_answer_tag(text, k)[source]#

Extract the last k numbers found inside an <answer>...</answer> block.

The content between the first <answer> and </answer> tags is searched for numbers (matching an optional sign, thousands separators, a decimal part and an exponent). Thousands separators are stripped so the comma-joined result splits back into the same numbers downstream.

Parameters:
  • text – Text expected to contain an <answer> block.

  • k – Number of trailing numbers to return.

Returns:

A comma-separated string of the last k numbers within the answer block, or an empty string if no answer tag is found or it contains fewer than k numbers.

Return type:

str

medvision_bm.utils.parse_utils.convert_numpy_to_python(obj)[source]#

Recursively convert NumPy values to native Python types for JSON serialization.

Parameters:

obj – Value to convert. May be a scalar, array, or a nested dict, list or tuple containing such values.

Returns:

The input with np.float32 scalars converted to float, np.ndarray converted to lists, and containers converted recursively. Values of other types are returned unchanged.

medvision_bm.utils.parse_utils.cal_IoU(pred, target)[source]#

Compute the Intersection over Union (IoU) of two axis-aligned boxes.

Each box is normalized so its corners are ordered, tolerating inputs given as [xmax, xmin, ymax, ymin] (they are sorted into [xmin, xmax, ymin, ymax]).

Parameters:
  • pred – Predicted box as 4 numbers [x1, y1, x2, y2].

  • target – Ground-truth box as 4 numbers [x1, y1, x2, y2].

Returns:

IoU in [0.0, 1.0]; 0.0 when the boxes do not overlap.

Return type:

float

Raises:

ValueError – If either input does not contain exactly 4 numbers.

medvision_bm.utils.parse_utils.cal_F1(pred, target)[source]#

Compute the F1 score (Dice similarity coefficient) of two axis-aligned boxes.

F1 is 2 * intersection / (pred_area + target_area). Each box is normalized so its corners are ordered before computing areas.

Parameters:
  • pred – Predicted box as 4 numbers [x1, y1, x2, y2].

  • target – Ground-truth box as 4 numbers [x1, y1, x2, y2].

Returns:

F1 score clamped to [0.0, 1.0]; 0.0 when the boxes do not overlap, or nan if both boxes have zero area.

Return type:

float

Raises:

ValueError – If either input does not contain exactly 4 numbers.

medvision_bm.utils.parse_utils.cal_Precision(pred, target)[source]#

Compute precision (intersection over predicted area) of two axis-aligned boxes.

Each box is normalized so its corners are ordered before computing areas.

Parameters:
  • pred – Predicted box as 4 numbers [x1, y1, x2, y2].

  • target – Ground-truth box as 4 numbers [x1, y1, x2, y2].

Returns:

Precision clamped to [0.0, 1.0]; 0.0 when the boxes do not overlap, or nan if the predicted box has zero area.

Return type:

float

Raises:

ValueError – If either input does not contain exactly 4 numbers.

medvision_bm.utils.parse_utils.cal_Recall(pred, target)[source]#

Calculates Recall with robustness fixes for floating point errors and invalid box checks.

Parameters:
  • pred – (list or np.array) [xmin, ymin, xmax, ymax]

  • target – (list or np.array) [xmin, ymin, xmax, ymax]

Returns:

Recall value (0.0 to 1.0)

Return type:

float

medvision_bm.utils.parse_utils.cal_metrics_detection_task(results)[source]#

Calculate detection task metrics from model predictions.

Parameters:

results – Dictionary containing ‘filtered_resps’ (predictions) and ‘target’ (ground truth)

Returns:

avgMAE, avgIoU, F1, Precision, Recall, SuccessRate

Return type:

Dictionary with metrics

medvision_bm.utils.parse_utils.cal_metrics(results, task_type)[source]#

Calculate metrics for different task types.

Parameters:
  • results – Dictionary containing ‘filtered_resps’ and ‘target’

  • task_type – Type of task - ‘Detection’, ‘TL’, or ‘AD’

Returns:

Dictionary with calculated metrics

medvision_bm.utils.parse_utils.get_labelsMap_imgModality_from_seg_benchmark_plan(dataset_name, task_id)[source]#

Import benchmark_plan and get labels_map for the given dataset and task_id.

Parameters:
  • dataset_name – Name of the dataset

  • task_id – Task ID (1-based)

Returns:

Labels map from the benchmark plan

medvision_bm.utils.parse_utils.get_labelsMap_imgModality_from_biometry_benchmark_plan(dataset_name, task_id)[source]#

Import benchmark_plan and get labels_map for the given dataset and task_id.

Parameters:
  • dataset_name – Name of the dataset

  • task_id – Task ID (1-based)

Returns:

Labels map from the benchmark plan

medvision_bm.utils.parse_utils.get_targetLabel_imgModality_from_biometry_benchmark_plan(dataset_name, task_id)[source]#
medvision_bm.utils.parse_utils.group_by_anatomy_modality_slice(data)[source]#

Group parsed results by parent anatomy class, modality and slice orientation.

Each label is mapped to its parent anatomy class via label_map_regroup, the imaging modality is normalized to a short code (e.g. MRI to MR, ultrasound to US, X-ray to XR), and the slice dimension is mapped to an orientation code (0 to S, 1 to C, 2 to A). Results are keyed as "<parent> @ <modality> (<orientation>)".

Parameters:

data – Iterable of tuples (imgModality, label_name, target, filtered_resps, _, slice_dim).

Returns:

Mapping of each group key to a dict with "targets" (list of targets) and "responses" (flattened list of responses).

Return type:

dict

Raises:

ValueError – If a label is missing from label_map_regroup or slice_dim is not 0, 1 or 2.

medvision_bm.utils.parse_utils.group_by_label_modality_slice(data)[source]#

Group parsed results by renamed label, modality and slice orientation.

Each label is renamed via label_map_rename, the imaging modality is normalized to a short code (e.g. MRI to MR, ultrasound to US, X-ray to XR), and the slice dimension is mapped to an orientation code (0 to S, 1 to C, 2 to A). Results are keyed as "<label> @ <modality> (<orientation>)".

Parameters:

data – Iterable of tuples (imgModality, label_name, target, filtered_resps, _, slice_dim).

Returns:

Mapping of each group key to a dict with "targets" (list of targets) and "responses" (flattened list of responses).

Return type:

dict

Raises:

ValueError – If a label is missing from label_map_rename or slice_dim is not 0, 1 or 2.

medvision_bm.utils.parse_utils.group_by_boxImgRatio(data)[source]#

Group parsed results into bins by box-to-image area ratio.

Each item is placed into a 5%-wide bin based on its box-to-image ratio, ranging from "Box/Image < 5%" up to "90% <= Box/Image".

Parameters:

data – Iterable of tuples (_, target, filtered_resps, _, box_img_ratio, image_size_2d).

Returns:

Mapping of each bin label to a dict with "targets" (list of targets), "responses" (flattened list of responses) and "image_size_2d" (list of image sizes).

Return type:

dict