
    ^jl"                    "   U d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
mZ ddlmZ ddlmZmZmZ ddlmZ ddlZddlZdd	lmZ dd
lmZ  e       ZerddlZddddZdZded<   ddZddZ ddZ! G d d      Z"ddZ#e
ddd       Z$y)zPrivate developer tools for testing and benchmarking RF-DETR.

These utilities are intended for internal use by developers and test suites. They are not part of the public API and may
change without notice.
    )annotationsN)	Generator)contextmanagersuppress)Path)TYPE_CHECKINGAnyLiteral)urlretrieve)Image)
get_loggerz0http://images.cocodataset.org/zips/train2017.zipz.http://images.cocodataset.org/zips/val2017.zipzFhttp://images.cocodataset.org/annotations/annotations_trainval2017.zip)	train2017val2017r   i  int_COCO_VAL_IMAGE_COUNTc                r    | j                         syt        d | j                         D              t        k\  S )a  Check whether the COCO val2017 image directory contains the expected number of JPEG files.

    Returns ``False`` for a missing or empty directory so callers can trigger a
    re-download without inspecting the directory manually.

    Args:
        images_dir: Path to the directory that should contain the val2017 images.

    Returns:
        ``True`` if *images_dir* exists and contains at least ``_COCO_VAL_IMAGE_COUNT``
        ``.jpg`` files, ``False`` otherwise.

    Raises:
        OSError: If *images_dir* exists but cannot be read (e.g. ``PermissionError``
            when the directory is not accessible, or ``FileNotFoundError`` on a
            TOCTOU race between the ``is_dir()`` check and ``iterdir()``).

    Examples:
        >>> import tempfile
        >>> with tempfile.TemporaryDirectory() as tmpdir:
        ...     _coco_val_images_complete(Path(tmpdir) / "val2017")
        False
    Fc              3  ~   K   | ]5  }|j                         s|j                  j                         d k(  s2d 7 yw)z.jpg   N)is_filesuffixlower).0entrys     c/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/datasets/_develop.py	<genexpr>z,_coco_val_images_complete.<locals>.<genexpr>F   s-     f%5==?u||GYGYG[_eGeAfs   ===)is_dirsumiterdirr   )
images_dirs    r   _coco_val_images_completer    +   s7    0 f:--/ff 	!    c                    	 | j                         xr | j                         j                  dkD  S # t        $ r Y yw xY w)a"  Check whether a file exists and contains at least one byte.

    Returns ``False`` for a missing or empty file so callers can trigger a
    re-download without inspecting the file manually.

    Args:
        path: Path to the file to check.

    Returns:
        ``True`` if *path* refers to an existing file with ``size > 0``,
        ``False`` otherwise.

    Examples:
        >>> import tempfile
        >>> with tempfile.TemporaryDirectory() as tmpdir:
        ...     _nonempty_file_exists(Path(tmpdir) / "missing.json")
        False
    r   F)r   statst_sizeOSError)paths    r   _nonempty_file_existsr'   K   s;    &||~9$))+"5"5"99 s   .1 	==c                    t         |    S )zCReturn the official COCO 2017 download URL for the requested asset.)
_COCO_URLS)assets    r   get_coco_download_urlr+   d   s    er!   c                  *    e Zd ZdZdddZddZd	dZy)
_SimpleDatasetaH  Simple synthetic dataset for testing augmentations and training loops.

    Creates synthetic images with varying numbers of bounding boxes to test edge cases in augmentation pipelines,
    particularly the case where num_boxes=2 (which matches orig_size shape [2]).

    Implements the ``__len__`` / ``__getitem__`` protocol expected by ``torch.utils.data.DataLoader`` without inheriting
    from ``torch.utils.data.Dataset``, so importing this class does not pull in torch at module load time.

    Args:
        num_samples: Number of samples in the dataset.
        transforms: Optional transforms to apply (e.g., Compose of AlbumentationsWrapper).

    Examples:
        >>> from albumentations import HorizontalFlip
        >>> from torchvision.transforms.v2 import Compose
        >>> from rfdetr.datasets.transforms import AlbumentationsWrapper
        >>>
        >>> transforms = Compose([
        ...     AlbumentationsWrapper(HorizontalFlip(p=0.5)),
        ... ])
        >>> dataset = _SimpleDataset(num_samples=10, transforms=transforms)
        >>> image, target = dataset[0]
    Nc                     || _         || _        y N)num_samples
transforms)selfr0   r1   s      r   __init__z_SimpleDataset.__init__   s    &$r!   c                    | j                   S r/   )r0   )r2   s    r   __len__z_SimpleDataset.__len__   s    r!   c           
     B   t        j                  dd      }|dz  dz   }g }g }t        |      D ]E  }d|dz  z   }d|dz  z   }|dz   }	|dz   }
|j                  |||	|
g       |j                  |dz          G t	        j
                  |t        j                  	      t	        j
                  |t        j                  	      t	        j
                  d
dg      t	        j
                  d
