Ë
    ¼Ó^jÝ  ã                  ó¦   — d dl m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
Zd dlmZ d dlmZ  ee«      Zg d¢Z G d„ d	e	«      Z G d
„ d«      Zy)é    )ÚannotationsN)ÚIterable)ÚAnyÚProtocol)Ú
Detections)Ú_get_logger©Úx_minÚy_minÚx_maxÚy_maxÚclass_idÚ
confidenceÚ
tracker_idc                  ó   — e Zd Zdd„Zy)ÚWriterProtocolc                 ó   — y ©N© )ÚselfÚrows     úo/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/supervision/detection/tools/csv_sink.pyÚwriterowzWriterProtocol.writerow   s   � ó    N)r   zIterable[Any]Úreturnr   )Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r      s   „ Ü6r   r   c                  ó²   — e Zd ZdZddd„Zdd„Z	 	 	 	 	 	 	 	 dd„Zdd„Zdd„Ze	dd„«       Z
e		 d	 	 	 	 	 dd	„«       Z	 d	 	 	 	 	 dd
„Ze		 d	 	 	 	 	 dd„«       Zy)ÚCSVSinkaP  
    A utility class for saving detection data to a CSV file. This class is designed to
    efficiently serialize detection objects into a CSV format, allowing for the
    inclusion of bounding box coordinates and additional attributes like `confidence`,
    `class_id`, and `tracker_id`.

    !!! tip

        CSVSink allows passing custom data alongside detection fields, providing
        flexibility for logging various types of information.
        When a list or tuple value in custom_data (or detections.data) has the
        same length as the detection count, each element is written to the
        corresponding detection row; any other value is broadcast to all rows.

    Args:
        file_name: The name of the CSV file where the detections will be stored.
            Defaults to 'output.csv'.

    Example:
        ```pycon
        >>> import supervision as sv
        >>> import numpy as np
        >>> import tempfile
        >>> import os
        >>> # Create synthetic detections
        >>> detections = sv.Detections(
        ...     xyxy=np.array([[10, 20, 30, 40], [50, 60, 70, 80]]),
        ...     confidence=np.array([0.9, 0.8]),
        ...     class_id=np.array([0, 1])
        ... )
        >>> # Use temporary file
        >>> temp_file = tempfile.NamedTemporaryFile(
        ...     mode='w', suffix='.csv', delete=False
        ... )
        >>> temp_file.close()
        >>> csv_sink = sv.CSVSink(temp_file.name)
        >>> with csv_sink as sink:
        ...     sink.append(detections, custom_data={'frame': 0})
        >>> os.unlink(temp_file.name)  # Clean up

        ```
    c                óJ   — || _         d| _        d| _        d| _        g | _        y)zr
        Initialize the CSVSink instance.

        Args:
            file_name: The name of the CSV file.
        NF)Ú	file_nameÚfileÚwriterÚheader_writtenÚfield_names)r   r"   s     r   Ú__init__zCSVSink.__init__K   s)   € ð #ˆŒØ-1ˆŒ	Ø-1ˆŒØ#ˆÔØ&(ˆÕr   c                ó&   — | j                  «        | S r   )Úopen©r   s    r   Ú	__enter__zCSVSink.__enter__X   s   € Ø�	‰	ŒØˆr   c                ó$   — | j                  «        y r   )Úclose)r   Úexc_typeÚexc_valÚexc_tbs       r   Ú__exit__zCSVSink.__exit__\   s   € ð 	�
‰
�r   c                óD  — t         j                  j                  | j                  «      }|r4t         j                  j	                  |«      st        j
                  |«       t        | j                  dd¬«      | _        t        j                  | j                  «      | _	        y)z0
        Open the CSV file for writing.
        ÚwÚ )ÚnewlineN)
ÚosÚpathÚdirnamer"   ÚexistsÚmakedirsr)   r#   Úcsvr$   )r   Úparent_directorys     r   r)   zCSVSink.opend   sc   € ô Ÿ7™7Ÿ?™?¨4¯>©>Ó:ÐÙ¤B§G¡G§N¡NÐ3CÔ$DÜ�K‰KÐ(Ô)ä˜Ÿ™¨°bÔ9ˆŒ	Ü—j‘j §¡Ó+ˆ�r   c                óR   — | j                   r| j                   j                  «        yy)z%
        Close the CSV file.
        N)r#   r-   r*   s    r   r-   zCSVSink.closeo   s   € ð �9Š9Ø�I‰I�O‰OÕð r   c                ó¸   — t        | t        j                  «      r| j                  dk(  r| S | |   S t        | t        t
        f«      rt        | «      |k(  r| |   S | S )a{  
        Return the i-th element when the value stores per-detection data.

        Dispatch rules:
            - np.ndarray with ndim == 0: return as-is for broadcasting
            - np.ndarray with ndim >= 1: return value[i]
            - list or tuple with len equal to n: return value[i]
            - any other type: return as-is for broadcasting

        Args:
            value: Custom-data field value.
            i: Zero-based detection index.
            n: Total number of detections.

        Returns:
            Element at position i if value is a per-detection sequence,
            otherwise value unchanged.
        r   )Ú
isinstanceÚnpÚndarrayÚndimÚlistÚtupleÚlen)ÚvalueÚiÚns      r   Ú_slice_valuezCSVSink._slice_valuev   sQ   € ô( �eœRŸZ™ZÔ(Ø!ŸJ™J¨!šO�5Ð9°°q±Ð9Ü�eœd¤E˜]Ô+´°E³
¸a²Ø˜‘8ˆOØˆr   Nc                óÞ  — g }t        | j                  «      }t        |«      D �]F  }| j                  |   d   | j                  |   d   | j                  |   d   | j                  |   d   | j                  €dnt	        | j                  |   «      | j
                  €dnt	        | j
                  |   «      | j                  €dnt	        | j                  |   «      dœ}t        | d«      r<| j                  j                  «       D ]  \  }}t        j                  |||«      ||<   Œ! |r2|j                  «       D ]  \  }}t        j                  |||«      ||<   Œ! |j                  |«       �ŒI |S )aK  
        Convert detections and optional custom data into per-detection rows.

        Builds one dictionary per detection containing bounding box coordinates,
        detection attributes, and any values from ``detections.data`` or
        ``custom_data``. List and tuple values in ``custom_data`` with length
        equal to ``len(detections.xyxy)`` are sliced one element per row; all
        other values are broadcast to every row.

        Args:
            detections: Detection data to serialize into row dictionaries.
            custom_data: Optional extra fields to include in each row.

        Returns:
            A list of dictionaries, one per detection, containing ``xyxy``
            coordinates, ``class_id``, ``confidence``, ``tracker_id``, and any
            values from ``detections.data`` or ``custom_data``.
        r   é   é   é   r4   r	   Údata)rE   ÚxyxyÚranger   Ústrr   r   ÚhasattrrN   Úitemsr    rI   Úappend)Ú
