Ë
    ëÓ^j�×  ã                   óB  — d Z ddlZddlZddlZddlmZ ddlZddlZddl	m
Z ddlmc mZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZ dd	lmZmZmZm Z  dd
l!m"Z" ddl#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z*m+Z+m,Z, ddl-m.Z.  e.«       Z/de0de0fd„Z1dedefd„Z2 G d„ de«      Z3y)u>   COCOEvalCallback â€” torchmetrics-based mAP and F1 evaluation.é    N)ÚAny)ÚCallback)ÚMeanAveragePrecision)Úget_coco_api_from_dataset)Úsweep_confidence_thresholds)ÚDEFAULT_KEYPOINT_MAX_DETSÚMetricKeypointOKSÚOKSKey)Úbuild_matching_dataÚdistributed_merge_matching_dataÚinit_matching_accumulatorÚmerge_matching_data)Úbox_cxcywh_to_xyxy)Ú_IS_RICH_AVAILABLEÚ_get_rich_consoleÚ_has_progress_barÚ_render_overall_mergedÚ_render_summary_tables)Ú
all_gatherÚget_world_sizeÚis_dist_avail_and_initialized)Ú
get_loggerÚwarning_emittedÚreturnc                 ó4   — | ryt         j                  d«       y)zýWarn once when metric table rendering is skipped because Rich is unavailable.

    Args:
        warning_emitted: Whether this warning has already been emitted.

    Returns:
        Always ``True``; caller assigns back to suppress future warnings.
    TzXRich is not installed; skipping metric table rendering. Install `rich` to enable tables.)ÚloggerÚwarning)r   s    ún/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/training/callbacks/coco_eval.pyÚ_warn_missing_rich_oncer   /   s   € ñ ØÜ
‡N�NÐmÔnØó    Úema_cbc                 óB   — | €yt        | dd«      }|€yt        |d|«      S )ur  Return the inner ``nn.Module`` wrapped by an EMA callback.

    ``RFDETREMACallback._average_model`` is a private attribute holding a ``torch.optim.swa_utils.AveragedModel``
    (which exposes the actual module on ``.module``).  This helper centralises the access so that consumers degrade
    gracefully when the EMA model has not yet been initialised â€” preferable to reaching through two layers of
    private attributes at every call site.

    Args:
        ema_cb: EMA callback instance (or ``None``).

    Returns:
        The inner module wrapped by ``AveragedModel``, or ``None`` when no EMA model is available.
    NÚ_average_modelÚmodule)Úgetattr)r!   Úaverageds     r   Ú_get_ema_inner_moduler'   >   s3   € ð €~ØÜ�vÐ/°Ó6€HØÐØÜ�8˜X xÓ0Ð0r    c                   óø  ‡ — e Zd ZdZedddddfdededed	ed
ee   dz  dedz  ddfˆ fd„Z	de
de
deddfd„Zde
de
deddfd„Zde
de
ddfd„Zde
de
ddfd„Zde
de
ddfd„Zde
de
de
de
deddfd„Zde
de
ddfd„Zde
de
deee
f   de
deddfd„Zde
de
ddfd„Z	 d@de
de
deee
f   de
dededdfd„Zde
de
ddfd„Zdd œde
de
d!ed"e
dz  ddf
d#„Zd!eddfd$„Zde
de
fd%„Zde
d"e
deee
f   fd&„Zde
de
ddfd'„Zde
defd(„Zd)Zd"e
ddfd*„Ze d"e
defd+„«       Z!de
d!ede"dz  fd,„Z#d!eddfd-„Z$de
deee
f   d!eddfd.„Z%dd/d0œd!ede
de
d1edz  d2eddfd3„Z&d4eee
f   d5ed!ede
d6eeef   d7eeeeef   f   deeee
f      fd8„Z'de
d!ed9eeef   d:eeee
f      ddf
d;„Z(d<eeee)jT                  f      deeee)jT                  f      fd=„Z+d>eeee)jT                  f      deeee)jT                  f      fd?„Z,ˆ xZ-S )AÚCOCOEvalCallbacka©  Validation callback that computes mAP (via torchmetrics) and macro-F1.

    Accumulates predictions and targets across validation batches, then at epoch end computes:

    - ``val/mAP_50_95``, ``val/mAP_50``, ``val/mAP_75``, ``val/mAR`` using
      ``torchmetrics.detection.MeanAveragePrecision``.
    - Per-class ``val/AP/<name>`` when class names are available.
    - ``val/F1``, ``val/precision``, ``val/recall`` from a confidence-threshold
      sweep over compact per-class matching data (DDP-safe).

    For segmentation models (``segmentation=True``) additional metrics ``val/segm_mAP_50_95`` and ``val/segm_mAP_50``
    are logged.

    Args:
        max_dets: Maximum detections per image passed to
            ``MeanAveragePrecision``. Defaults to :data:`~rfdetr.evaluation.keypoint_oks.DEFAULT_KEYPOINT_MAX_DETS`.
        segmentation: When ``True``, evaluate both bbox and segm IoU using
            ``backend="faster_coco_eval"``. Defaults to ``False``.
        eval_interval: Run validation metrics every N epochs. Test metrics are
            always computed when ``trainer.test()`` is called.
        log_per_class_metrics: When ``False``, skip per-class AP logging/table.
    Fé   TNÚmax_detsÚsegmentationÚeval_intervalÚlog_per_class_metricsÚkeypoint_oks_sigmasÚin_notebookr   c                 ó   •— t         ‰| �  «        || _        || _        t	        dt        |«      «      | _        t        |«      | _        g | _	        i | _
        t        «       | _        t        «       | _        d| _        d| _        d | _        d| _        || _        d| _        i | _        || _        d| _        |€7t/        j0                  t2        «      5  ddlm}  |«       d u| _        d d d «       y || _        y # 1 sw Y   y xY w)Nr*   Fr   )Úget_ipython)ÚsuperÚ__init__Ú	_max_detsÚ_segmentationÚmaxÚintÚ_eval_intervalÚboolÚ_log_per_class_metricsÚ_class_namesÚ_cat_id_to_namer   Ú	_f1_localÚ_f1_train_localÚ_ema_has_updatesÚ_missing_rich_warning_emittedÚ_output_widgetÚ_keypoint_modeÚ_use_segm_metricsÚ_train_segm_skip_warnedÚ_keypoint_oks_metricsÚ_keypoint_oks_sigmasÚ_in_notebookÚ
contextlibÚsuppressÚImportErrorÚIPythonr2   )	Úselfr+   r,   r-   r.   r/   r0   r2   Ú	__class__s	           €r   r4   zCOCOEvalCallback.__init__l   sú   ø€ ô 	‰ÑÔØ!ˆŒØ)ˆÔÜ! !¤S¨Ó%7Ó8ˆÔÜ&*Ð+@Ó&AˆÔ#Ø')ˆÔØ/1ˆÔÜ4MÓ4OˆŒÜ:SÓ:UˆÔð ',ˆÔØ38ˆÔ*Ø#'ˆÔØ$)ˆÔØ'3ˆÔØ-2ˆÔ$ØCEˆÔ"Ø$7ˆÔ!Ø"'ˆÔØÐÜ×$Ñ$¤[Ó1ñ >Ý/á$/£M¸Ð$=�Ô!÷>ð >ð
 !,ˆDÕ÷>ð >ús   ÃC4Ã4C=ÚtrainerÚ	pl_moduleÚstagec                 ó°  — t        |dd«      }|�t        |dd«      nd}|du | _        | j                  xr | j                   | _        | j                  rddgnd}t	        ddd	| j
                  gd¬
«      }d|d<   t        dd|i|¤Ž| _        t        dd|i|¤Ž| _        | j                  j                  j                  «       D ��	ch c]  \  }}	t        |	t        «      sŒ|’Œ }
}}	t        | j                  «      }|
|k7  rKt        d| j                  j                   j"                  › dt%        |
|z
  «      › dt%        ||
z
  «      › d�«      ‚d| _        yc c}	}w )zúInstantiate ``MeanAveragePrecision`` after DDP device placement.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
            stage: One of ``"fit"``, ``"validate"``, ``"test"``, ``"predict"``.
        Úmodel_configNÚuse_grouppose_keypointsFTÚbboxÚsegmr*   é
   )Úclass_metricsÚmax_detection_thresholdsÚsync_on_computeÚfaster_coco_evalÚbackendÚiou_typezZCOCOEvalCallback._MAP_STATE_ATTRS is out of sync with the installed torchmetrics (version z"). Missing from _MAP_STATE_ATTRS: z. Stale in _MAP_STATE_ATTRS: zé. Re-run: python -c "from torchmetrics.detection import MeanAveragePrecision; m = MeanAveragePrecision(); print(sorted(k for k, v in m._defaults.items() if isinstance(v, list)))" and update COCOEvalCallback._MAP_STATE_ATTRS to match.© )r%   rC   r6   rD   Údictr5   r   Ú
map_metricÚmap_metric_trainÚ	_defaultsÚitemsÚ
isinstanceÚlistÚsetÚ_MAP_STATE_ATTRSÚRuntimeErrorrN   Ú
__module__ÚsortedÚmap_metric_ema)rM   rO   rP   rQ   rS   rT   r]   ÚkwargsÚkÚvÚ	installedÚdeclareds               r   ÚsetupzCOCOEvalCallback.setup•   s„  € ô ˜y¨.¸$Ó?ˆð HTÐG_ŒG�LÐ";¸UÔCÐejð 	 ð 6¸Ð=ˆÔØ!%×!3Ñ!3Ò!O¸D×<OÑ<OÐ8OˆÔØ,0×,BÒ,B˜ Ñ(ÈˆÜ!%ØØ&'¨¨T¯^©^Ð%<ð "ô
"
ˆð /ˆˆyÑÜ.ÑK¸ÐKÀFÑKˆŒÜ 4Ñ Q¸hÐ QÈ&Ñ QˆÔð $(§?¡?×#<Ñ#<×#BÑ#BÓ#D×\™4˜1˜aÌ
ÐSTÔVZÕH[’QÐ\ˆ	Ñ\Ü�t×,Ñ,Ó-ˆØ˜Ò ÜðØ!Ÿ_™_×6Ñ6×AÑAÐBð C3Ü39¸)ÀhÑ:NÓ3OÐ2Pð Q/Ü/5°hÀÑ6JÓ/KÐ.Lð MJðJó	ð 	ð $(ˆÕùó! ]s   ÃEÃEc                 ó   — d| _         y)zôRelease the notebook output widget when the trainer exits.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
            stage: One of ``"fit"``, ``"validate"``, ``"test"``, ``"predict"``.
        N)rB   )rM   rO   rP   rQ   s       r   ÚteardownzCOCOEvalCallback.teardownÈ   s   € ð #ˆÕr    c                 ó\  — |j                   }|€yt        |d«      r|j                  xs g | _        dD ]·  }t	        ||d«      }|€Œt	        |dd«      }|€Œ#t        |d«      sŒ0t        |d«      rE|j
                  j                  «       D ��ci c]  \  }}||j                  |   d   “Œ c}}| _         y|j                  j                  «       D �	�
ci c]  \  }	}
|	|
d   “Œ c}
}	| _         y t        | j                  «      D ��ci c]  \  }}||“Œ
 c}}| _        yc c}}w c c}
}	w c c}}w )u�  Pull class names from the DataModule once the datasets are set up.

        Builds a ``category_id â†’ name`` mapping from the COCO annotation metadata so that per-class AP is logged under
        the class name regardless of whether the dataset uses sequential or non-sequential category IDs.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
        NÚclass_names)Ú_dataset_trainÚ_dataset_valÚcocoÚcatsÚ	label2catÚname)
