Ë
    ëÓ^jsy  ã                   óZ  — d Z ddlmZ ddlmZmZmZmZmZm	Z	 ddl
Z
ddlZ
ddlmZ ddlmZ ddlmZ ddlmZ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  e«       ZdZerddl m!Z! de"fd„Z# G d„ de
jH                  jJ                  jL                  «      Z'de(de(fd„Z) G d„ de«      Z*y)zALightningDataModule for RF-DETR dataset construction and loaders.é    )ÚPath)ÚTYPE_CHECKINGÚAnyÚListÚLiteralÚOptionalÚTupleN)ÚLightningDataModule)Ú
DataLoader)Ú_namespace_from_configs)ÚModelConfigÚTrainConfig)Úbuild_dataset)Ú
AUG_CONFIG)Úbox_xyxy_to_cxcywh)Ú
get_logger)Úmake_collate_fné   )ÚFigureÚreturnc                  óB   — ddl m}  t        | «      j                  d«      S )zûReturn ``True`` when the runtime has a CUDA accelerator available.

    Uses the fork-safe global ``DEVICE`` constant instead of direct ``torch.cuda.is_available()`` calls to avoid
    creating a CUDA context in fork-based notebook/DDP workflows.
    r   ©ÚDEVICEÚcuda)Úrfdetr.configr   ÚstrÚ
startswithr   s    úf/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/training/module_data.pyÚ_has_cuda_devicer       s   € õ %äˆv‹;×!Ñ! &Ó)Ð)ó    c            	       ó„   — e Zd ZdZ	 ddej
                  j                  j                  dededdfd„Z	defd„Z
d	edefd
„Zy)ÚGradAccumAlignedDatasetu  Dataset wrapper that pads length to a multiple of ``effective_batch_size * world_size``.

    Workaround for https://github.com/Lightning-AI/pytorch-lightning/issues/19987: PTL fires the optimizer on partial
    accumulation windows at the tail of the dataset, causing the last optimizer step to be under-scaled.  Padding the
    dataset to a multiple of ``effective_batch_size * world_size`` ensures that ``drop_last=True`` on the DataLoader
    becomes a true no-op â€” every accumulation window is always complete.

    Padding indices are drawn randomly from the original dataset.  Because RF-DETR uses online augmentation, each padded
    sample receives a fresh random augmentation at ``__getitem__`` time, so it behaves like a new training example
    rather than a true duplicate.

    This wrapper can be removed once the upstream PTL issue is resolved.

    Args:
        dataset: The underlying dataset to wrap.
        effective_batch_size: ``batch_size * grad_accum_steps``.
        world_size: Number of DDP processes (default 1 for single-GPU/CPU).
            The alignment unit is ``effective_batch_size * world_size`` so that after PTL's ``DistributedSampler``
            splits samples across ranks each rank still receives an exact multiple of ``effective_batch_size``.
    ÚdatasetÚeffective_batch_sizeÚ
world_sizer   Nc                 ó¤  — |dk  rt        d|› �«      ‚|dk  rt        d|› �«      ‚|| _        t        |«      | _        ||z  }| j                  |z  }||z
  |z  }t	        j
                  «       }|j                  d«       |dkD  r2t	        j                  d| j                  |f|¬«      j                  «       ng | _	        | j                  |z   | _
        y )Né   z'effective_batch_size must be >= 1, got zworld_size must be >= 1, got r   )Ú	generator)Ú
ValueErrorÚ_datasetÚlenÚ_dataset_lengthÚtorchÚ	GeneratorÚmanual_seedÚrandintÚtolistÚ_pad_indicesÚ_length)Úselfr#   r$   r%   Úpad_unitÚ	remainderÚ	pad_countÚpad_index_generators           r   Ú__init__z GradAccumAlignedDataset.__init__A   så   € ð   !Ò#ÜÐFÐG[ÐF\Ð]Ó^Ð^Ø˜Š>ÜÐ<¸Z¸LÐIÓJÐJàˆŒÜ" 7›|ˆÔØ'¨*Ñ4ˆØ×(Ñ(¨8Ñ3ˆ	Ø 	Ñ)¨XÑ5ˆ	Ü#Ÿo™oÓ/ÐØ×'Ñ'¨Ô*ð ˜1Š}ô �M‰MØØ×$Ñ$Ø�Ø-ô	÷
 ‰fŒhàð 	Ôð ×+Ñ+¨iÑ7ˆ�r    c                 ó   — | j                   S )zKReturn the padded dataset length (always a multiple of the alignment unit).)r3   ©r4   s    r   Ú__len__zGradAccumAlignedDataset.__len___   s   € à�|‰|Ðr    Úidxc                 óz   — || j                   k  r|n| j                  || j                   z
     }| j                  |   S )z1Return the item at the (possibly remapped) index.)r,   r2   r*   )r4   r=   Údataset_idxs      r   Ú__getitem__z#GradAccumAlignedDataset.__getitem__c   s>   € ð ! 4×#7Ñ#7Ò7‘c¸T×=NÑ=NÈsÐUY×UiÑUiÑOiÑ=jˆØ�}‰}˜[Ñ)Ð)r    )r'   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r-   ÚutilsÚdataÚDatasetÚintr9   r<   r   r@   © r    r   r"   r"   +   sf   „ ñð2 ñ	8à—‘×!Ñ!×)Ñ)ð8ð "ð8ð ð	8ð
 