detectionsÚcustom_dataÚparsed_rowsrH   rG   r   ÚkeyrF   s           r   Úparse_detection_datazCSVSink.parse_detection_data�   sz  € ð, ˆÜ�
—‘Ó ˆÜ�q“ó 	$ˆAà#Ÿ™¨Ñ+¨AÑ.Ø#Ÿ™¨Ñ+¨AÑ.Ø#Ÿ™¨Ñ+¨AÑ.Ø#Ÿ™¨Ñ+¨AÑ.à×&Ñ&Ð.ñ ä˜×,Ñ,¨QÑ/Ó0à×(Ñ(Ð0ñ !ä˜×.Ñ.¨qÑ1Ó2à×(Ñ(Ð0ñ !ä˜×.Ñ.¨qÑ1Ó2ñˆCô  �z 6Ô*Ø",§/¡/×"7Ñ"7Ó"9ò A‘J�C˜Ü&×3Ñ3°E¸1¸aÓ@�C˜’HðAñ Ø"-×"3Ñ"3Ó"5ò A‘J�C˜Ü&×3Ñ3°E¸1¸aÓ@�C˜’HðAð ×Ñ˜sÖ#ð3	$ð4 Ðr   c           
     ó  — | j                   st        d| j                  › d�«      ‚t        j	                  ||«      }| j
                  s)|| _        | j                   j                  |«       d| _        || j                  k7  r!t        j                  d| j                  |«       t        j                  ||«      }|D ]E  }| j                   j                  | j                  D �cg c]  }|j                  |d«      ‘Œ c}«       ŒG yc c}w )aÜ  
        Append detection data to the CSV file.

        Args:
            detections: The detection data.
            custom_data: Custom data to include. Scalars, dictionaries, and
                other non-sequence values are broadcast to every detection in
                this batch. NumPy arrays, lists, and tuples with length equal
                to ``len(detections)`` are sliced per detection; other lists
                and tuples are broadcast unchanged.
        z Cannot append to CSV: The file 'z' is not open.Tz<Field names do not match the header. Expected: %s, given: %sr4   N)r$   Ú	Exceptionr"   r    Úparse_field_namesr%   r&   r   ÚloggerÚwarningrY   Úget)r   rU   rV   r&   rW   r   Ú
field_names          r   rT   zCSVSink.appendÄ   sè   € ð �{Š{ÜØ2°4·>±>Ð2BÀ.ÐQóð ô ×/Ñ/°
¸KÓHˆØ×"Ò"Ø*ˆDÔØ�K‰K× Ñ  Ô-Ø"&ˆDÔà˜$×*Ñ*Ò*Ü�N‰NØNØ× Ñ Øôô ×2Ñ2°:¸{ÓKˆØò 	ˆCØ�K‰K× Ñ Ø;?×;KÑ;KÖL¨Z�—‘˜ RÕ(ÒLõñ	ùâLs   ÃD
c           
     ó¾   — |rt        |j                  «       «      n	t        «       }t        |t        t        | di «      j                  «       «      z  «      }t        |z   S )NrN   )ÚsetÚkeysÚsortedÚgetattrÚBASE_HEADER)rU   rV   Úcustom_keysÚdynamic_headers       r   r\   zCSVSink.parse_field_namesé   sS   € ñ 2=”c˜+×*Ñ*Ó,Ô-Ä#Ã%ˆÜØœ#œg j°&¸"Ó=×BÑBÓDÓEÑEó
ˆô ˜^Ñ+Ð+r   )z
output.csv)r"   rQ   r   ÚNone)r   r    )r.   ztype | Noner/   zException | Noner0   z
Any | Noner   ri   )r   ri   )rF   r   rG   ÚintrH   rj   r   r   r   )rU   r   rV   údict[str, Any] | Noner   zlist[dict[str, Any]])rU   r   rV   rk   r   ri   )rU   r   rV   rk   r   z	list[str])r   r   r   Ú__doc__r'   r+   r1   r)   r-   ÚstaticmethodrI   rY   rT   r\   r   r   r   r    r       sß   „ ñ)ôV)óðàðð "ðð ð	ð
 
óó	,óð òó ðð2 àEIð1Øð1Ø-Bð1à	ò1ó ð1ðh LPð#Ø$ð#Ø3Hð#à	ó#ðJ àEIð,Øð,Ø-Bð,à	ò,ó ñ,r   r    )Ú
__future__r   r;   Úior6   Úcollections.abcr   Útypingr   r   Únumpyr@   Úsupervision.detection.corer   Úsupervision.utils.loggerr   r   r]   rf   r   r    r   r   r   ú<module>ru      sI   ðÝ "ã 
Û 	Û 	Ý $ß  ã å 1Ý 0á	�XÓ	€ò€ô7�Xô 7÷R,ò R,r   