dg      t	        j
                  |g      t	        j
                  dg|z        t	        j
                  dg|z        d}| j                  r| j                  ||      \  }}t	        j                  t        j                  |            j                  ddd      j                         dz  }||fS )NRGB)       r   
   d   2   P   )dtyper9   r8   g      Y@r   )boxeslabels	orig_sizesizeimage_idareaiscrowd   g     o@)r   newrangeappendtorchtensorfloat32int64r1   
from_numpynparraypermutefloat)r2   idximage	num_boxesr@   rA   ix1y1x2y2targets               r   __getitem__z_SimpleDataset.__getitem__   sn   		%, 1WM	y! 	!Aa#gBa"fBbBcBLL"b"b)*MM!a% 	! \\%u}}=ll6=sCj1LL#s,cU+LL%9!45||QC)O4
 ?? OOE6:ME6   %199!QBHHJURf}r!   )r;   N)r0   r   r1   z
Any | NonereturnNone)r^   r   )rT   r   r^   z#tuple[torch.Tensor, dict[str, Any]])__name__
__module____qualname____doc__r3   r5   r]    r!   r   r-   r-   i   s    0% #r!   r-   c           	        |j                  dd       || j                  dd      d   z  }t        j                  d|        t	        | t        |             t        j                  d|       |j                         }t        j                  t        |      d      5 }|j                         D ]  }|j                  s||j                  z  j                         }|j                  |      st        d	|j                        |j                         r|j                  dd       z|j                  j                  dd       |j                  |d      5 }t        |d
      5 }t!        j"                  ||       ddd       ddd        	 ddd       t%        t&              5  |j)                          ddd       y# 1 sw Y   ExY w# 1 sw Y   'xY w# 1 sw Y   KxY w# 1 sw Y   yxY w)zDownload a zip file and safely extract it into the destination directory.

    Args:
        url: URL to a zip archive.
        dest_dir: Directory where the archive will be saved and extracted.
    Tparentsexist_ok/r   zDownloading %s ...zExtracting %s ...rz"Unsafe path detected in ZIP file: wbN)mkdirrsplitloggerinfor   strresolvezipfileZipFileinfolistfilenameis_relative_toRuntimeErrorr   parentopenshutilcopyfileobjr   FileNotFoundErrorunlink)	urldest_dirzip_pathdest_dir_resolvedzfmembertarget_pathsrcdsts	            r   _download_and_extractr      s    NN4$N/#**S!,R00H
KK$c*S]#
KK#X. ((*	X	, 1kkm 	1F??,v>GGIK--.?@"%GGZ#[\\}}!!$!>""(((EWWVS) 1S${D2I 1S&&sC01 1 1	11 
#	$  1 1 1 11 1 sI   B:GG
#F>	:G

G$G#>GG

GGG #G,c              #    K   | j                   j                  dd       t        j                         }	 	 t        j                  | t        j
                  t        j                  z  t        j                  z        }t        j                  |       	 	 d t        t              5  t        j                  |        ddd       y# t        $ r@ t        j                         |z
  |kD  rt        d|        t        j                  |       Y nw xY w# 1 sw Y   yxY w# t        t              5  t        j                  |        ddd       w # 1 sw Y   w xY wxY ww)a  Provide a simple cross-process lock using an exclusive lock file.

    Args:
        lock_path: Path to the lock file used for mutual exclusion.
        timeout_s: Maximum time in seconds to wait for the lock.
        poll_s: Sleep interval in seconds between lock attempts.

    Yields:
        None. The caller runs inside the locked region.

    Raises:
        TimeoutError: If the lock cannot be acquired within the timeout.

    Note:
        Lock identity is file existence (``O_CREAT | O_EXCL``), not a held file descriptor.
        A SIGKILL-terminated process will leak the lock file until ``timeout_s`` expires.
        If all worker processes have exited but the lock persists, remove it manually:
        ``rm <lock_path>``.
    Trf   zTimed out waiting for lock: N)ry   rm   timeosrz   O_CREATO_EXCLO_WRONLYcloseFileExistsErrorTimeoutErrorsleepr   r}   r~   )	lock_path	timeout_spoll_sstartfds        r   _download_lockr      s    * 4$7IIKE
	BJJ$:R[[$HIBHHRL
! '( 	!IIi 	! 	!  	yy{U"Y."%A)#MNNJJv	 	! 	!X'( 	!IIi 	! 	! 	!sr   3EAC ED E&D<	EADEDEDEE.E	EEEE)r   r   r^   bool)r&   r   r^   r   )r*   z.Literal['train2017', 'val2017', 'annotations']r^   rq   )r   rq   r   r   r^   r_   )g     @g      ?)r   r   r   rS   r   rS   r^   zGenerator[None, Any, None])%rc   
__future__r   r   r{   r   rs   collections.abcr   
contextlibr   r   pathlibr   typingr   r	   r
   urllib.requestr   numpyrP   rK   PILr   rfdetr.util.loggerr   ro   r)   r   __annotations__r    r'   r+   r-   r   r   rd   r!   r   <module>r      s    # 	    % /  . . &    )	 D?[

 " s !@2
C CL< %! %!r!   