ó8ð<˜ó ð*˜sð * sô *r    r"   Úbackendc                 óP   — | dk7  r| S t        «       sy	 ddl}y# t        $ r Y yw xY w)aø  Resolve ``"auto"`` to ``"cpu"`` or ``"gpu"`` based on runtime availability.

    For ``"cpu"`` and ``"gpu"`` the value is returned unchanged.  For ``"auto"`` the function checks CUDA and kornia
    availability and returns ``"gpu"`` only when both are present; otherwise ``"cpu"``.

    Called before dataset construction so that ``gpu_postprocess`` in the dataset builders always matches what the
    DataModule will actually do in ``on_after_batch_transfer``.

    Args:
        backend: Value of ``TrainConfig.augmentation_backend``.

    Returns:
        Resolved backend string, either ``"cpu"`` or ``"gpu"``.

    Examples:
        >>> _resolve_augmentation_backend("cpu")
        'cpu'
        >>> _resolve_augmentation_backend("gpu")
        'gpu'
    ÚautoÚcpur   NÚgpu)r   Úkornia.augmentationÚImportError)rJ   Úkornias     r   Ú_resolve_augmentation_backendrR   k   s7   € ð* �&ÒØˆÜÔØðÛ"àøÜò Ùðús   ” ™	%¤%c                   óð  ‡ — e Zd ZdZdededdfˆ fd„Zdeddfd„Zde	fd	„Z
de	fd
„Zde	fd„Zde	fd„Z	 d$dddœdeded   dedeeef   dz  ddf
d„Zed%dededefd„«       Zded   dej,                  j.                  j0                  dz  fd„Zedej,                  j.                  j0                  dededz  fd„«       Zd&d„Zdededefd „Zede e!e      fd!„«       Z"ded"ejF                  dedefd#„Z$ˆ xZ%S )'ÚRFDETRDataModulea  LightningDataModule wrapping RF-DETR dataset construction and data loading.

    Args:
        model_config: Architecture configuration (used for resolution, patch_size, etc.).
        train_config: Training hyperparameter configuration (used for dataset params).
    Úmodel_configÚtrain_configr   Nc           	      óž  •— t         ‰| �  «        || _        || _        |j                  |j
                  z  }|dk  r)t        d|› d|j                  › d|j
                  › d�«      ‚t        |¬«      | _        d | _	        d | _
        d | _        d | _        d | _        d| _        | j                  j                  | _        ddlm} t'        | j                  j(                  «      j+                  «       }|d	v }| j                  j,                  €	|d