Ú
datamoduleÚhasattrru   r<   r%   rz   rc   ry   r=   Ú	enumerate)rM   rO   rP   ÚdmÚattrÚdatasetrx   ÚlabelÚcat_idrm   rn   Úir{   s                r   Úon_fit_startzCOCOEvalCallback.on_fit_startÒ   s.  € ð ×ÑˆØˆ:ØÜ�2�}Ô%Ø "§¡Ò 4°"ˆDÔà6ò 	ˆDÜ˜b $¨Ó-ˆGØˆØÜ˜7 F¨DÓ1ˆDØÑ¤G¨D°&Õ$9Ü˜4 Ô-ð
 OSÏnÉn×NbÑNbÓNd÷,Ù=J¸UÀF˜˜tŸy™y¨Ñ0°Ñ8Ñ8ó,�DÔ(ñ ð FJÇYÁYÇ_Á_ÓEV×+W¹T¸QÀ¨A¨q°©y©LÓ+W�DÔ(Ùð!	ô$ 8AÀ×ARÑARÓ7S×T©G¨A¨t  4¡ÓTˆÕùó,ùó
 ,Xùó  Us   ÂDÃD"ÄD(c                 ó¾   — | j                   j                  «        t        «       | _        | j	                  d«       | j	                  d«       | j                  ||«       y)zÃPrepare the EMA metric on every rank before validation (keeps DDP collectives symmetric).

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
        ÚvalÚval_emaN©r`   Úresetr   r>   Ú_reset_keypoint_splitÚ_prepare_ema_metric©rM   rO   rP   s      r   Úon_validation_epoch_startz*COCOEvalCallback.on_validation_epoch_startö   sJ   € ð 	�‰×ÑÔÜ2Ó4ˆŒØ×"Ñ" 5Ô)Ø×"Ñ" 9Ô-Ø× Ñ  ¨)Õ4r    c                 óœ   — | j                   j                  «        t        «       | _        | j	                  d«       | j                  ||«       y)a¹  Reset ``_ema_has_updates`` before test to prevent stale validation state from triggering EMA compute.

        ``on_test_batch_end`` never sets ``_ema_has_updates = True``, so EMA compute is always skipped during
        test (test metrics already reflect the EMA model via checkpoint loading in
        :class:`~rfdetr.training.callbacks.best_model.BestModelCallback`).  Without this hook a stale ``True`` value
        left by a preceding validation epoch would make ``_should_compute_ema`` return ``True``, causing an
        empty-state EMA compute pass that logs sentinel ``-1`` values.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
        ÚtestNr‰   r�   s      r   Úon_test_epoch_startz$COCOEvalCallback.on_test_epoch_start  s<   € ð 	�‰×ÑÔÜ2Ó4ˆŒØ×"Ñ" 6Ô*Ø× Ñ  ¨)Õ4r    ÚoutputsÚbatchÚ	batch_idxc                 ó  — t        t        |dd«      dd«      duryt        |t        «      rd|vsd|vry| j                  |d   «      }| j	                  |d   «      }| j
                  r2|r0d|d	   vr)| j                  st        j                  d
«       d| _        y| j                  j                  ||«       | j
                  rdnd}t        ||d|¬«      }	t        | j                  |	«       | j                  ||d¬«       y)aa  Accumulate train predictions for optional train-split mAP logging.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
            outputs: Return value of ``training_step``.
            batch: The device-transferred batch (unused here).
            batch_idx: Batch index within the training epoch.
        Útrain_configNÚcompute_train_metricsFTÚresultsÚtargetsÚmasksr   z‰Train-split segmentation mAP skipped: pred_masks is a sparse dict during training (sparse_forward).  Only val/test segm mAP is available.rV   rU   ç      à?©Úiou_thresholdr]   Útrain©Úsplit)r%   rd   r_   Ú_convert_predsÚ_convert_targetsrD   rE   r   Úinfora   Úupdater   r   r?   Ú_update_keypoint_oks_metric)
rM   rO   rP   r’   r“   r”   Úpredsr™   r]   Úbatch_matchings
             r   Úon_train_batch_endz#COCOEvalCallback.on_train_batch_end  s  € ô" ”7˜9 n°dÓ;Ð=TÐV[Ó\ÐdhÑhØÜ˜'¤4Ô(¨I¸WÑ,DÈ	ÐY`ÑH`Øà/3×/BÑ/BÀ7È9ÑCUÓ/VˆØ×'Ñ'¨°	Ñ(:Ó;ˆð ×!Ò!¡e°¸uÀQ¹xÑ0GØ×/Ò/Ü—‘ðNôð 04�Ô,ØØ×Ñ×$Ñ$ U¨GÔ4à!×3Ò3‘6¸ˆÜ,¨U°GÈ3ÐYaÔbˆÜ˜D×0Ñ0°.ÔAØ×(Ñ(¨°'ÀÐ(ÕIr    c                 ó0  — t        t        |dd«      dd«      dur;| j                  j                  «        t        «       | _        | j                  d«       y| j                  dkD  r“t        t        |dd	«      «      dz   }t        |d
d«      }t        |t        «      xr |d	kD  xr ||k\  }|| j                  z  d	k7  r=|s;| j                  j                  «        t        «       | _        | j                  d«       y| j                  ||d| j                  ¬«       y)z¬Compute optional train-split mAP at the end of the training epoch.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
        r–   Nr—   FTrž   r*   Úcurrent_epochr   Ú
max_epochs©Úmetric)
r%   ra   rŠ   r   r?   r‹   r9   r8   rd   Ú_compute_and_log©rM   rO   rP   rª   r«   Úis_last_epochs         r   Úon_train_epoch_endz#COCOEvalCallback.on_train_epoch_end>  s  € ô ”7˜9 n°dÓ;Ð=TÐV[Ó\ÐdhÑhØ×!Ñ!×'Ñ'Ô)Ü#<Ó#>ˆDÔ Ø×&Ñ& wÔ/ØØ×Ñ Ò"Ü¤¨°À!Ó DÓEÈÑIˆMÜ  ¨,¸Ó=ˆJÜ& z´3Ó7Òj¸JÈ¹NÒjÈ}Ð`jÑOjˆMØ˜t×2Ñ2Ñ2°aÒ7ÁØ×%Ñ%×+Ñ+Ô-Ü'@Ó'B�Ô$Ø×*Ñ*¨7Ô3ØØ×Ñ˜g y°'À$×BWÑBWÐÕXr    c                 ón  — | j                  |d   «      }| j                  |d   «      }| j                  j                  ||«       | j                  rdnd}t        ||d|¬«      }	t        | j                  |	«       | j                  ||d¬«       | j                  |«      }
t        |
«      }|
�ù|�ö| j                  �é|\  }}t        j                  |d   D �cg c]  }|d
   ‘Œ	 c}«      j                  |j                  «      }|j                   }t        j"                  «       5  |j%                  «         ||«      }|j'                  ||«      }d	d	d	«       | j                  «      }| j                  j                  ||«       | j                  |||d   dœd¬«       d| _        y	y	y	y	c c}w # 1 sw Y   Œ`xY w)aØ  Accumulate predictions and matching data for one validation batch.

        Expects ``outputs`` to be the dict returned by ``RFDETRModelModule.validation_step``: ``{"results": list[dict],
        "targets": list[dict]}``.

        When an EMA callback is present the EMA model is run on the same batch in a separate ``torch.no_grad()`` forward
        pass so that base and EMA metrics are computed from independent predictions.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
            outputs: Return value of ``validation_step``.
            batch: The device-transferred batch ``(samples, targets)``.
            batch_idx: Batch index within the validation epoch.
        r˜   r™   rV   rU   r›   rœ   r‡   rŸ   NÚ	orig_size)r˜   r™   rˆ   T)r¡   r¢   r`   r¤   rD   r   r   r>   r¥   Ú_get_ema_callbackr'   rk   ÚtorchÚstackÚtoÚdeviceÚmodelÚno_gradÚevalÚpostprocessr@   )rM   rO   rP   r’   r“   r”   r¦   r™   r]   r§   r!   Ú	ema_innerÚsamplesÚ_ÚtÚ
orig_sizesÚema_underlyingÚema_outputsÚema_resultsÚ	ema_predss                       r   Úon_validation_batch_endz(COCOEvalCallback.on_validation_batch_endU  s®  € ð. 04×/BÑ/BÀ7È9ÑCUÓ/VˆØ×'Ñ'¨°	Ñ(:Ó;ˆà�‰×Ñ˜u gÔ.à!×3Ò3‘6¸ˆÜ,¨U°GÈ3ÐYaÔbˆÜ˜DŸN™N¨NÔ;Ø×(Ñ(¨°'ÀÐ(ÔGð ×'Ñ'¨Ó0ˆÜ)¨&Ó1ˆ	ØÐ )Ð"7¸D×<OÑ<OÐ<[Ø‰JˆG�QÜŸ™¸gÀiÑ>PÖ%Q¸ a¨£nÒ%QÓR×UÑUÐV_×VfÑVfÓgˆJØ&Ÿ_™_ˆNÜ—‘“ñ MØ×#Ñ#Ô%Ù,¨WÓ5�Ø'×3Ñ3°KÀÓL�÷Mð ×+Ñ+¨KÓ8ˆIØ×Ñ×&Ñ& y°'Ô:Ø×,Ñ,ØØ'°G¸IÑ4FÑGØð -ô ð
 %)ˆDÕ!ð =\Ð"7Ðùâ%Q÷Mð Mús   ÃF&Ä!+F+Æ+F4c                 óÜ  — | j                   dkD  rÊt        t        |dd«      «      dz   }t        |dd«      }t        |t        «      xr |dkD  xr ||k\  }|| j                   z  dk7  rt|sr| j                  j                  «        | j                  �| j                  j                  «        t        «       | _        | j                  d«       | j                  d«       y| j                  ||d«       y)z°Compute and log mAP and F1 metrics at the end of the validation epoch.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
        r*   rª   r   r«   Nr‡   rˆ   )r9   r8   r%   rd   r`   rŠ   rk   r   r>   r‹   r®   r¯   s         r   Úon_validation_epoch_endz(COCOEvalCallback.on_validation_epoch_end�  sÖ   € ð ×Ñ Ò"Ü¤¨°À!Ó DÓEÈÑIˆMÜ  ¨,¸Ó=ˆJÜ& z´3Ó7Òj¸JÈ¹NÒjÈ}Ð`jÑOjˆMØ˜t×2Ñ2Ñ2°aÒ7ÁØ—‘×%Ñ%Ô'Ø×&Ñ&Ð2Ø×'Ñ'×-Ñ-Ô/Ü!:Ó!<�”Ø×*Ñ*¨5Ô1Ø×*Ñ*¨9Ô5ØØ×Ñ˜g y°%Õ8r    Údataloader_idxc                 ó  — | j                  |d   «      }| j                  |d   «      }| j                  j                  ||«       | j                  rdnd}	t        ||d|	¬«      }
t        | j                  |
«       | j                  ||d¬«       y	)
a  Accumulate predictions and matching data for one test batch.

        Mirrors :meth:`on_validation_batch_end` for the test evaluation loop triggered by ``trainer.test()`` at the end
        of training.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
            outputs: Return value of ``test_step``.
            batch: Raw batch (unused here).
            batch_idx: Batch index within the test epoch.
            dataloader_idx: Index of the test dataloader (unused here).
        r˜   r™   rV   rU   r›   rœ   r�   rŸ   N)	r¡   r¢   r`   r¤   rD   r   r   r>   r¥   )rM   rO   rP   r’   r“   r”   rÉ   r¦   r™   r]   r§   s              r   Úon_test_batch_endz"COCOEvalCallback.on_test_batch_end¥  s…   € ð, 04×/BÑ/BÀ7È9ÑCUÓ/VˆØ×'Ñ'¨°	Ñ(:Ó;ˆà�‰×Ñ˜u gÔ.à!×3Ò3‘6¸ˆÜ,¨U°GÈ3ÐYaÔbˆÜ˜DŸN™N¨NÔ;Ø×(Ñ(¨°'ÀÐ(ÕHr    c                 ó*   — | j                  ||d«       y)a   Compute and log mAP and F1 under ``test/`` prefix at end of test epoch.

        Mirrors :meth:`on_validation_epoch_end` for the test evaluation loop.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
        r�   N)r®   r�   s      r   Úon_test_epoch_endz"COCOEvalCallback.on_test_epoch_endÅ  s   € ð 	×Ñ˜g y°&Õ9r    r¬   r    r­   c                ób  — |€| j                   n|}|dk(  r| j                  n| j                  }| j                  |«      sI|j	                  «        | j                  |«       | j                  |«       t        j                  d|«       y| j                  |«       | j                  ||«      }| j                  rdnd}|› d| j                  › �}dt        ||› d�   «      d	t        ||› d
�   «      dt        ||› d�   «      d| j                  › �t        ||   «      i}	|j                  |› d�||› d�   dddd¬«       |j                  |› d�||› d
�   dddd¬«       |j                  |› d�||› d�   ddd¬«       |j                  |› d�||   ddd¬«       ||› d�   j                  «       j!                  «       |j"                  |› d�<   ||› d
�   j                  «       j!                  «       |j"                  |› d�<   ||› d�   j                  «       j!                  «       |j"                  |› d�<   ||   j                  «       j!                  «       |j"                  |› d�<   | j%                  |«      }
|
�rì| j                  | j&                  «       | j                  || j&                  «      }|j                  |› d�||› d�   dddd¬«       |j                  |› d�||› d
�   ddd¬«       |j                  |› d�||   ddd¬«       ||› d�   j                  «       j!                  «       |j"                  |› d�<   ||› d
�   j                  «       j!                  «       |j"                  |› d�<   ||   j                  «       j!                  «       |j"                  |› d�<   | j                  rš|j                  |› d�|d   ddd¬«       |j                  |› d�|d   ddd¬«       |d   j                  «       j!                  «       |j"                  |› d�<   |d   j                  «       j!                  «       |j"                  |› d�<   | j&                  j	                  «        n&| j&                  �| j&                  j	                  «        | j                  r¼t        |d   «      |	d<   t        |d   «      |	d<   |j                  |› d�|d   ddd¬«       |j                  |› d �|d   ddd¬«       |d   j                  «       j!                  «       |j"                  |› d�<   |d   j                  «       j!                  «       |j"                  |› d �<   t)        |«      }i }|�rt+        |j-                  «       «      }|D �cg c]  }||   ‘Œ	 }}t/        |«      D ��cg c]  \  }}||   d!   d"kD  sŒ|‘Œ }}}t1        |t3        j4                  d"d#d$«      |«      }t7        |d%„ ¬&«      }t        |d'   «      |	d(<   t        |d)   «      |	d*<   t        |d+   «      |	d,<   |j                  |› d-�t        |d'   «      dddd¬«       |j                  |› d.�t        |d)   «      ddd¬«       |j                  |› d/�t        |d+   «      ddd¬«       t9        j:                  t        |d'   «      «      |j"                  |› d-�<   t9        j:                  t        |d)   «      «      |j"                  |› d.�<   t9        j:                  t        |d+   «      «      |j"                  |› d/�<   t/        |«      D ];  \  }}t        |d0   |   «      t        |d1   |   «      t        |d2   |   «      d3œ||<   Œ= nÊd4|	d(<   d4|	d*<   d4|	d,<   |j                  |› d-�d4dddd¬«       |j                  |› d.�d4ddd¬«       |j                  |› d/�d4ddd¬«       t9        j:                  d4«      |j"                  |› d-�<   t9        j:                  d4«      |j"                  |› d.�<   t9        j:                  d4«      |j"                  |› d/�<   d5|v r‘|d5   j<                  d"k(  rt?        |«      }|d5   jA                  d"«      |d5<   tC        |«      D ]O  }tE        ||   t8        jF                  «      sŒ!||   j<                  d"k(  sŒ4d6|v sŒ9||   jA                  d"«      ||<   ŒQ |› d| j                  › d7�}i }||v r5d5|v r1tI        |d5   ||   «      D ]  \  }}t        |«      |tK        |«      <   Œ | jM                  ||||||¬8«      }| jO                  |||	|«       | jQ                  |||«       |d9k(  r|
r| jQ                  d:||d9d;¬<«       n|d9k(  r| j                  d:«       |j	                  «        | j                  |«       yc c}w c c}}w )=u  Shared epoch-end logic for validation and test evaluation loops.

        Computes mAP (via ``self.map_metric``), runs the F1 confidence-threshold sweep, logs all scalar metrics via
        ``pl_module.log``, prints two summary tables to the terminal, and resets internal accumulators.  When
        ``self.map_metric_ema`` is set, EMA variants of all metrics (including ``ema_segm_mAP_50_95`` and
        ``ema_segm_mAP_50`` for segmentation models) are logged under the same ``split/`` namespace.

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule.
            split: Metric namespace â€” ``"val"`` or ``"test"``.
            metric: Optional split-specific mAP accumulator. Defaults to the validation/test accumulator.
        Nrž   zHSkipping %s COCO metric compute because no predictions were accumulated.Úbbox_Ú Úmar_z	mAP 50:95ÚmapzmAP 50Úmap_50zmAP 75Úmap_75zmAR @z
/mAP_50_95TF©Úprog_barr   Úon_stepÚon_epochz/mAP_50z/mAP_75)r   r×   rØ   z/mARz/ema_mAP_50_95z/ema_mAP_50z/ema_mARz/ema_segm_mAP_50_95Úsegm_mapz/ema_segm_mAP_50Úsegm_map_50zsegm mAP 50:95zsegm mAP 50z/segm_mAP_50_95z/segm_mAP_50Útotal_gtr   r*   ée   c                 ó   — | d   S )NÚmacro_f1r^   )Úxs    r   ú<lambda>z3COCOEvalCallback._compute_and_log.<locals>.<lambda>F  s
   € °°:±€ r    )ÚkeyrÞ   ÚF1Úmacro_precisionÚ	PrecisionÚmacro_recallÚRecallz/F1z
/precisionz/recallÚper_class_f1Úper_class_precÚper_class_rec©Úf1Ú	precisionÚrecallg        ÚclassesÚ	per_classÚ
_per_class)ÚmetricsÚpfxr    rP   Ú	ar_by_cidÚ	f1_by_cidr‡   rˆ   Úema_©Ú	log_splitÚmetric_prefix))r`   r?   r>   Ú_metric_has_updatesrŠ   Ú_reset_f1_localr‹   r   ÚdebugÚ _merge_metric_state_across_ranksÚ_compute_map_metricrD   r5   ÚfloatÚlogÚdetachÚcpuÚcallback_metricsÚ_should_compute_emark   r   rj   Úkeysr~   r   ÚnpÚlinspacer7   rµ   ÚtensorÚndimr_   Ú	unsqueezere   rd   ÚTensorÚzipr8   Ú_build_per_class_rowsÚ_print_metrics_tablesÚ_compute_and_log_keypoint_map)rM   rO   rP   r    r­   Úf1_localrñ   rò   Úmar_keyÚoverallÚshould_compute_emaÚema_metricsÚmergedrô   Ú
sorted_idsÚcidÚper_class_listr„   Úclasses_with_gtÚ
f1_resultsÚbestrm   Ú	ar_pc_keyró   Úclass_idÚarrï   s                              r   r®   z!COCOEvalCallback._compute_and_logÔ  s†
  € ð %+ N�—’¸ˆØ+0°GÒ+;�4×'Ò'ÀÇÁˆØ×'Ñ'¨Ô/Ø�L‰LŒNØ× Ñ  Ô'Ø×&Ñ& uÔ-Ü�L‰LÐcÐejÔkØð
 	×-Ñ-¨fÔ5Ø×*Ñ*¨7°FÓ;ˆð ×/Ò/‰g°RˆØ�E˜˜dŸn™nÐ-Ð.ˆð œ˜w¨#¨¨c {Ñ3Ó4Ø”e˜G s e¨6 NÑ3Ó4Ø”e˜G s e¨6 NÑ3Ó4Ø�D—N‘NÐ#Ð$¤e¨G°GÑ,<Ó&=ð	%
