Repository: Lightning-AI/torchmetrics

Issue:
Mean Average Detection ignores `warn_on_many_detections` set to False
## 🐛 Bug

MeanAverageDetection still outputs warning about too many detections even if warn_on_many_detections set to False.

### To Reproduce

The existing unit test could be used for reproduction, just try to set field to False before running it:
https://github.com/Lightning-AI/torchmetrics/blob/master/tests/unittests/detection/test_map.py#L715
The test will detect that warning is still outputted and therefore test passes.

### Expected behavior

Warnings are not outputted at all.

### Environment

Conda environment with Python 3.10 and torchmetrics 1.3.1 installed into it using pip.
See additional context why further details about environment are not actually important.

### Additional context

I looked through sources and already identified the issue: https://github.com/Lightning-AI/torchmetrics/blob/master/src/torchmetrics/detection/mean_ap.py#L803
Basically, warn parameter is never used inside function. Instead it should be a condition for triggering warning.
Also another unit test case for the flag being set to False could be useful.



Discussion:
Hi! thanks for your contribution!, great first issue!

Resolving patch:
diff --git a/src/torchmetrics/detection/mean_ap.py b/src/torchmetrics/detection/mean_ap.py
--- a/src/torchmetrics/detection/mean_ap.py
+++ b/src/torchmetrics/detection/mean_ap.py
@@ -827,8 +827,9 @@ def _get_safe_item_values(
                 rle = self.mask_utils.encode(np.asfortranarray(i))
                 masks.append((tuple(rle["size"]), rle["counts"]))
             output[1] = tuple(masks)  # type: ignore[call-overload]
-        if (output[0] is not None and len(output[0]) > self.max_detection_thresholds[-1]) or (
-            output[1] is not None and len(output[1]) > self.max_detection_thresholds[-1]
+        if warn and (
+            (output[0] is not None and len(output[0]) > self.max_detection_thresholds[-1])
+            or (output[1] is not None and len(output[1]) > self.max_detection_thresholds[-1])
         ):
             _warning_on_too_many_detections(self.max_detection_thresholds[-1])
         return output  # type: ignore[return-value]


Test patch:
diff --git a/tests/unittests/detection/test_map.py b/tests/unittests/detection/test_map.py
--- a/tests/unittests/detection/test_map.py
+++ b/tests/unittests/detection/test_map.py
@@ -712,7 +712,8 @@ def test_for_box_format(self, box_format, iou_val_expected, map_val_expected, ba
         assert round(float(result["ious"][(0, 0)]), 3) == iou_val_expected
 
     @pytest.mark.parametrize("iou_type", ["bbox", "segm"])
-    def test_warning_on_many_detections(self, iou_type, backend):
+    @pytest.mark.parametrize("warn_on_many_detections", [False, True])
+    def test_warning_on_many_detections(self, iou_type, warn_on_many_detections, backend, recwarn):
         """Test that a warning is raised when there are many detections."""
         if iou_type == "bbox":
             preds = [
@@ -727,8 +728,13 @@ def test_warning_on_many_detections(self, iou_type, backend):
             preds, targets = _generate_random_segm_input("cpu", 1, 101, 10, False)
 
         metric = MeanAveragePrecision(iou_type=iou_type, backend=backend)
-        with pytest.warns(UserWarning, match="Encountered more than 100 detections in a single image.*"):
-            metric.update(preds, targets)
+        metric.warn_on_many_detections = warn_on_many_detections
+
+        if warn_on_many_detections:
+            with pytest.warns(UserWarning, match="Encountered more than 100 detections in a single image.*"):
+                metric.update(preds, targets)
+        else:
+            assert len(recwarn) == 0
 
     @pytest.mark.parametrize(
         ("preds", "target", "expected_iou_len", "iou_keys", "precision_shape", "recall_shape", "scores_shape"),