k(  xr! |nt/        | j                  j,                  «      | _        | j                  j2                  €| j                   dkD  nt/        | j                  j2                  «      | _        | j                   dkD  r:| j                  j6                  �| j                  j6                  | _        y d| _        y d | _        y )Nr   z-Computed collate block_size must be > 0, got z from patch_size=z and num_windows=ú.)Ú
block_sizeFr   >   rN   rL   r   r   é   )Úsuperr9   rU   rV   Ú
patch_sizeÚnum_windowsr)   r   Ú_collate_fnÚ_dataset_trainÚ_dataset_valÚ_dataset_testÚ_kornia_pipelineÚ_kornia_normalizeÚ_kornia_setup_doneÚnum_workersÚ_num_workersr   r   r   ÚacceleratorÚlowerÚ
pin_memoryÚboolÚ_pin_memoryÚpersistent_workersÚ_persistent_workersÚprefetch_factorÚ_prefetch_factor)r4   rU   rV   rY   r   rg   Úuses_cuda_acceleratorÚ	__class__s          €r   r9   zRFDETRDataModule.__init__”   sÔ  ø€ Ü‰ÑÔØ(ˆÔØ(ˆÔð "×,Ñ,¨|×/GÑ/GÑGˆ
Ø˜Š?ÜØ?Ø�,Ð/°×0GÑ0GÐ/Hð I#Ø#/×#;Ñ#;Ð"<¸Að?óð ô
 +Ø!ô
ˆÔð CGˆÔØ@DˆÔØAEˆÔð -1ˆÔØ-1ˆÔð ).ˆÔà!%×!2Ñ!2×!>Ñ!>ˆÔõ 	)ä˜$×+Ñ+×7Ñ7Ó8×>Ñ>Ó@ˆØ +Ð/FÐ FÐð × Ñ ×+Ñ+Ð3ð �vÑÒ7Ñ"7ä�d×'Ñ'×2Ñ2Ó3ð 	Ôð × Ñ ×3Ñ3Ð;ð ×Ñ Ò!ä�d×'Ñ'×:Ñ:Ó;ð 	Ô ð
 ×Ñ˜qÒ à59×5FÑ5F×5VÑ5VÐ5b�×!Ñ!×1Ñ1ð Õ!Øhið Õ!ð %)ˆDÕ!r    Ústagec                 ó&  — | j                   j                  }t        | j                   | j                  «      }|dk(  rÊt	        | j                  j
                  «      }|| j                  j
                  k7  r||_        | j                   j                  r|dk7  rt        d|› d�«      ‚| j                  €t        d||«      | _        | j                  €t        d||«      | _
        | j                  s| j                  «        d| _        yy|d	k(  r | j                  €t        d||«      | _
        yy|d
k(  r=| j                  €0| j                  j                  dk(  rd
nd}t        |||«      | _        yy|dk(  r | j                  €t        d||«      | _
        yyy)u†  Build datasets for the requested stage.

        PTL calls this on every process before the corresponding dataloader method.  Datasets are built lazily â€” a
        dataset is only constructed once even if ``setup`` is called multiple times.

        Args:
            stage: PTL stage identifier â€” one of ``"fit"``, ``"validate"``,
                ``"test"``, or ``"predict"``.
        ÚfitrM   zGPU augmentation backend 'zi' does not support keypoint transforms. Set augmentation_backend='cpu' when use_grouppose_keypoints=True.NÚtrainÚvalTÚvalidateÚtestÚroboflowÚpredict)rU   Ú
resolutionr   rV   rR   Úaugmentation_backendÚuse_grouppose_keypointsr)   r_   r   r`   rd   Ú_setup_kornia_pipelinera   Údataset_file)r4   rr   r{   ÚnsÚresolvedÚsplits         r   ÚsetupzRFDETRDataModule.setupÑ   sŸ  € ð ×&Ñ&×1Ñ1ˆ
Ü$ T×%6Ñ%6¸×8IÑ8IÓJˆØ�EŠ>ô 5°T×5FÑ5F×5[Ñ5[Ó\ˆHØ˜4×,Ñ,×AÑAÒAØ*2�Ô'Ø× Ñ ×8Ò8¸XÈÒ=NÜ Ø0°°
ð ;Xð Xóð ð ×"Ñ"Ð*Ü&3°G¸RÀÓ&L�Ô#Ø× Ñ Ð(Ü$1°%¸¸ZÓ$H�Ô!ð ×*Ò*Ø×+Ñ+Ô-Ø*.�Õ'ð +ð �jÒ Ø× Ñ Ð(Ü$1°%¸¸ZÓ$H�Õ!ð )à�fŠ_Ø×!Ñ!Ð)Ø"&×"3Ñ"3×"@Ñ"@ÀJÒ"N™ÐTY�Ü%2°5¸"¸jÓ%I�Õ"ð *ð �iÒØ× Ñ Ð(Ü$1°%¸¸ZÓ$H�Õ!ð )ð  r    c                 óÀ  — | j                   }| j                  j                  }|| j                  j                  z  }| j                  }t        |«      |t        z  k  r•t        j                  dt        |«      |t        z  «       t        j                  j                  j                  |d|t        z  ¬«      }t        |||| j                  || j                  | j                   | j"                  ¬«      S | j$                  rt'        | j$                  dd«      nd}t)        |||«      }t        ||dd| j                  || j                  | j                   | j"                  ¬«	      S )a  Return the training DataLoader.

        Uses a replacement sampler when the dataset is too small to fill ``_MIN_TRAIN_BATCHES`` effective batches
        (matching legacy behaviour in ``main.py``).  Otherwise wraps the dataset with :class:`GradAccumAlignedDataset`
        to ensure its length is an exact multiple of ``effective_batch_size * world_size`` (workaround for
        https://github.com/Lightning-AI/pytorch-lightning/issues/19987) and then uses ``shuffle=True, drop_last=True``
        so that PTL can auto-inject ``DistributedSampler`` in DDP mode.

        Returns:
            DataLoader for the training dataset.
        zCTraining with uniform sampler because dataset is too small: %d < %dT)ÚreplacementÚnum_samples)Ú
batch_sizeÚsamplerÚ
collate_fnre   ri   rl   rn   r%   r'   )r‡   ÚshuffleÚ	drop_lastr‰   re   ri   rl   rn   )r_   rV   r‡   Úgrad_accum_stepsrf   r+   Ú_MIN_TRAIN_BATCHESÚloggerÚinfor-   rE   rF   ÚRandomSamplerr   r^   rk   rm   ro   ÚtrainerÚgetattrr"   )r4   r#   r‡   r$   re   rˆ   r%   s          r   Útrain_dataloaderz!RFDETRDataModule.train_dataloader   sQ  € ð ×%Ñ%ˆØ×&Ñ&×1Ñ1ˆ
Ø)¨D×,=Ñ,=×,NÑ,NÑNÐØ×'Ñ'ˆäˆw‹<Ð.Ô1CÑCÒCÜ�K‰KØUÜ�G“Ø$Ô'9Ñ9ôô
 —k‘k×&Ñ&×4Ñ4ØØ Ø0Ô3EÑEð 5ó ˆGô
 ØØ%ØØ×+Ñ+Ø'Ø×+Ñ+Ø#'×#;Ñ#;Ø $× 5Ñ 5ô	ð 	ð EIÇLÂLœ' $§,¡,°¸aÔ@ÐVWˆ
Ü)¨'Ð3GÈÓTˆäØØ!ØØØ×'Ñ'Ø#Ø×'Ñ'Ø#×7Ñ7Ø ×1Ñ1ô

ð 
	
r    c                 ó,  — t        | j                  | j                  j                  t        j
                  j                  j                  | j                  «      d| j                  | j                  | j                  | j                  | j                  ¬«	      S )zˆReturn the validation DataLoader.

        Returns:
            DataLoader for the validation dataset with sequential sampling.
        F©r‡   rˆ   r‹   r‰   re   ri   rl   rn   ©r   r`   rV   r‡   r-   rE   rF   ÚSequentialSamplerr^   rf   rk   rm   ro   r;   s    r   Úval_dataloaderzRFDETRDataModule.val_dataloader:  ów   € ô Ø×ÑØ×(Ñ(×3Ñ3Ü—K‘K×$Ñ$×6Ñ6°t×7HÑ7HÓIØØ×'Ñ'Ø×)Ñ)Ø×'Ñ'Ø#×7Ñ7Ø ×1Ñ1ô