ˆð 	�‰Øˆg�ZÐ  '¨S¨E°¨+Ñ"6ÀÈdÐ\aÐlpð 	ô 	
ð 	�‰Øˆg�WÐ˜w¨#¨¨f ~Ñ6ÀÈdÐ\aÐlpð 	ô 	
ð 	�‰˜˜˜wÐ'¨°C°5¸°Ñ)@ÈÐW\ÐgkˆÔlØ�‰˜˜˜t�n g¨gÑ&6¸tÈUÐ]aˆÔbð :AÀCÀ5ÈÀÑ9M×9TÑ9TÓ9V×9ZÑ9ZÓ9\ˆ× Ñ  E 7¨*Ð!5Ñ6Ø6=ÀÀÀV¸nÑ6M×6TÑ6TÓ6V×6ZÑ6ZÓ6\ˆ× Ñ  E 7¨'Ð!2Ñ3Ø6=ÀÀÀV¸nÑ6M×6TÑ6TÓ6V×6ZÑ6ZÓ6\ˆ× Ñ  E 7¨'Ð!2Ñ3Ø3:¸7Ñ3C×3JÑ3JÓ3L×3PÑ3PÓ3Rˆ× Ñ  E 7¨$ Ñ0ð "×5Ñ5°iÓ@ÐÚØ×1Ñ1°$×2EÑ2EÔFØ×2Ñ2°7¸D×<OÑ<OÓPˆKØ�M‰MØ�'˜Ð(Ø˜s˜e 3˜KÑ(ØØØØð ô ð �M‰M˜U˜G ;Ð/°À¸uÀF¸^Ñ1LÐUYÐchÐswˆMÔxØ�M‰M˜U˜G 8Ð,¨k¸'Ñ.BÈ4ÐY^ÐimˆMÔnØALÐPSÈuÐTWÈ[ÑAY×A`ÑA`ÓAb×AfÑAfÓAhˆG×$Ñ$¨ w¨nÐ%=Ñ>Ø>IÈSÈEÐQWÈ.Ñ>Y×>`Ñ>`Ó>b×>fÑ>fÓ>hˆG×$Ñ$¨ w¨kÐ%:Ñ;Ø;FÀwÑ;O×;VÑ;VÓ;X×;\Ñ;\Ó;^ˆG×$Ñ$¨ w¨hÐ%7Ñ8Ø×%Ò%Ø—‘Ø�gÐ0Ð1°;¸zÑ3JÐSWÐafÐquð ô ð —‘Ø�gÐ-Ð.°¸MÑ0JÐSWÐafÐquð ô ð KVÐV`ÑJa×JhÑJhÓJj×JnÑJnÓJp�×(Ñ(¨E¨7Ð2EÐ)FÑGØGRÐS`ÑGa×GhÑGhÓGj×GnÑGnÓGp�×(Ñ(¨E¨7Ð2BÐ)CÑDØ×Ñ×%Ñ%Õ'Ø× Ñ Ð,ð ×Ñ×%Ñ%Ô'à×!Ò!Ü(-¨g°jÑ.AÓ(BˆGÐ$Ñ%Ü%*¨7°=Ñ+AÓ%BˆG�MÑ"Ø�M‰M˜U˜G ?Ð3°W¸ZÑ5HÐQUÐ_dÐosˆMÔtØ�M‰M˜U˜G <Ð0°'¸-Ñ2HÐQUÐ_dÐosˆMÔtØBIÈ*ÑBU×B\ÑB\ÓB^×BbÑBbÓBdˆG×$Ñ$¨ w¨oÐ%>Ñ?Ø?FÀ}Ñ?U×?\Ñ?\Ó?^×?bÑ?bÓ?dˆG×$Ñ$¨ w¨lÐ%;Ñ<ô 1°Ó:ˆà13ˆ	ÚÜ §¡£Ó.ˆJØ5?Ö@¨c˜f S›kÐ@ˆNÐ@Ü/8¸Ó/D×d¡V Q¨ÈÈsÉÐT^ÑH_ÐbcÓHcšqÐdˆOÑdÜ4°^ÄRÇ[Á[ÐQRÐTUÐWZÓE[Ð]lÓmˆJÜ�zÑ'>Ô?ˆDÜ! $ zÑ"2Ó3ˆG�D‰MÜ#(¨Ð.?Ñ)@Ó#AˆG�KÑ Ü % d¨>Ñ&:Ó ;ˆG�HÑØ�M‰MØ�'˜�Ü�d˜:Ñ&Ó'ØØØØð ô ð �M‰MØ�'˜Ð$¤e¨DÐ1BÑ,CÓ&DÈTÐ[`Ðkoð ô ð �M‰M˜U˜G 7Ð+¬U°4¸Ñ3GÓ-HÐQUÐ_dÐosˆMÔtÜ6;·l±lÄ5ÈÈjÑIYÓCZÓ6[ˆG×$Ñ$¨ w¨c ]Ñ3Ü=B¿\¹\Ì%ÐPTÐUfÑPgÓJhÓ=iˆG×$Ñ$¨ w¨jÐ%9Ñ:Ü:?¿,¹,ÄuÈTÐR`ÑMaÓGbÓ:cˆG×$Ñ$¨ w¨gÐ%6Ñ7Ü# JÓ/ò ‘��3ä  ^Ñ 4°QÑ 7Ó8Ü!& tÐ,<Ñ'=¸aÑ'@Ó!AÜ# D¨Ñ$9¸!Ñ$<Ó=ñ"�	˜#’ñð  ˆG�D‰MØ#&ˆG�KÑ Ø #ˆG�HÑØ�M‰M˜U˜G 3˜-¨°tÀDÐRWÐbfˆMÔgØ�M‰M˜U˜G :Ð.°¸DÈ%ÐZ^ˆMÔ_Ø�M‰M˜U˜G 7Ð+¨S¸ÀuÐW[ˆMÔ\Ü6;·l±lÀ3Ó6GˆG×$Ñ$¨ w¨c ]Ñ3Ü=B¿\¹\È#Ó=NˆG×$Ñ$¨ w¨jÐ%9Ñ:Ü:?¿,¹,ÀsÓ:KˆG×$Ñ$¨ w¨gÐ%6Ñ7ð ˜Ñ G¨IÑ$6×$;Ñ$;¸qÒ$@Ü˜7“mˆGØ!(¨Ñ!3×!=Ñ!=¸aÓ!@ˆG�IÑÜ˜'“]ò 9�Ü˜g a™j¬%¯,©,Õ7¸GÀA¹J¿O¹OÈqÓ<PÐU`ÐdeÒUeØ!(¨¡×!5Ñ!5°aÓ!8�G˜A’Jð9ð
 �e˜4 §¡Ð/¨zÐ:ˆ	Ø&(ˆ	Ø˜Ñ I°Ñ$8Ü # G¨IÑ$6¸À	Ñ8JÓ Kò 5‘�˜"Ü+0°«9�	œ#˜h›-Ò(ð5ð ×.Ñ.Ø ¨E¸YÐR[Ðgpð /ó 
ˆ	ð 	×"Ñ" 7¨E°7¸IÔFØ×*Ñ*¨5°)¸WÔEØ�EŠ>Ñ0Ø×.Ñ.¨y¸)ÀWÐX]ÐmsÐ.ÕtØ�eŠ^Ø×&Ñ& yÔ1Ø�‰ŒØ×Ñ˜UÕ#ùòM AùÛds   Õ?f&Öf+Ö/f+c                 óL   — |dk(  rt        «       | _        yt        «       | _        y)z,Reset the F1 accumulator for a metric split.rž   N)r   r?   r>   )rM   r    s     r   rú   z COCOEvalCallback._reset_f1_local‹  s   € à�GÒÜ#<Ó#>ˆDÕ ä6Ó8ˆD�Nr    c                 ó\   — t        |dg «      D ]  }t        t        |dd«      «      sŒ|c S  y)z=Return the EMA callback instance, or ``None`` if not present.Ú	callbacksÚget_ema_model_state_dictN)r%   Úcallable)rM   rO   Úcallbacks      r   r´   z"COCOEvalCallback._get_ema_callback’  s6   € ä ¨°bÓ9ò 	 ˆHÜœ Ð*DÀdÓKÕLØ’ð	 ð r    c                 ó<  — t        |«      s|j                  «       S t        t        j                  d«      t        j                  d«      f}|D �cg c]  }||j
                  f‘Œ }}	 |D ]C  }|j                  «       t        j                  k  sŒ%|j                  t        j                  «       ŒE t        j                  t        j                  «       «      5  t        j                  t        j                  «       «      5  |j                  «       cddd«       cddd«       |D ]  \  }}|j                  |«       Œ S c c}w # 1 sw Y   nxY wddd«       n# 1 sw Y   nxY w|D ]  \  }}|j                  |«       Œ y# |D ]  \  }}|j                  |«       Œ w xY w)zeCompute a torchmetrics mAP metric while suppressing duplicate terminal summaries under progress bars.r[   zfaster_coco_eval.coreN)r   Úcomputer   ÚloggingÚ	getLoggerÚlevelÚgetEffectiveLevelÚWARNINGÚsetLevelrI   Úredirect_stdoutÚioÚStringIOÚredirect_stderr)rM   rO   r­   Úmetric_loggersÚmetric_loggerÚprevious_levelsÚprevious_levels          r   rý   z$COCOEvalCallback._compute_map_metric™  sr  € ä  Ô)Ø—>‘>Ó#Ð#ä ¤'×"3Ñ"3Ð4FÓ"GÌ×IZÑIZÐ[rÓIsÐtˆØUcÖdÀM˜M¨=×+>Ñ+>Ò?ÐdˆÐdð	7Ø!/ò <�Ø ×2Ñ2Ó4´w·±ÓFØ!×*Ñ*¬7¯?©?Õ;ð<ô ×+Ñ+¬B¯K©K«MÓ:ñ (¼J×<VÑ<VÔWY×WbÑWbÓWdÓ<eñ (Ø—~‘~Ó'÷(÷ (ñ (ð 2Aò 7Ñ-�˜~Ø×&Ñ& ~Õ6ñ7ùò e÷
