Repository: Project-MONAI/MONAI

Issue:
data list utility enhancement
**Is your feature request related to a problem? Please describe.**
the current data list utility assumes that when the key is `"test"`, the data is a list of filenames. https://github.com/Project-MONAI/MONAI/blob/ed1c281a0f1b0d9c364ed59020a69ab2a821a5f2/monai/data/decathlon_datalist.py#L125-L126

would be great to optionally support the testing data in the form of a list of dictionaries, to be consistent with the `'training'` list, for example,

```
        "test":
        [
            {'image': '/workspace/data/chest_19.nii.gz',  'othermetafield': 0},
            {'image': '/workspace/data/chest_31.nii.gz',  'othermetafield': 1}
        ]
```


Discussion:

Patch:
diff --git a/monai/data/decathlon_datalist.py b/monai/data/decathlon_datalist.py
--- a/monai/data/decathlon_datalist.py
+++ b/monai/data/decathlon_datalist.py
@@ -122,7 +122,8 @@ def load_decathlon_datalist(
     if data_list_key not in json_data:
         raise ValueError(f'Data list {data_list_key} not specified in "{data_list_file_path}".')
     expected_data = json_data[data_list_key]
-    if data_list_key == "test":
+    if data_list_key == "test" and not isinstance(expected_data[0], dict):
+        # decathlon datalist may save the test images in a list directly instead of dict
         expected_data = [{"image": i} for i in expected_data]
 
     if base_dir is None:
diff --git a/monai/metrics/confusion_matrix.py b/monai/metrics/confusion_matrix.py
--- a/monai/metrics/confusion_matrix.py
+++ b/monai/metrics/confusion_matrix.py
@@ -102,7 +102,9 @@ def _compute_tensor(self, y_pred: torch.Tensor, y: torch.Tensor):  # type: ignor
 
         return get_confusion_matrix(y_pred=y_pred, y=y, include_background=self.include_background)
 
-    def aggregate(self, compute_sample: bool = False, reduction: Union[MetricReduction, str, None] = None):  # type: ignore
+    def aggregate(  # type: ignore
+        self, compute_sample: bool = False, reduction: Union[MetricReduction, str, None] = None
+    ):
         """
         Execute reduction for the confusion matrix values.
 


Test patch:
diff --git a/tests/test_load_decathlon_datalist.py b/tests/test_load_decathlon_datalist.py
--- a/tests/test_load_decathlon_datalist.py
+++ b/tests/test_load_decathlon_datalist.py
@@ -29,7 +29,7 @@ def test_seg_values(self):
                     {"image": "spleen_19.nii.gz", "label": "spleen_19.nii.gz"},
                     {"image": "spleen_31.nii.gz", "label": "spleen_31.nii.gz"},
                 ],
-                "test": ["spleen_15.nii.gz", "spleen_23.nii.gz"],
+                "test": [{"image": "spleen_15.nii.gz"}, {"image": "spleen_23.nii.gz"}],
             }
             json_str = json.dumps(test_data)
             file_path = os.path.join(tempdir, "test_data.json")
@@ -38,6 +38,8 @@ def test_seg_values(self):
             result = load_decathlon_datalist(file_path, True, "training", tempdir)
             self.assertEqual(result[0]["image"], os.path.join(tempdir, "spleen_19.nii.gz"))
             self.assertEqual(result[0]["label"], os.path.join(tempdir, "spleen_19.nii.gz"))
+            result = load_decathlon_datalist(file_path, True, "test", None)
+            self.assertEqual(result[0]["image"], os.path.join(tempdir, "spleen_15.nii.gz"))
 
     def test_cls_values(self):
         with tempfile.TemporaryDirectory() as tempdir:
@@ -81,6 +83,8 @@ def test_seg_no_basedir(self):
             result = load_decathlon_datalist(file_path, True, "training", None)
             self.assertEqual(result[0]["image"], os.path.join(tempdir, "spleen_19.nii.gz"))
             self.assertEqual(result[0]["label"], os.path.join(tempdir, "spleen_19.nii.gz"))
+            result = load_decathlon_datalist(file_path, True, "test", None)
+            self.assertEqual(result[0]["image"], os.path.join(tempdir, "spleen_15.nii.gz"))
 
     def test_seg_no_labels(self):
         with tempfile.TemporaryDirectory() as tempdir: