U
    `
                     @   s   d Z ddlZddlZddlZddl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  mZ ddlmZ ddlZddlmZ ddlmZ ddlmZ dZG dd dZd	d
 Zdd Zdd Zdd ZdddZdd Z dd Z!dS )zL
General utility functions

Author: Shengyu Huang
Last modified: 30.11.2020
    N)Rotation)NearestNeighbors)	minkowskigHz>c                   @   s$   e Zd Zdd Zdd Zdd ZdS )Loggerc                 C   s   || _ t| j d d| _d S )Nz/loga)pathopenfw)selfr    r   '/workspace/OverlapPredator/lib/utils.py__init__   s    zLogger.__init__c                 C   s   | j | | j   d S N)r	   writeflush)r
   textr   r   r   r      s    zLogger.writec                 C   s   | j   d S r   )r	   close)r
   r   r   r   r      s    zLogger.closeN)__name__
__module____qualname__r   r   r   r   r   r   r   r      s   r   c              	   C   s&   t |d}t| | W 5 Q R X dS )z,
    save a dictionary to a pickle file
    wbN)r   pickledump)objr   fr   r   r   save_obj    s    r   c              
   C   s,   t | d}t|W  5 Q R  S Q R X dS )z.
    read a dictionary from a pickle file
    rbN)r   r   load)r   r   r   r   r   load_obj'   s    r   c              	   C   sV   t | d}t|}W 5 Q R X t }| D ]"\}}| D ]\}}|||< q>q.|S )z
    Loads config file:

    Args:
        path (str): path to the config file

    Returns: 
        config (dict): dictionary of the configuration parameters, merge sub_dicts

    r)r   yamlZ	safe_loaddictitems)r   r   cfgconfigkeyvaluekvr   r   r   load_config.   s    r)   c                 C   s:   t |  t j|  tj|  t|  dt jj_	dS )z4
    fix random seed for deterministic training
    TN)
torchmanual_seedcudamanual_seed_allnprandomseedbackendscudnndeterministic)r0   r   r   r   
setup_seedD   s
    

r4   Fc              	   C   s   | j \}}}|j \}}}dt| |ddd }|r@|d7 }nP|tj| d dddddddf 7 }|tj|d dddddddf 7 }tj|ddd	}|S )
z
    Calculate Euclid distance between each two points.
    Args:
        src: source points, [B, N, C]
        dst: target points, [B, M, C]
    Returns:
        dist: per-point square distance, [B, N, M]
    r         )dimNg-q=)minmax)shaper*   matmulpermutesumclamp)srcdstZ
normalisedBN_Mdistr   r   r   square_distanceN   s    	
((rH   c                 C   sP   |   D ]B\}}|jdk	rtt|jr2 dS tt|jr dS qdS )z;
    Confirm all the gradients are non-nan and non-inf
    NFT)named_parametersgradr*   anyisnanisinf)modelnameparamr   r   r   validate_gradientd   s    
rQ   c                 C   s   dd t d| D S )z-
    Sort strings by numbers in the name
    c                 S   s    g | ]}|  rt|n|qS r   )isdigitint).0sr   r   r   
<listcomp>u   s     znatural_key.<locals>.<listcomp>z(\d+))resplit)string_r   r   r   natural_keyq   s    rZ   )F)"__doc__osrW   sysjsonr    r/   argparser*   r   torch.nnnnZtorch.nn.functional
functionalFtorch.optimoptimnumpyr.   Zscipy.spatial.transformr   Zsklearn.neighborsr   Zscipy.spatial.distancer   Z_EPSr   r   r   r)   r4   rH   rQ   rZ   r   r   r   r   <module>   s"   H