(ð (ú÷ (÷ (ñ (úð 2Aò 7Ñ-�˜~Ø×&Ñ& ~Õ6ñ7ø°ò 7Ñ-�˜~Ø×&Ñ& ~Õ6ñ7úsO   ÁD<Á'&E> ÂAE> Ã(EÃ>EÄ	EÄ	E> ÅE
	ÅEÅ	E> ÅEÅE> Å>Fc                 ó,  — d| _         | j                  |«      €d| _        y| j                  €N| j                  rddgnd}t	        |ddd| j
                  gdd¬	«      j                  |j                  «      | _        y| j                  j                  «        y)
a§  Ensure ``map_metric_ema`` exists (and is reset) on EVERY rank when EMA is active.

        Driven by the rank-invariant presence of the EMA callback rather than by per-batch state, so any cross-rank
        state merge (via :meth:`_merge_metric_state_across_ranks`) is issued symmetrically across DDP ranks. Previously
        the metric was created lazily in :meth:`on_validation_batch_end`, so a rank with an empty/uneven shard could
        finish without it, skip the merge/compute path, and deadlock validation (#931 / #449).

        Args:
            trainer: The PTL Trainer.
            pl_module: The LightningModule (provides the device for metric placement).
        FNrU   rV   Tr*   rW   r[   )r]   rX   rY   r\   rZ   )	r@   r´   rk   rD   r   r5   r·   r¸   rŠ   )rM   rO   rP   Úema_iou_types       r   rŒ   z$COCOEvalCallback._prepare_ema_metricª  s™   € ð !&ˆÔØ×!Ñ! 'Ó*Ð2Ø"&ˆDÔØØ×ÑÐ&Ø48×4JÒ4J ¨Ñ 0ÐPVˆLÜ"6Ø%Ø"Ø*+¨R°·±Ð)@Ø*Ø %ô#÷ ‰b�×!Ñ!Ó"ð Õð ×Ñ×%Ñ%Õ'r    c                 óF  — | j                   duxr | j                  }|rdnd}t        «       rkt        j                  |gt        |dd«      ¬«      }t        j                  |t        j                  j                  ¬«       t        |j                  «       «      }t        |«      S )uÙ  Decide â€” identically on every rank â€” whether to run the EMA metric ``compute()``.

        Under DDP, ``_merge_metric_state_across_ranks`` issues cross-rank collectives that every rank must
        participate in, or none may â€” a rank that skips desynchronises the NCCL collective sequence and deadlocks
        validation (#931 / #449).  Each rank votes ``1`` only when its EMA metric exists and received at least
        one batch update this epoch; a cross-rank ``all_reduce(MIN)`` makes the decision unanimous â€” a single
        rank voting 0 suppresses EMA compute on all ranks.

        Args:
            pl_module: The LightningModule (provides the device for the reduction).

        Returns:
            ``True`` iff every rank both holds an EMA metric object and received at least one batch update this
            epoch, making ``compute()`` safe to run identically on all ranks; ``False`` otherwise (EMA compute
            skipped uniformly on all ranks).
        Nr*   r   r¸   r  ©r¸   ©Úop)rk   r@   r   rµ   r  r%   ÚdistÚ
