o
    ϯi'                     @  s
  d dl mZ d dl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mZ d dlmZ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 eeZd4d
dZ	d5d6ddZ d7ddZ!G dd dej"j#j$Z%d8d!d"Z&G d#d$ d$Z'	%d9d:d,d-Z(d;d2d3Z)dS )<    )annotationsN)defaultdict)Fieldfieldfields)AnyCallableDictIterableListTupleUnion)	g_pathmgrdatatorch.Tensorreturnc                 C  s   |  ddddS )zd
    Permute tensor from (time, height, weight, channel) to
    (channel, height, width, time).
       r         )permute)r    r   K/home/ubuntu/.local/lib/python3.10/site-packages/pytorchvideo/data/utils.pythwc_to_cthw   s   r   floortime_in_secondsfloat	time_base	start_ptsint
round_modestrc                 C  sT   | t jkrt jS |dv sJ d| d|dkr!t | | | S t | | | S )z
    Converts a time (in seconds) to the given time base and start_pts offset
    presentation time. Round_mode specifies the mode of rounding when converting time.

    Returns:
        pts (int): The time in the given time base.
    )r   ceilzround_mode=z is not supported!r   )mathinfr   r!   )r   r   r   r   r   r   r   secs_to_pts   s   
r$   ptsc                 C  s    | t jkrt jS t| | | S )z
    Converts a present time with the given time base and start_pts offset to seconds.

    Returns:
        time_in_seconds (float): The corresponding time in seconds.
    )r"   r#   r   )r%   r   r   r   r   r   pts_to_secs6   s   
r&   c                   @  s"   e Zd ZdZdddZdd	 Zd
S )MultiProcessSamplerz
    MultiProcessSampler splits sample indices from a PyTorch Sampler evenly across
    workers spawned by a PyTorch DataLoader.
    samplertorch.utils.data.Samplerr   Nonec                 C  s
   || _ d S N)_sampler)selfr(   r   r   r   __init__I   s   
zMultiProcessSampler.__init__c           	      C  s   t jj }|durT|jdkrTtt| j}t	||j}|j
}|| }t|dkr>td|j dt| j d tdS |d }|d d }tt| j||}|S t| j}|S )	zj
        Returns:
            Iterator for underlying PyTorch Sampler indices split by worker id.
        Nr   zMore data workers(z) than videos(z3). For optimal use of processes reduce num_workers.r   r   )torchutilsr   get_worker_infonum_workersrangelenr,   nparray_splitidloggerwarningiter	itertoolsislice)	r-   worker_infovideo_indexesworker_splits	worker_idworker_split
iter_startiter_endworker_samplerr   r   r   __iter__L   s&   

zMultiProcessSampler.__iter__N)r(   r)   r   r*   )__name__
__module____qualname____doc__r.   rF   r   r   r   r   r'   C   s    
r'   targetr   args_iterableIterable[Tuple]multithreadedboolc                 C  s^   |r$g }|D ]}t j| |d}|  || q|D ]}|  qdS |D ]}| |  q&dS )a  
    Applies 'target' function to each Tuple args in 'args_iterable'.
    If 'multithreaded' a thread is spawned for each function application.

    Args:
        target (Callable):
            A function that takes as input the parameters in each args_iterable Tuple.

        args_iterable (Iterable[Tuple]):
            An iterable of the tuples each containing a set of parameters to pass to
            target.

        multithreaded (bool):
            Whether or not the target applications are parallelized by thread.
    )rK   argsN)	threadingThreadstartappendjoin)rK   rL   rN   threadsrP   threadtr   r   r   optional_threaded_foreachl   s   

rY   c                   @  s,   e Zd ZdZdZdddZedd
dZdS )DataclassFieldCasterz
    Class to allow subclasses wrapped in @dataclass to automatically
    cast fields to their relevant type by default.

    Also allows for an arbitrary intialization function to be applied
    for a given field.
    )DataclassFieldCaster__complex_initializerr   r*   c                 C  s   d| j  d t| D ]Q}t| |j}t||jrtj |jv r\tj |jv rRt| |j|jtj  | tt| |j|jsQJ d|j d|j dtt| |j qt| |j|| qd S )Na  
        This function is run by the dataclass library after '__init__'.

        Here we use this to ensure all fields are casted to their declared types
        and to apply any complex field_initializer functions that have been
        declared via the 'complex_initialized_dataclass_field' method of
        this class.

        A complex field_initializer for a given field would be stored in the
        field.metadata dictionary at:
            key = 'z&' (self.COMPLEX_INITIALIZER)

        z 'field_initializer' function of z must return type z but returned type )	COMPLEX_INITIALIZERdataclass_fieldsgetattrname