ð 
	
r    c                 ó,  — t        | j                  | j                  j                  t        j
                  j                  j                  | j                  «      d| j                  | j                  | j                  | j                  | j                  ¬«	      S )z|Return the test DataLoader.

        Returns:
            DataLoader for the test dataset with sequential sampling.
        Fr•   )r   ra   rV   r‡   r-   rE   rF   r—   r^   rf   rk   rm   ro   r;   s    r   Útest_dataloaderz RFDETRDataModule.test_dataloaderL  sw   € ô Ø×ÑØ×(Ñ(×3Ñ3Ü—K‘K×$Ñ$×6Ñ6°t×7IÑ7IÓJØØ×'Ñ'Ø×)Ñ)Ø×'Ñ'Ø#×7Ñ7Ø ×1Ñ1ô

ð 
	
r    c                 ó,  — t        | j                  | j                  j                  t        j
                  j                  j                  | j                  «      d| j                  | j                  | j                  | j                  | j                  ¬«	      S )z¶Return the predict DataLoader (reuses the validation dataset, no augmentation).

        Returns:
            DataLoader for the validation dataset with sequential sampling.
        Fr•   r–   r;   s    r   Úpredict_dataloaderz#RFDETRDataModule.predict_dataloader^  r™   r    é   )ÚcolumnsÚfigure_sizeÚcountr‚   )ru   rv   rx   rŸ   r    r   c                ó  — 	 ddl m} ddl}ddl}ddlm} ddlm}
 |dk  rt        d|› d�«      ‚|dk  rt        d|› d�«      ‚|�<t        |«      dk7  rt        d	|› d�«      ‚|d   dk  s|d
   dk  rt        d|› d�«      ‚| j                  |«      }|€t        d|›d�«      ‚|j                  g d¢g d¢¬«      }t        d
t        |t        |«      «      |z   d
z
  |z  «      }|j!                  |||xs
 d|z  d|z  f¬«      \  }}|j#                  |t$        ¬«      j'                  d«      }|D ]  }|j)                  d«       Œ | j*                  }t-        |t/        t        |t        |«      «      «      d¬«      D �]Ø  \  }}||   \  }}| j1                  ||«      } ||«      }|j3                  «       j5                  «       j                  «       }|j7                  |j9                  |j;                  d
dd«      dd«      dz  j=                  |j>                  «      «      }|jA                  d«      }tC        |tD        jF                  «      rtI        |d   «      tI        |d
   «      }}n0tI        |jJ                  d   «      tI        |jJ                  d   «      }}|jA                  dtE        jL                  dtD        jN                  ¬«      «      }|jA                  dtE        jL                  d tD        jP                  ¬«      «      }|jS                  «       dkD  �r¶tE        jT                  ||||gtD        jN                  ¬«      } |
|j3                  «       j5                  «       «      |z  } |j3                  «       j5                  «       j                  «       j=                  tH        «      }!|jA                  d!«      }"|"�?|"jS                  «       dkD  r,|"j3                  «       j5                  «       j                  «       nd}#|jW                  | j                  «       j=                  |jN                  «      |!|#¬"«      }$|!D �%cg c]"  }%|�|%t        |«      k  r||%   n
tY        |%«      ‘Œ$ }&}%|#�!|j[                  «       j]                  ||$¬#«      }|j_                  d
¬$«      j]                  ||$¬#«      }|ja                  d%d¬&«      j]                  ||$|&¬'«      }|jA                  d(«      }'|'��|'jS                  «       dkD  �r|'j3                  «       j5                  «       j                  «       j=                  |jN                  «      }(|(d)dd…f   |j#                  ||g|jN                  ¬«      z  })|(d*   dkD  }*|jc                  |)|*j=                  |jN                  «      |j3                  «       j5                  «       j                  «       j=                  tH        «      |*d+|*i¬,«      }+|je                  d-¬.«      j]                  ||+¬/«      }|jg                  |«       |�|jh                  n|› d0|› d1�},|jk                  | jm                  |,«      d2¬3«       |j)                  d«       �ŒÛ |jo                  «        |S # t        $ r}	t        d«      |	‚d}	~	ww xY wc c}%w )4aø  Build a private diagnostic figure for transformed dataset samples.

        Samples the dataset after RF-DETR dataset transforms, so boxes and
        keypoints match the model input tensors rather than raw annotation JSON.

        Args:
            count: Maximum number of samples to render.
            split: Dataset split to visualize.
            columns: Number of subplot columns.
            figure_size: Optional Matplotlib figure size ``(width, height)`` in
                inches. When omitted, the size is derived from the grid shape.

        Returns:
            Matplotlib figure containing the annotated sample grid. When the
            dataset includes instance masks, they are rendered as coloured
            overlays before bounding boxes and labels.

        Raises:
            ValueError: If ``count`` or ``columns`` is not positive.

        Example:
            >>> # dm = RFDETRDataModule(model_config, train_config)
            >>> # figure = dm._show_samples(3, split="train")
        r   NzwRFDETRDataModule._show_samples() requires visualization dependencies. Install them with `pip install 'rfdetr[visual]'`.)Úbox_cxcywh_to_xyxyzcount must be positive, got rX   zcolumns must be positive, got rZ   z)figure_size must contain two values, got r'   z)figure_size values must be positive, got zCould not build dataset split z for visualization.)g:ÜŸ�wñ Àg’$I’$I ÀgŠgE#ßü¿)g!:ÜŸ�w@g·mÛ¶mÛ@grÇqÇ@)ÚmeanÚstdr   )Úfigsize)ÚdtypeéÿÿÿÿÚoffF)Ústrictg        g      ð?éÿ   ÚsizeéþÿÿÿÚboxes)r   é   Úlabels)r   Úmasks)ÚxyxyÚclass_idÚmask)ÚsceneÚ