all_reduceÚReduceOpÚMINr8   Úitemr:   )rM   rP   Úhas_emaÚvoteÚflags        r   r  z$COCOEvalCallback._should_compute_emaÆ  s{   € ð" ×%Ñ%¨TÐ1ÒK°d×6KÑ6KˆÙ‰q ˆÜ(Ô*Ü—<‘<  ¬w°yÀ(ÈEÓ/RÔSˆDÜ�O‰O˜D¤T§]¡]×%6Ñ%6Õ7Ü�t—y‘y“{Ó#ˆDÜ�D‹zÐr    )	Údetection_boxÚdetection_scoresÚdetection_labelsÚdetection_maskÚgroundtruth_boxÚgroundtruth_labelsÚgroundtruth_maskÚgroundtruth_crowdsÚgroundtruth_areac                 ó¬  — |�t        «       rt        «       dk(  ry| j                  D ]„  }t        ||d«      }|€Œ|D �cg c]7  }t	        j
                  |«      r|j                  «       j                  «       n|‘Œ9 }}t        |«      }|D ��cg c]  }|D ]  }|‘Œ Œ }	}}t        |||	«       Œ† t        t        |dd«      d«      |_        yc c}w c c}}w )u¼  Merge a metric's accumulated per-rank state onto every rank, replacing torchmetrics' sync.

        torchmetrics' built-in sync (``gather_all_tensors``) varies the number of collectives by each state
        tensor's *local* ndim (scalar â†’ 1 all_gather, vector â†’ 2), so when DDP seg validation leaves a state
        scalar on some ranks and a vector on others the ranks issue different collective counts and deadlock
        (#931 / #449).  Instead we gather each state list once with the repo's pickle-based ``all_gather`` â€” a
        fixed collective pattern issued identically on every rank regardless of tensor shape â€” and concatenate.
        With ``sync_on_compute=False`` the metric's own ``compute()`` then runs locally over the merged full-set
        state, yielding the identical global mAP without any shape-dependent collective.

        Args:
            metric: The ``MeanAveragePrecision`` instance whose state should be merged in place.

        Note:
            No-op when ``metric`` is ``None``, when the distributed process group is not
            initialised, or when world size is 1 (single GPU / CPU training).  In these
            cases the metric state is unchanged.
        Nr*   Ú_update_countr   )r   r   rg   r%   rµ   Ú	is_tensorr   r  r   Úsetattrr7   rL  )
rM   r­   r€   Úlocalrn   Ú	local_cpuÚgatheredÚ	rank_listr>  r  s
             r   rü   z1COCOEvalCallback._merge_metric_state_across_ranksó  sÔ   € ð& ˆ>Ô!>Ô!@ÄNÓDTÐXYÒDYØØ×)Ñ)ò 		*ˆDÜ˜F D¨$Ó/ˆEØˆ}Øð QVÖVÈ1¬U¯_©_¸QÔ-?˜Ÿ™›Ÿ™Ô)ÀQÑFÐVˆIÐVÜ! )Ó,ˆHØ,4×K˜yÀÒK¸’dÐK�dÐKˆFÑKÜ�F˜D &Õ)ð		*ô  #¤7¨6°?ÀAÓ#FÈÓJˆÕùò WùãKs   ¾<CÂCc                 óâ   — t        | dd«      }t        |t        «      r|dkD  S t        j                  |«      r8t        |j                  «       j                  «       j                  «       dkD  «      S y)zIReturn whether a torchmetrics metric has accumulated at least one update.rL  Nr   T)	r%   rd   r8   rµ   rM  r:   r   r  r>  )r­   Úupdate_counts     r   rù   z$COCOEvalCallback._metric_has_updates  sa   € ô ˜v ¸Ó=ˆÜ�l¤CÔ(Ø !Ñ#Ð#Ü�?‰?˜<Ô(Ü˜×+Ñ+Ó-×1Ñ1Ó3×8Ñ8Ó:¸QÑ>Ó?Ð?Ør    c                 ó^  — || j                   v r| j                   |   S t        |dd«      }|€y|j                  d«      }ddddœj                  |d«      }|D ]T  }t        ||d«      }|€Œt	        |«      }|€Œ!t        || j                  | j                  ¬	«      }	|	| j                   |<   |	c S  y)
a}  Return the :class:`~rfdetr.evaluation.keypoint_oks.MetricKeypointOKS` for *split*, creating it if needed.

        The metric is created lazily on first access per split and reused across epochs (state is reset
        at epoch boundaries via :meth:`_reset_keypoint_split`).

        Args:
            trainer: The PTL Trainer (provides access to the datamodule).
            split: One of ``"train"``, ``"val"``, ``"val_ema"``, or ``"test"``.

        Returns:
            A :class:`~rfdetr.evaluation.keypoint_oks.MetricKeypointOKS` bound to the split's COCO
            ground-truth, or ``None`` when no dataset is available.
        r|   NÚ_ema)rv   )rw   )Ú_dataset_test)rž   r‡   r�   )rw   rW  rv   )r/   r+   )rF   r%   ÚremovesuffixÚgetr   r	   rG   r5   )
rM   rO   r    r|   Úsource_splitÚsplit_attrsr€   r�   Úcoco_apir­   s
             r   Ú"_get_or_create_keypoint_oks_metricz3COCOEvalCallback._get_or_create_keypoint_oks_metric!  sß   € ð �D×.Ñ.Ñ.Ø×-Ñ-¨eÑ4Ð4ä˜W l°DÓ9ˆ
ØÐØà×)Ñ)¨&Ó1ˆà(Ø$Ø&ñ
÷ ‰#ˆlÐOÓ
Pð	 	ð
  ò 	ˆDÜ˜j¨$°Ó5ˆGØˆØÜ0°Ó9ˆHØÐØÜ&ØØ$(×$=Ñ$=ØŸ™ôˆFð
 17ˆD×&Ñ& uÑ-ØŠMð	ð r    c                 ó`   — | j                   j                  |«      }|�|j                  «        yy)z›Reset accumulated keypoint predictions for *split*.

        Args:
            split: One of ``"train"``, ``"val"``, ``"val_ema"``, or ``"test"``.
        N)rF   rY  rŠ   )rM   r    r­   s      r   r‹   z&COCOEvalCallback._reset_keypoint_splitL  s.   € ð ×+Ñ+×/Ñ/°Ó6ˆØÐØ�L‰L�Nð r    c                 ój  — | j                   sy| j                  ||«      }|€yi }|d   }|d   }t        ||«      D ]â  \  }}	|	j                  d«      }
|
€Œt	        j
                  |
«      rt        |
j                  «       «      n
t        |
«      }d|vri ||<   Œ]|d   j                  «       j                  «       |d   j                  «       j                  «       |d   j                  «       j                  «       |d   j                  «       j                  «       d	œ||<   Œä |sy|j                  |«       y)
a"  Accumulate batch predictions into the keypoint OKS metric.

        Args:
            trainer: The PTL Trainer.
            outputs: Batch output dict with ``"results"`` and ``"targets"`` keys.
            split: Metric split (``"train"``, ``"val"``, ``"val_ema"``, or ``"test"``).
        Nr˜   r™   Úimage_idÚ	keypointsÚboxesÚscoresÚlabels)rb  rc  rd  ra  )rC   r]  r  rY  rµ   rM  r8   r>  r   r  r¤   )rM   rO   r’   r    r­   Úpredictionsr˜   r™   ÚresultÚtargetÚimage_id_tensorr`  s               r   r¥   z,COCOEvalCallback._update_keypoint_oks_metricV  s7  € ð ×"Ò"Øà×8Ñ8¸À%ÓHˆØˆ>Øà:<ˆØ˜)Ñ$ˆØ˜)Ñ$ˆÜ! '¨7Ó3ò 	‰NˆF�FØ$Ÿj™j¨Ó4ˆOØÐ&ØÜ6;·o±oÀoÔ6V”s˜?×/Ñ/Ó1Ô2Ô\_Ð`oÓ\pˆHØ &Ñ(Ø(*�˜HÑ%Øà ™×/Ñ/Ó1×5Ñ5Ó7Ø  Ñ*×1Ñ1Ó3×7Ñ7Ó9Ø  Ñ*×1Ñ1Ó3×7Ñ7Ó9Ø# KÑ0×7Ñ7Ó9×=Ñ=Ó?ñ	%ˆK˜Ò!ð	ñ ØØ�‰�kÕ"r    rÐ   rö   r÷   rø   c          	      óZ  — | j                   j                  |«      }| j                  r|€y|j                  rdnd}t	        «       rkt        j                  |gt        |dd«      ¬«      }t        j                  |t        j                  j                  ¬«       t        |j                  «       «      }|sy|€|n|}	 |j                  «       }	t        j                   dft        j"                  dft        j$                  d	ft        j&                  d	fd
