o
    wi3                     @   sf   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	 ddl
mZ dd ZG dd	 d	ZdS )
    N   )compute_curve)figure_to_image)make_npc                    s    fdd}|S )Nc                    s4   | j std |   d S  | g|R i | d S )Nz+ERROR: No Visdom server currently connected)server_connectedprint_try_connect)selfargskwargsfn W/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/tensorboardX/visdom_writer.pywrapper   s
   z"_check_connection.<locals>.wrapperr   )r   r   r   r   r   _check_connection   s   r   c                   @   s   e Zd Zdd Zdd Zed+ddZed,d	d
Zedd Zed-ddZ	ed.ddZ
ed/ddZed0ddZed1ddZed,ddZedd Zed2d d!Zed3d"d#Zed4d%d&Ze	d4d'd(Zd)d* ZdS )5VisdomWriterc                 O   sV   zddl m} W n ty   tdw i | _d| _||i || _i | _|   d S )Nr   )Visdomz4Visdom visualization requires installation of VisdomF)visdomr   ImportErrorscalar_dictr   viswindowsr   )r	   r
   r   r   r   r   r   __init__   s   zVisdomWriter.__init__c                 C   s\   d}| j  | _| js%|dkr%td |d8 }| j  | _| js%|dks| js,J dd S )Nr   r   g?z%No connection could be formed quickly)r   check_connectionr   timesleep)r	   startup_secr   r   r   r   '   s   
zVisdomWriter._try_connectNdefaultc                 C   s   | j |du ri | j |< | j | |du}|r#| j | | |g n|g| j | |< | d| }|r6|nt| j | | }|rU| jjt|t||d| j| d dS | jjt|t|||d|dd| j|< dS )aN  Add scalar data to Visdom. Plots the values in a plot titled
           {main_tag}-{tag}.

        Args:
            tag (string): Data identifier
            scalar_value (float or string/blobname): Value to save
            global_step (int): Global step value to record
            main_tag (string): Data group identifier
        N-append)XYnameupdatewintimesteptitlexlabelylabelr!   r"   r#   opts)r   getlenr   liner   r   )r	   tagscalar_valueglobal_stepmain_tagexists	plot_namex_valr   r   r   
add_scalar0   s8   

	zVisdomWriter.add_scalarc                 C   s"   |D ]}|  ||| || qdS )a?  Adds many scalar data to summary.

        Note that this function also keeps logged scalars in memory. In extreme case it explodes your RAM.

        Args:
            tag (string): Data identifier
            main_tag (string): Data group identifier
            tag_scalar_dict (dict): Key-value pair storing the tag and corresponding values
            global_step (int): Global step value to record

        Examples::

            writer.add_scalars('run_14h',{'xsinx':i*np.sin(i/r),
                                          'xcosx':i*np.cos(i/r),
                                          'arctanx': numsteps*np.arctan(i/r)}, i)
            This function adds three plots:
                'run_14h-xsinx',
                'run_14h-xcosx',
                'run_14h-arctanx'
            with the corresponding values.
        N)r7   )r	   r3   tag_scalar_dictr2   keyr   r   r   add_scalarsY   s   zVisdomWriter.add_scalarsc                 C   sB   t |d}t| j| W d   n1 sw   Y  i | _dS )a  Exports to the given 'path' an ASCII file containing all the scalars written
        so far by this instance, with the following format:
        {writer_id : [[timestamp, step, value], ...], ...}

        The scalars saved by ``add_scalars()`` will be flushed after export.
        wN)openjsondumpr   )r	   pathfr   r   r   export_scalars_to_jsons   s   
z#VisdomWriter.export_scalars_to_json
tensorflowc                 C   s$   t |}| jjt |d|id dS )a  Add histogram to summary.

        Args:
            tag (string): Data identifier
            values (torch.Tensor, numpy.array, or string/blobname): Values to build histogram
            global_step (int): Global step value to record
            bins (string): one of {'tensorflow', 'auto', 'fd', ...}, this determines how the bins are made. You can find
              other options in: https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html
        r(   r,   N)r   r   	histogram)r	   r0   valuesr2   binsr   r   r   add_histogram   s   zVisdomWriter.add_histogramc                 C   s"   t |}| jj|||dd dS )a  Add image data to summary.

        Note that this requires the ``pillow`` package.

        Args:
            tag (string): Data identifier
            img_tensor (torch.Tensor, numpy.array, or string/blobname): Image data
            global_step (int): Global step value to record
        Shape:
            img_tensor: :math:`(C, H, W)`. Use ``torchvision.utils.make_grid()`` to prepare it is a good idea.
            C = colors (can be 1 - grayscale, 3 - RGB, 4 - RGBA)
        )r(   captionrC   N)r   r   image)r	   r0   
img_tensorr2   rH   r   r   r   	add_image   s   zVisdomWriter.add_imageTc                 C   s   |  |t||| dS )a  Render matplotlib figure into an image and add it to summary.

        Note that this requires the ``matplotlib`` package.

        Args:
            tag (string): Data identifier
            figure (matplotlib.pyplot.figure) or list of figures: figure or a list of figures
            global_step (int): Global step value to record
            close (bool): Flag to automatically close the figure
        N)rK   r   )r	   r0   figurer2   closer   r   r   