detections)Ú	thicknessgš™™™™™Ù?)Ú
text_scaleÚtext_padding)rµ   r¶   r°   Ú	keypoints.).rZ   Úvisible)ÚxyÚkeypoint_confidencer³   r»   rF   rž   )Úradius)rµ   Ú
key_pointsú[ú]é
   )Úfontsize)8Úmatplotlib.pyplotÚpyplotÚnumpyÚsupervisionÚtorchvision.transformsÚ
transformsrP   Úrfdetr.utilities.box_opsr£   r)   r+   Ú_get_dataset_for_visualizationÚRuntimeErrorÚ	NormalizeÚmaxÚminÚsubplotsÚasarrayÚobjectÚreshapeÚaxisÚclass_namesÚzipÚrangeÚ_source_image_pathÚdetachrM   ÚascontiguousarrayÚclipÚ	transposeÚastypeÚuint8ÚgetÚ
isinstancer-   ÚTensorrH   ÚshapeÚzerosÚfloat32Úint64ÚnumelÚtensorÚ
Detectionsr   ÚMaskAnnotatorÚannotateÚBoxAnnotatorÚLabelAnnotatorÚ	KeyPointsÚVertexAnnotatorÚimshowÚnameÚ	set_titleÚ_ellipsize_sample_titleÚtight_layout)-r4   r¡   r‚   rŸ   r    ÚpltÚnpÚsvÚTÚerrr£   r#   Úinv_normalizeÚrowsÚfigureÚaxesÚ
axes_arrayrÔ   rÕ   Úsample_indexÚimage_tensorÚtargetÚ
image_pathÚimageÚimage_arrayrµ   r¬   ÚheightÚwidthr®   r°   Úscaler²   Ú	class_idsÚmasks_tensorÚ
mask_arrayr¶   r³   Úlabels_textrº   Úkeypoints_arrayÚkeypoint_xyÚkeypoint_visibilityr¿   Útitles-                                                r   Ú_show_sampleszRFDETRDataModule._show_samplesp  s-  € ð@		Ý+ÛÛ$Ý.õ 	@à�AŠ:ÜÐ;¸E¸7À!ÐDÓEÐEØ�aŠ<ÜÐ=¸g¸YÀaÐHÓIÐIØÐ"Ü�;Ó 1Ò$Ü Ð#LÈ[ÈMÐYZÐ![Ó\Ð\Ø˜1‰~ Ò" k°!¡n¸Ò&9Ü Ð#LÈ[ÈMÐYZÐ![Ó\Ð\à×5Ñ5°eÓ<ˆØˆ?ÜÐ!?À¸yÐH[Ð\Ó]Ð]àŸ™ÚAÚ1ð $ó 
ˆô �1”s˜5¤# g£,Ó/°'Ñ9¸AÑ=À'ÑIÓJˆØ—|‘| D¨'¸;Ò;aÈ1ÈwÉ;ÐXYÐ\`ÑX`ÐJa�|Ób‰ˆ�Ø—Z‘Z ¬F�ZÓ3×;Ñ;¸BÓ?ˆ
Øò 	ˆDØ�I‰I�eÕð	ð ×&Ñ&ˆÜ"% j´%¼¸EÄ3ÀwÃ<Ó8PÓ2QÐZ_Ô"`ó 8	ÑˆD�,Ø#*¨<Ñ#8Ñ ˆL˜&Ø×0Ñ0°¸,ÓGˆJÙ! ,Ó/ˆEØŸ,™,›.×,Ñ,Ó.×4Ñ4Ó6ˆKØ×(Ñ(¨"¯'©'°+×2GÑ2GÈÈ1ÈaÓ2PÐRUÐWZÓ*[Ð^aÑ*a×)iÑ)iÐjl×jrÑjrÓ)sÓtˆEà—:‘:˜fÓ%ˆDÜ˜$¤§¡Ô-Ü # D¨¡G£¬c°$°q±'«l˜‘ä # L×$6Ñ$6°rÑ$:Ó ;¼SÀ×ASÑASÐTVÑAWÓ=X˜�à—J‘J˜w¬¯©°FÄ%Ç-Á-Ô(PÓQˆEØ—Z‘Z ¬%¯+©+°dÄ%Ç+Á+Ô*NÓOˆFØ�{‰{‹}˜qÓ ÜŸ™ e¨V°U¸FÐ%CÌ5Ï=É=ÔY�Ù)¨%¯,©,«.×*<Ñ*<Ó*>Ó?À%ÑG�Ø"ŸM™M›O×/Ñ/Ó1×7Ñ7Ó9×@Ñ@ÄÓE�	Ø%Ÿz™z¨'Ó2�ð $Ð/°L×4FÑ4FÓ4HÈ1Ò4Lð !×'Ñ'Ó)×-Ñ-Ó/×5Ñ5Ô7àð ð
  Ÿ]™]°·
±
³×0CÑ0CÀBÇJÁJÓ0OÐZcÐjt˜]Óu�
ð %.öà ð .9Ð-DÈÔTWÐXcÓTdÒId�K Ò)ÔjmÐnvÓjwÑwð�ð ð Ð)Ø×,Ñ,Ó.×7Ñ7¸eÐPZÐ7Ó[�EØŸ™°!˜Ó4×=Ñ=ÀEÐV`Ð=Óa�Ø×)Ñ)°SÀqÐ)ÓI×RÑRØØ)Ø&ð Só �ð Ÿ
™
 ;Ó/ˆIØÑ$¨¯©Ó):¸QÓ)>Ø"+×"2Ñ"2Ó"4×"8Ñ"8Ó":×"@Ñ"@Ó"B×"IÑ"IÈ"Ï*É*Ó"U�Ø-¨c°2°A°2¨gÑ6¸¿¹ÀUÈFÀOÐ[]×[eÑ[e¸Ó9fÑf�Ø&5°fÑ&=ÀÑ&AÐ#ØŸ\™\Ø"Ø(;×(BÑ(BÀ2Ç:Á:Ó(NØ#Ÿ]™]›_×0Ñ0Ó2×8Ñ8Ó:×AÑAÄ#ÓFØ/Ø#Ð%8Ð9ð *ó �
ð ×*Ñ*°!Ð*Ó4×=Ñ=ÀEÐV`Ð=Óa�à�K‰K˜ÔØ'1Ð'=�J—O’OÀeÀWÈAÈlÈ^Ð[\ÐC]ˆEØ�N‰N˜4×7Ñ7¸Ó>ÈˆNÔLØ�I‰I�eÖðq8	ðt 	×ÑÔØˆøôy ò 	ÜðDóð ðûð	üòvs   ‚Y( Ð6'ZÙ(	ZÙ1Y=Ù=Zr  Ú
max_lengthc                 ó†   — t        | «      |k  r| S |dk  rd|z  S t        d|dz
  dz  «      }|dz
  |z
  }| d| › d| | d › �S )a‚  Shorten long sample titles so subplot grids do not overflow.

        Args:
            title: Raw title text, usually an image file name.
            max_length: Maximum returned character count including the ellipsis.

        Returns:
            Original title when it already fits, otherwise a middle-ellipsized
            string that preserves the start and file suffix.
        rž   rX   r'   rZ   Nz...)r+   rÎ   )r  r  Ú	keep_leftÚ
keep_rights       r   rò   z(RFDETRDataModule._ellipsize_sample_titleó  sm   € ô ˆu‹:˜Ò#ØˆLØ˜Š?Ø˜Ñ#Ð#Ü˜˜J¨™N¨qÑ0Ó1ˆ	Ø !‘^ iÑ/ˆ
Ø˜
˜Ð#Ð$ C¨¨z¨k¨lÐ(;Ð'<Ð=Ð=r    c                 óì   — |dk(  r| j                  d«       | j                  S |dk(  r| j                  d«       | j                  S |dk(  r| j                  d«       | j                  S t	        d|›d�«      ‚)z7Return a built dataset split for private visualization.ru   rt   rv   rw   rx   zUnsupported split rX   )rƒ   r_   r`   ra   r)   )r4   r‚   s     r   rË   z/RFDETRDataModule._get_dataset_for_visualization  sw   € ð
 �GÒØ�J‰J�uÔØ×&Ñ&Ð&Ø�EŠ>Ø�J‰J�zÔ"Ø×$Ñ$Ð$Ø�FŠ?Ø�J‰J�vÔØ×%Ñ%Ð%ÜÐ-¨e¨Y°aÐ8Ó9Ð9r    r#   rþ   c                 ó²   — t        | dd«      }t        | dd«      }t        | dd«      }|�|�|€y||   }|j                  |«      d   }t        |«      |d   z  S )z:Return a source image path for common COCO-style datasets.ÚrootNÚidsÚcocor   Ú	file_name)r’   ÚloadImgsr   )r#   rþ   Úimage_folderÚ	image_idsr  Úimage_idÚ