œ}
|
j)                  «       D ]b  \  }\  }}|	j                  |d«      }|dk  rŒ!|› d|› |› �}|j+                  |||dd	d¬«       t        j                  |«      |j,                  |<   Œd 	 |j/                  «        y# |j/                  «        w xY w)aõ  Compute and log OKS keypoint AP/AR metrics when keypoint mode is active.

        Args:
            split: Internal metric split (``"val"``, ``"val_ema"``, ``"train"``, ``"test"``).
            pl_module: The LightningModule used to log scalar metrics.
            trainer: The PTL Trainer (provides ``callback_metrics``).
            log_split: Namespace prefix for logged keys. Defaults to *split*.
            metric_prefix: Optional string prepended to each metric name (e.g. ``"ema_"``).
        Nr*   r   r¸   r  r7  r8  TF)Úkeypoint_map_50_95Úkeypoint_map_50Úkeypoint_map_75Úkeypoint_mARg      ð¿ú/rÕ   )rF   rY  rC   Úhas_updatesr   rµ   r  r%   r:  r;  r<  r=  r8   r>  r%  r
   ÚMAPÚMAP_50ÚMAP_75ÚMARrc   rÿ   r  rŠ   )rM   r    rP   rO   r÷   rø   r­   Úhas_updates_voterA  ÚstatsÚkeypoint_metricsÚmetric_nameÚstat_keyrÖ   ÚvalueÚlog_keys                   r   r  z.COCOEvalCallback._compute_and_log_keypoint_map{  s�  € ð$ ×+Ñ+×/Ñ/°Ó6ˆØ×"Ò" f nØð
 !'× 2Ò 2™1¸ÐÜ(Ô*Ü—<‘<Ð!1Ð 2¼7À9ÈhÐX]Ó;^Ô_ˆDÜ�O‰O˜D¤T§]¡]×%6Ñ%6Õ7Ü" 4§9¡9£;Ó/ÐÙØà&Ð.‘E°Iˆ	ð	Ø—N‘NÓ$ˆEä'-§z¡z°4Ð&8Ü$*§M¡M°4Ð#8Ü$*§M¡M°5Ð#9Ü!'§¡¨UÐ 3ñ	 Ðð 6F×5KÑ5KÓ5Mò HÑ1�Ñ1˜h¨ØŸ	™	 (¨DÓ1�Ø˜1’9ØØ&˜K q¨¨¸°}ÐE�Ø—‘˜g u°xÈÐV[Ðfj�ÔkÜ49·L±LÀÓ4G�×(Ñ(¨Ò1ñHð �L‰L�NøˆF�L‰L�Nús   Â:CF ÆF*rñ   rò   ró   rô   c                 ó2  — g }| j                   s|S |› d�}||vsd|vr|S t        |d   ||   «      D ]â  \  }	}
t        |
«      }|j                  t	        |	«      t        d«      «      }|dk  r||k7  s|dk  rŒEt	        |	«      }| j
                  j                  |t        |«      «      }|j                  |› d|› �|
«       |||dœ}|j                  |j                  |t        d«      t        d«      t        d«      dœ«      «       |j                  |«       Œä |S )a,  Build per-class rows and emit per-class AP metrics.

        Args:
            metrics: Output of ``MeanAveragePrecision.compute()``.
            pfx: Key prefix for bbox metrics when segmentation mode is enabled.
            split: Metric namespace (``"val"`` or ``"test"``).
            pl_module: LightningModule used for metric logging.
            ar_by_cid: Per-class AR keyed by ``category_id``.
            f1_by_cid: Per-class F1/precision/recall keyed by ``category_id``.

        Returns:
            Per-class rows for table rendering.
        Úmap_per_classrî   Únanr   z/AP/)r{   Úapr  rê   )
r;   r  rþ   rY  r8   r=   Ústrrÿ   r¤   Úappend)rM   rñ   rò   r    rP   ró   rô   rï   Úpc_keyr  r~  Úap_fÚar_fÚidxr{   Úrows                   r   r  z&COCOEvalCallback._build_per_class_rows¯  s!  € ð, +-ˆ	Ø×*Ò*ØÐà�5˜Ð&ˆØ˜Ñ  I°WÑ$<ØÐä ¨	Ñ 2°G¸F±OÓDò 
	"‰LˆH�bÜ˜“9ˆDØ—=‘=¤ X£´°e³Ó=ˆDØ�aŠx˜T Tš\¨T°AªXØÜ�h“-ˆCØ×'Ñ'×+Ñ+¨C´°S³Ó:ˆDØ�M‰M˜U˜G 4¨ vÐ.°Ô3Ø+/°tÀ4Ñ"HˆCØ�J‰J�y—}‘} S´°u³ÌEÐRWËLÔdiÐjoÓdpÑ*qÓrÔsØ×Ñ˜SÕ!ð
	"ð Ðr    r  rï   c                 ó²  — t        |dd«      syt        st        | j                  «      | _        yt	        |«      }t        t        |dd«      «      dz   }t        |dd«      }t        |t
        «      r|dkD  r	d|› d	|› d
�nd|› d
�}|j                  «       |z   }	t        |	|| j                  «      }
| j                  rë| j                  €St        j                  t        «      5  ddl}ddlm} |j%                  «       | _         || j                  «       ddd«       | j                  �@| j                  j'                  d¬«       | j                  5  t)        ||	|
|«       ddd«       yt        j                  t        «      5  ddlm}  |d¬«       ddd«       t)        ||	|
|«       yt)        ||	|
|«       y# 1 sw Y   Œ¤xY w# 1 sw Y   yxY w# 1 sw Y   Œ?xY w)uz  Print two tables to the terminal: overall metrics and per-class metrics.

        The overall table is transposed (metrics as columns, one value row) with true merged group-header cells rendered
        via box-drawing characters: ``mAP`` spans sub-columns 50:95 / 50 / 75, ``mAR`` spans ``@N``, and ``F1 sweep``
        spans F1 / Prec / Recall.  The per-class table uses a standard Rich ``Table`` with columns for AP 50:95, AR, F1,
        Prec, Recall.

        Only runs on the global-zero rank to avoid duplicate output in DDP.

        Args:
            trainer: The PTL Trainer (used to check ``is_global_zero``).
            split: ``"val"`` or ``"test"``.
            overall: Ordered mapping of metric label â†’ scalar value.
            per_class: Per-class dicts with keys ``name``, ``ap``, ``ar``,
                ``f1``, ``precision``, ``recall``; skipped when empty.
        Úis_global_zeroTNrª   r   r*   r«   z (Epoch rn  ú))Údisplay)Úwait)Úclear_output)r%   r   r   rA   r   r8   rd   Ú