add_figure   s   zVisdomWriter.add_figure   c           
   
   C   s   |j }t|dkrst|d D ]a}t|tjr6ddl}|||ddddddddf dddd}n||ddddddddf dddd}d}	|	 }||	 
tj}|j d dv sfJ d	| jj|d
|id qdS | jj|d
|id dS )a^  Add video data to summary.

        Note that this requires the ``moviepy`` package.

        Args:
            tag (string): Data identifier
            vid_tensor (torch.Tensor): Video data, the pixel value should in [0, 1]
            global_step (int): Global step value to record
            fps (float or int): Frames per second
        Shape:
            vid_tensor: :math:`(B, C, T, H, W)`. (if following tensorboardX format)
            vid_tensor: :math:`(T, H, W, C)`. (if following visdom format)
            B = batches, C = colors (1, 3, or 4), T = time frames, H = height, W = width
        rO   r   Nr            )r   rQ   rO   z_Visdom requires the last dimension to be color, which can be 1 (grayscale), 3 (RGB) or 4 (RGBA)fpstensorr,   )shaper.   range
isinstancenpndarraytorch
from_numpypermutenumpyastypeuint8r   video)
r	   r0   
vid_tensorr2   rS   rV   ir[   ind_vidscale_factorr   r   r   	add_video   s(    .zVisdomWriter.add_videoD  c                 C   s    t |}| jj|d|id dS )az  Add audio data to summary.

        Args:
            tag (string): Data identifier
            snd_tensor (torch.Tensor, numpy.array, or string/blobname): Sound data
            global_step (int): Global step value to record
            sample_rate (int): sample rate in Hz

        Shape:
            snd_tensor: :math:`(1, L)`. The values should lie between [-1, 1].
        sample_frequencyrT   N)r   r   audio)r	   r0   
snd_tensorr2   sample_rater   r   r   	add_audio   s   zVisdomWriter.add_audioc                 C   s   |du r|}| j | dS )aM  Add text data to summary.

        Args:
            tag (string): Data identifier
            text_string (string): String to save
            global_step (int): Global step value to record
        Examples::
            writer.add_text('lstm', 'This is an lstm', 0)
            writer.add_text('rnn', 'This is an rnn', 10)
        N)r   text)r	   r0   text_stringr2   r   r   r   add_text   s   zVisdomWriter.add_textc                 C      d S Nr   )r	   prototxtr   r   r   add_onnx_graph      zVisdomWriter.add_onnx_graphFc                 K   rp   rq   r   )r	   modelinput_to_modelverboser   r   r   r   	add_graph   rt   zVisdomWriter.add_graphc                 C   rp   rq   r   )r	   matmetadata	label_imgr2   r0   metadata_headerr   r   r   add_embedding   rt   zVisdomWriter.add_embedding   c           
      C   sh   t |t |}}t||||}|dddf |dddf }}	| jj|	||d| dddd dS )	a  Adds precision recall curve.

        Args:
            tag (string): Data identifier
            labels (torch.Tensor, numpy.array, or string/blobname): Ground truth data. Binary label for each element.
            predictions (torch.Tensor, numpy.array, or string/blobname):
            The probability that an element be classified as true. Value should in [0, 1]
            global_step (int): Global step value to record
            num_thresholds (int): Number of thresholds used to draw the curve.

        rO   N   PR Curve for recall	precisionr'   r+   )r   r   r   r/   )
r	   r0   labelspredictionsr2   num_thresholdsweightsraw_datar   r   r   r   r   add_pr_curve  s   "
zVisdomWriter.add_pr_curvec                 C   s8   t |t |}}| jj|||d| dddd dS )a  Adds precision recall curve with raw data.

        Args:
            tag (string): Data identifier
            true_positive_counts (torch.Tensor, numpy.array, or string/blobname): true positive counts
            false_positive_counts (torch.Tensor, numpy.array, or string/blobname): false positive counts
            true_negative_counts (torch.Tensor, numpy.array, or string/blobname): true negative counts
            false_negative_counts (torch.Tensor, numpy.array, or string/blobname): false negative counts
            precision (torch.Tensor, numpy.array, or string/blobname): precision
            recall (torch.Tensor, numpy.array, or string/blobname): recall
            global_step (int): Global step value to record
            num_thresholds (int): Number of thresholds used to draw the curve.
            see: https://github.com/tensorflow/tensorboard/blob/master/tensorboard/plugins/pr_curve/README.md
        r   r   r   r'   r+   N)r   r   r/   )r	   r0   true_positive_countsfalse_positive_countstrue_negative_countsfalse_negative_countsr   r   r2   r   r   r   r   r   add_pr_curve_raw#  s   
zVisdomWriter.add_pr_curve_rawc                 C   s   | ` | `t  d S rq   )r   r   gccollect)r	   r   r   r   rM   D  s   zVisdomWriter.close)Nr   rq   )NrB   )NN)NT)NrO   )Nrg   )NF)NNNr   N)Nr~   N)__name__
__module____qualname__r   r   r   r7   r:   rA   rG   rK   rN   rf   rl   ro   rs   rx   r}   r   r   rM   r   r   r   r   r      sB    	(
&
 r   )r   r=   mathr   r^   rY   summaryr   utilsr   x2numr   r   r   r   r   r   r   <module>   s    