image_infos          r   rØ   z#RFDETRDataModule._source_image_path  sr   € ô ˜w¨°Ó5ˆÜ˜G U¨DÓ1ˆ	Ü�w ¨Ó-ˆØÐ 9Ð#4¸¸ØØ˜\Ñ*ˆØ—]‘] 8Ó,¨QÑ/ˆ
Ü�LÓ! J¨{Ñ$;Ñ;Ð;r    c                 óv  — | j                   j                  }|dk(  ry|dk(  r&t        «       st        j	                  d«       y	 ddl}n|dk(  rt        «       st        d«      ‚	 ddl}dd
lm	}m
}  || j                   j                  �| j                   j                  nt        | j                  j                  | j                  j                  ¬«      | _         |«       | _        t        j%                  d|«       y# t        $ r t        j	                  d«       Y yw xY w# t        $ r}t        d	«      |‚d}~ww xY w)aX  Resolve augmentation backend and build the Kornia pipeline if applicable.

        Called once during ``setup("fit")``.  When ``augmentation_backend`` is ``"cpu"`` this is a no-op.  For
        ``"auto"`` the method falls back silently when CUDA or Kornia are unavailable.  For ``"gpu"`` missing
        requirements raise hard errors.
        rM   NrL   zFaugmentation_backend='auto': no CUDA, falling back to CPU augmentationr   zIaugmentation_backend='auto': kornia not installed, using CPU augmentationrN   z1augmentation_backend='gpu' requires a CUDA devicezLGPU augmentation requires kornia. Install with: pip install 'rfdetr[kornia]')Úbuild_kornia_pipelineÚbuild_normalize)Ú