capitalizer   r5   rH   rB   rI   rJ   rK   Ú
ipywidgetsÚIPython.displayr‰  ÚOutputr‹  r   )rM   rO   r    r  rï   Úconsolerª   r«   Ú	epoch_sfxÚ	title_pfxÚoverall_renderedÚwidgetsr‰  r‹  s                 r   r  z&COCOEvalCallback._print_metrics_tablesÚ  sÅ  € ô. �wÐ 0°$Ô7ØÝ!Ü1HÈ×IkÑIkÓ1lˆDÔ.Øä# GÓ,ˆÜœG G¨_¸aÓ@ÓAÀAÑEˆÜ˜W l°DÓ9ˆ
ô ˜*¤cÔ*¨z¸Aª~ð �}�o Q z l°!Ñ4à˜M˜?¨!Ð,ð 	ð
 ×$Ñ$Ó&¨Ñ2ˆ	Ü1°)¸WÀdÇnÁnÓUÐà×Òð
 ×"Ñ"Ð*Ü×(Ñ(¬Ó5ñ 1Û0Ý7à*1¯.©.Ó*:�DÔ'Ù˜D×/Ñ/Ô0÷1ð ×"Ñ"Ð.Ø×#Ñ#×0Ñ0°dÐ0Ô;Ø×(Ñ(ñ \Ü*¨7°IÐ?OÐQZÔ[÷\àô ×$Ñ$¤[Ó1ñ (Ý8á $Õ'÷(ô # 7¨IÐ7GÈÔSØô 	˜w¨	Ð3CÀYÕO÷51ð 1ú÷\àú÷(ð (ús$   Ã 2F5ÅGÅ?GÆ5F>ÇG
ÇGr¦   c                 óÔ   — g }|D ]`  }t        |«      }d|v r>|d   j                  dk(  r,|d   j                  d   dk(  r|d   j                  d«      |d<   |j	                  |«       Œb |S )až  Normalise prediction dicts from ``PostProcess`` for torchmetrics.

        ``PostProcess.forward`` returns masks with shape ``[K, 1, H, W]`` (the extra channel is introduced by
        ``F.interpolate`` which requires 4-D input).  Both ``torchmetrics.MeanAveragePrecision`` and
        ``engine.build_matching_data`` expect ``[K, H, W]``, so squeeze the channel dim when present.

        ``PostProcess.forward`` currently returns ``[K, 1, H, W]`` masks. Keep this callback-local squeeze for metric
        code paths because ``RFDETR.predict`` and other inference-facing callers still consume the 4-D representation
        and apply ``.squeeze(1)`` at their boundary.

        Args:
            preds: Raw per-image prediction dicts from ``PostProcess``.

        Returns:
            Per-image dicts with ``masks`` squeezed to ``[K, H, W]`` when applicable; all other keys are passed through
            unchanged.
        rš   é   r*   )r_   r  ÚshapeÚsqueezer€  )rM   r¦   ÚoutÚpÚentrys        r   r¡   zCOCOEvalCallback._convert_preds$  s}   € ð$ ˆØò 	ˆAÜ˜“GˆEØ˜%Ñ E¨'¡N×$7Ñ$7¸1Ò$<ÀÀwÁ×AUÑAUÐVWÑAXÐ\]ÒA]Ø!& w¡×!7Ñ!7¸Ó!:��g‘Ø�J‰J�uÕð		ð
 ˆ
r    r™   c                 ó4  — g }|D �]  }|d   j                  «       \  }}|d   j                  ||||g«      }t        |d   «      |z  }||d   dœ}d|v r¤|d   j                  «       }	|	j                  dd t        |«      t        |«      fk7  rft        j                  |	j                  «       j                  d«      t        |«      t        |«      fd	¬
«      j                  d«      j                  «       }	|	|d<   d|v r|d   |d<   |j                  |«       �Œ |S )a¥  Convert targets from normalised CxCyWH to absolute xyxy boxes.

        Also passes ``iscrowd`` and ``masks`` through unchanged.

        Args:
            targets: Per-image target dicts with ``boxes`` in normalised
                CxCyWH format and ``orig_size`` as ``[H, W]``.

        Returns:
            Per-image dicts with ``boxes`` in absolute xyxy, ``labels``, and optionally ``masks`` and ``iscrowd``.
        r³   rb  rd  )rb  rd  rš   éþÿÿÿNr*   Únearest)ÚsizeÚmodeÚiscrowd)ÚtolistÚ
new_tensorr   r:   r—  r8   ÚFÚinterpolaterþ   r	  r˜  r€  )
rM   r™   r™  rÀ   ÚhÚwÚscalerb  r›  rš   s
             r   r¢   z!COCOEvalCallback._convert_targets>  s!  € ð ˆØó 	ˆAØ�[‘>×(Ñ(Ó*‰DˆAˆqØ�g‘J×)Ñ)¨1¨a°°A¨,Ó7ˆEÜ& q¨¡zÓ2°UÑ:ˆEØ7<ÈÈ(ÉÑ-TˆEØ˜!‰|Ø˜'™
Ÿ™Ó)�ð —;‘;˜r˜sÐ#¬¨A«´°A³Ð'7Ò7äŸ™Ø!ŸK™K›M×3Ñ3°AÓ6Ü"% a£&¬#¨a«&Ð!1Ø!*ô÷
 !™ ›ß™›ð ð "'��g‘Ø˜A‰~Ø#$ Y¡<��iÑ Ø�J‰J�uÖð-	ð. ˆ
r    )r   ).Ú__name__ri   Ú__qualname__Ú__doc__r   r8   r:   re   rþ   r4   r   r  rq   rs   r…   rŽ   r‘   r¨   r±   r_   rÆ   rÈ   rË   rÍ   r®   rú   r´   rý   rŒ   r  rg   rü   Ústaticmethodrù   r	   r]  r‹   r¥   r  r  r  rµ   r
  r¡   r¢   Ú__classcell__)rN   s   @r   r)   r)   T   s8  ø„ ñð2 2Ø"ØØ&*Ø26Ø#'ñ#,àð#,ð ð#,ð ð	#,ð
  $ð#,ð " %™[¨4Ñ/ð#,ð ˜D‘[ð#,ð 
õ#,ðR1(˜Sð 1(¨Sð 1(¸ð 1(Àó 1(ðf# ð #°ð #¸Cð #ÀDó #ð"U Cð "U°Cð "U¸Dó "UðH5°ð 5Àð 5Èó 5ð5¨3ð 5¸3ð 5À4ó 5ð$'Jàð'Jð ð'Jð ð	'Jð
 ð'Jð ð'Jð 
ó'JðRY¨#ð Y¸#ð YÀ$ó Yð.9)àð9)ð ð9)ð �c˜3�h‘ð	9)ð
 ð9)ð ð9)ð 
ó9)ðv9¨sð 9¸sð 9Àtó 9ð8  ñIàðIð ðIð �c˜3�h‘ð	Ið
 ðIð ðIð ðIð 
óIð@	:¨ð 	:¸ð 	:Àó 	:ð bfò u$¨ð u$¸ð u$ÀCð u$ÐTWÐZ^ÑT^ð u$Ðjnó u$ðn9 Sð 9¨Tó 9ð¨ð °ó ð7¨3ð 7¸ð 7ÀÀSÈ#ÀXÁó 7ð"(¨3ð (¸3ð (À4ó (ð8¨Sð °Tó ðB
Ðð"K°sð "K¸tó "KðH ð Cð ¨Dò ó ðð)¸#ð )Àcð )ÐN_ÐbfÑNfó )ðV¨3ð °4ó ð##°3ð ##ÀÀcÈ3ÀhÁð ##ÐX[ð ##Ð`dó ##ðV !%Øò2àð2ð ð2ð ð	2ð ˜‘:ð2ð ð2ð 
ó2ðh)à�c˜3�h‘ð)ð ð)ð ð	)ð
 ð)ð ˜˜U˜
Ñ#ð)ð ˜˜T # u *Ñ-Ð-Ñ.ð)ð 
ˆd�3˜�8‰nÑ	ó)ðVHPàðHPð ðHPð �c˜5�jÑ!ð	HPð
 ˜˜S #˜X™Ñ'ðHPð 
óHPðT D¨¨c°5·<±<Ð.?Ñ)@Ñ$Að ÀdÈ4ÐPSÐUZ×UaÑUaÐPaÑKbÑFcó ð4$¨¨T°#°u·|±|Ð2CÑ-DÑ(Eð $È$ÈtÐTWÐY^×YeÑYeÐTeÑOfÑJg÷ $r    r)   )4r«  rI   r-  r&  Útypingr   Únumpyr  rµ   Útorch.distributedÚdistributedr:  Útorch.nn.functionalÚnnÚ
functionalr¤  Úpytorch_lightningr   Útorchmetrics.detectionr   Úrfdetr.datasetsr   Úrfdetr.evaluation.f1_sweepr   Úrfdetr.evaluation.keypoint_oksr   r	   r
   Úrfdetr.evaluation.matchingr   r   r   r   Úrfdetr.utilities.box_opsr   Úrfdetr.utilities.consoler   r   r   r   r   Úrfdetr.utilities.distributedr   r   r   Úrfdetr.utilities.loggerr   r   r:   r   r'   r)   r^   r    r   ú<module>r¿     sœ   ðñ Eã Û 	Û Ý ã Û Ý  ß Ð Ý &Ý 7å 5Ý B÷ñ ÷
ó õ 8÷õ ÷ cÑ bÝ .á	‹€ð¨Tð °dó ð1 #ð 1¨#ó 1ô,N�xõ Nr    