isinstancetyperZ   metadatasetattr)r-   r   valuer   r   r   __post_init__   s0   


z"DataclassFieldCaster.__post_init__field_initializerr   r   c                 K  s<   | dpi }tj|vsJ | |tj< ||d< tdi |S )u  
        Allows for the setting of a function to be called on the
        named parameter associated with a field during initialization,
        after __init__() completes.

        Args:
            field_initializer (Callable):
                The function to be called on the field

            **kwargs: To be passed downstream to the dataclasses.field method

        Returns:
            (dataclasses.Field) that contains the field_initializer and kwargs infoÎ
        rb   Nr   )getrZ   r\   dataclass_field)rf   kwargsrb   r   r   r   #complex_initialized_dataclass_field   s
   
z8DataclassFieldCaster.complex_initialized_dataclass_fieldN)r   r*   )rf   r   r   r   )rG   rH   rI   rJ   r\   re   staticmethodrj   r   r   r   r   rZ      s    
&rZ   Finput_csv_file_pathdataclass_classra   dict_key_fieldlist_per_key Dict[Any, Union[Any, List[Any]]]c           	        s   |rt tni }t| P}tj|ddd}dd tt|D  |D ]1| fddt|D  }t	||}|rB|| 
| q#||vsPJ d| d	| |||< q#W d
   |S 1 s`w   Y  |S )a  
    Args:
        input_csv_file_path (str): File path of the csv to read from
        dataclass_class (type): The dataclass to read each row into.
        dict_key_field (str): The field of 'dataclass_class' to use as
            the dictionary key.
        list_per_key (bool) = False: If the output data structure
        contains a list of dataclass objects per key, rather than a
        single unique dataclass object.

    Returns:
        Dict[Any, Union[Any, List[Any]] mapping from the dataclass
        value at attr = dict_key_field to either:

        if 'list_per_key', a list of all dataclass objects that
        have equal values at attr = dict_key_field, equal to the key

        if not 'list_per_key', the unique dataclass object
        for which the value at attr = dict_key_field is equal to the key

    Raises:
        AssertionError: if not 'list_per_key' and there are
        dataclass obejcts with equal values at attr = dict_key_field
    ,"	delimiter	quotecharc                 S  s   i | ]\}}||qS r   r   ).0iheaderr   r   r   
<dictcomp>       z0load_dataclass_dict_from_csv.<locals>.<dictcomp>c                 3  s    | ]
} |j   V  qd S r+   r_   )rv   r   column_indexliner   r   	<genexpr>   s
    
z/load_dataclass_dict_from_csv.<locals>.<genexpr>zMultiple entries for z in N)r   listr   opencsvreader	enumeratenextr]   r^   rT   )	rl   rm   rn   ro   output_dictdataclass_filer   datumdict_keyr   r|   r   load_dataclass_dict_from_csv   s,   



r   dataclass_objs	List[Any]	file_namer*   c                   s   t | d }dd t|D }t|d'}tj|ddd}|| | D ] | fdd|D  q%W d	   d	S 1 s?w   Y  d	S )
z
    Saves a list of @dataclass objects to the specified csv file.

    Args:
        dataclass_objs (List[Any]):
            A list of @dataclass objects to be saved.

        file_name (str):
            file_name to save csv data to.
    r   c                 S  s   g | ]}|j qS r   r{   rv   fr   r   r   
<listcomp>  s    z7save_dataclass_objs_to_headered_csv.<locals>.<listcomp>wrq   rr   rs   c                   s   g | ]}t  |qS r   )r^   r   objr   r   r     rz   N)ra   r]   r   r   r   writerwriterow)r   r   dataclass_typefield_namesr   r   r   r   r   #save_dataclass_objs_to_headered_csv  s   
"r   )r   r   r   r   )r   )
r   r   r   r   r   r   r   r    r   r   )r%   r   r   r   r   r   r   r   )rK   r   rL   rM   rN   rO   )F)
rl   r    rm   ra   rn   r    ro   rO   r   rp   )r   r   r   r    r   r*   )*
__future__r   r   r<   loggingr"   rQ   collectionsr   dataclassesr   r   rh   r   r]   typingr   r   r	   r
   r   r   r   numpyr6   r0   iopath.common.file_ior   	getLoggerrG   r9   r   r$   r&   r1   r   Samplerr'   rY   rZ   r   r   r   r   r   r   <module>   s.   $



)!N5