with_masksz3Kornia GPU augmentation pipeline built (backend=%s))rV   r|   r   rŽ   ÚwarningrO   rP   rÌ   Ú!rfdetr.datasets.kornia_transformsr   r!  Ú
aug_configr   rU   r{   Úsegmentation_headrb   rc   r�   )r4   rJ   rQ   rø   r   r!  s         r   r~   z'RFDETRDataModule._setup_kornia_pipeline#  s  € ð ×#Ñ#×8Ñ8ˆØ�eÒØà�fÒÜ#Ô%Ü—‘ÐgÔhØðÜ*ð ˜ÒÜ#Ô%Ü"Ð#VÓWÐWðÛ*÷ 	]á 5Ø,0×,=Ñ,=×,HÑ,HÐ,TˆD×Ñ×(Ò(ÔZdØ×Ñ×(Ñ(Ø×(Ñ(×:Ñ:ô!
ˆÔñ
 "1Ó!2ˆÔÜ�‰ÐIÈ7ÕSøô+ ò Ü—‘ÐjÔkÙðûô ò Ü!Øbóàðûðús*   ÁC: Á#D Ã:DÄDÄ	D8Ä'D3Ä3D8ÚbatchÚdataloader_idxc                 óÞ  — | j                   �"| j                   j                  r| j                  €|S ddlm}m}m} ddlm} |\  }}|j                  }	| j                  j                  |	j                  «       | j                  j                  |	j                  «        |||	j                  «      \  }
}| j                  j                  rz|	j                  dd \  }} |||	j                  |j                  d   ||¬«      }| j                  |	|
|«      \  }}}| j                  |«      } ||||g|j                  dd ¢­d|iŽ}n>| j                  |	|
«      \  }}| j                  |«      } ||||g|j                  dd ¢­Ž }|j                  dd \  }}|D ]A  }|d	   }|j!                  «       dk(  rŒ|j#                  ||||g«      }t%        |«      |z  |d	<   ŒC  |||j&                  «      |f}|S )
a€  Apply Kornia GPU augmentation after the batch is transferred to device.

        When ``_kornia_pipeline`` is set and the trainer is in training mode, augmentation and normalization are applied
        on the GPU.  Validation and test batches pass through unchanged.

        Segmentation models use a mask-aware pipeline (``with_masks=True``) so images, boxes, and per-instance masks are
        augmented in sync.

        Args:
            batch: Tuple of ``(NestedTensor, list[dict])`` already on device.
            dataloader_idx: Index of the current dataloader.

        Returns:
            The (possibly augmented) batch.
        Nr   )Úcollate_boxesÚcollate_masksÚunpack_boxes)ÚNestedTensorr­   r'   )Ún_maxÚimage_heightÚimage_widthÚ	masks_augr®   )r‘   Útrainingrb   r$  r*  r+  r,  Úrfdetr.utilities.tensorsr-  ÚtensorsÚtoÚdevicerc   rU   r&  râ   ræ   Ú
new_tensorr   r´   )r4   r'  r(  r*  r+  r,  r-  ÚsamplesÚtargetsÚimgÚboxes_paddedÚvalidr/  r0  Úmasks_paddedÚimg_augÚ	boxes_augr1  r  r  r   r®   r  s                          r   Úon_after_batch_transferz(RFDETRDataModule.on_after_batch_transferK  sð  € ð  �<‰<Ð t§|¡|×'<Ò'<À×@UÑ@UÐ@]ØˆLç`Ñ`Ý9à Ñˆ�Ø�o‰oˆð 	×Ñ× Ñ  §¡Ô,Ø×Ñ×!Ñ! #§*¡*Ô-Ù+¨G°S·Z±ZÓ@Ñˆ�eà×Ñ×.Ò.Ø(+¯	©	°"°#¨Ñ%ˆL˜+Ù(Ø˜Ÿ™¨5¯;©;°q©>ÈÐbmôˆLð -1×,AÑ,AÀ#À|ÐUaÓ,bÑ)ˆG�Y 	Ø×,Ñ,¨WÓ5ˆGÙ" 9¨e°WÐg¸w¿}¹}ÈRÈSÐ?QÒgÐ]fÑg‰Gà!%×!6Ñ!6°s¸LÓ!IÑˆG�YØ×,Ñ,¨WÓ5ˆGÙ" 9¨e°WÐR¸w¿}¹}ÈRÈSÐ?QÒRˆGàŸ™ b cÐ*‰ˆ�Øò 	@ˆFØ˜7‘OˆEØ�{‰{‹} Ò!ØØ×$Ñ$ e¨V°U¸FÐ%CÓDˆEÜ0°Ó7¸%Ñ?ˆF�7ŠOð	@ñ ˜g w§|¡|Ó4°gÐ>ˆØˆr    c                 ó&  — | j                   | j                  fD ]ñ  }|€Œt        |dd«      }|€Œt        |d«      sŒ#t        |dd«      }|€t        |dd«      }t	        |t
        «      ra|r_t        |«      }dg|dz   z  }t        |j                  «       «      D ]+  \  }}|j                  j                  |«      }|€Œ$|d   ||<   Œ- |c S t        |j                  j                  «       «      D �	cg c]  }	|j                  |	   d   ‘Œ c}	c S  yc c}	w )aa  Class names from the training or validation dataset annotation file.

        Reads category names from the first available COCO-style dataset. Returns ``None`` if no dataset has been set up
        yet or the dataset does not expose COCO-style category information.

        Returns:
            Sorted list of class name strings, or ``None``.
        Nr  ÚcatsÚ	label2catÚ r'   rð   )r_   r`   r’   Úhasattrrà   ÚdictrÎ   ÚsortedÚitemsrB  rß   Úkeys)
r4   r#   r  rC  Ú	max_labelÚnamesÚlabelÚcategory_idÚcategoryÚks
             r   rÕ   zRFDETRDataModule.class_names„  s  € ð ×+Ñ+¨T×->Ñ->Ð?ò 	PˆGØˆØÜ˜7 F¨DÓ1ˆDØÑ¤G¨D°&Õ$9Ü# G¨[¸$Ó?�	ØÐ$Ü '¨¨k¸4Ó @�IÜ˜i¬Ô.±9Ü # I£�IØ˜D I°¡MÑ2�EÜ.4°Y·_±_Ó5FÓ.Gò <Ñ*˜˜{Ø#'§9¡9§=¡=°Ó#=˜Ø#Ñ/Ø+3°FÑ+;˜E %šLð<ð !’LÜ6<¸T¿Y¹Y¿^¹^Ó=MÓ6NÖO°˜Ÿ	™	 !™ VÓ,ÒOÒOð!	Pð" ùò Ps   Ã.Dr6  c                 óþ   — |\  }}|j                   dk(  }|j                  ||¬«      }|D ���	cg c]7  }|j                  «       D ��	ci c]  \  }}	||	j                  ||¬«      “Œ c}	}‘Œ9 }}}}	||fS c c}	}w c c}	}}w )aæ  Move a ``(NestedTensor, targets)`` batch to *device*.

        PTL's default iterates tuple elements and calls ``.to(device)``; that works for plain tensors but
        ``NestedTensor`` must be moved explicitly.

        Args:
            batch: Tuple of (NestedTensor samples, list of target dicts).
            device: Target device.
            dataloader_idx: Index of the dataloader providing this batch.

        Returns:
            Batch with all tensors on ``device``.
        r   )Únon_blocking)Útyper5  rH  )
r4   r'  r6  r(  r8  r9  rQ  ÚtrO  Úvs
             r   Útransfer_batch_to_devicez)RFDETRDataModule.transfer_batch_to_device¡  s€   € ð !Ñˆ�Ø—{‘{ fÑ,ˆØ—*‘*˜V°,�*Ó?ˆØ_f×gÐgÐZ[È1Ï7É7Ë9×UÁ4À1Àa�A�q—t‘t˜F°�tÓ>Ñ>ÕUÐgˆÒgØ˜ÐÐùó VùÔgs   ®A8ÁA2Á$A8Á2A8)ru   )é0   )r   N)&rA   rB   rC   rD   r   r   r9   r   rƒ   r   r“   r˜   r›   r�   rH   r   ÚtupleÚfloatr  Ústaticmethodrò   r-   rE   rF   rG   rË   r   rØ   r~   r	   r@  Úpropertyr   r   rÕ   r6  rU  Ú__classcell__)rq   s   @r   rT   rT   Œ   s×  ø„ ñð7) [ð 7)Àð 7)ÐPTõ 7)ðz-I˜3ð -I 4ó -Ið^8
 *ó 8
ðt
 
ó 
ð$
 ó 
ð$
 Jó 
ð* 29ðAð
 Ø26òAàðAð Ð-Ñ.ðAð
 ðAð ˜5 %˜<Ñ(¨4Ñ/ðAð 
óAðF ñ> sð >¸ð >ÀSò >ó ð>ð&:àÐ-Ñ.ð:ð 
�‰×	Ñ	×	!Ñ	! DÑ	(ó:ð  ð	< E§K¡K×$4Ñ$4×$<Ñ$<ð 	<ÈCð 	<ÐTXÐ[_ÑT_ò 	<ó ð	<ó&TðP3¨Uð 3ÀCð 3ÈEó 3ðr ð˜X d¨3¡iÑ0ò ó ðð8 ¨eð  ¸U¿\¹\ð  Ð[^ð  Ðch÷  r    rT   )+rD   Úpathlibr   Útypingr   r   r   r   r   r	   r-   Útorch.utils.dataÚpytorch_lightningr
   r   Úrfdetr._namespacer   r   r   r   Úrfdetr.datasetsr   Úrfdetr.datasets.aug_configsr   rÊ   r   Úrfdetr.utilities.loggerr   r3  r   rŽ   r�   Úmatplotlib.figurer   rj   r   rE   rF   rG   r"   r   rR   rT   rI   r    r   ú<module>re     s”   ðñ Hå ß E× Eã Û Ý 1Ý 'å 5ß 2Ý )Ý 2Ý 7Ý .Ý 4á	‹€àÐ áÝ(ð*˜$ó *ô=*˜eŸk™k×.Ñ.×6Ñ6ô =*ð@¨3ð °3ó ôBg Ð*õ g r    