B
    ¨d:"  ã               @   sR   d dl mZmZmZ d dlmZ d dlmZ d dlZd dl	m
Z
 G dd„ dƒZdS )é    )Úabsolute_importÚdivisionÚprint_function)Úflex)ÚfloorN)Úrangec               @   sX   e Zd Zedd„ ƒZdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )Ú	NDimTablec             C   s4  t | tƒrt| dƒ} tƒ }t d|  ¡ ¡ d¡|_t	t d|  ¡ ¡ d¡ƒ|_
|  ¡  g |_g |_g |_g |_g |_t d¡}xÜt|j
ƒD ]Î}| |  ¡ ¡}|j t| d¡ƒ¡ |j t| d¡ƒ¡ |j t	| d¡ƒ¡ | d¡ ¡  ¡ }|d	ks|d
ks|dks|dkr&|j d¡ n|j d¡ |j |j| |j|  |j|  ¡ qŠW t t |j¡d¡|_t d|  ¡ ¡rŠd}nd}|  ¡ }x˜|r.| ¡ }t|ƒ|j
krºq˜|rêt|d ƒ}	dd„ |d|j
d … D ƒ}
n&t||j
 ƒ}	dd„ |d|j
… D ƒ}
| | |
¡|	¡ |  ¡ }q˜W |S )z…Loads rotamer or Ramachandran data from a text file, returning a new object.

        Can pass in either a file handle or a file nameÚrz
: +"(.+)"$é   z	: +(\d+)$z&: +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+)$é   é   é   ÚtrueÚyesÚonÚ1TFr   Úfirstc             S   s   g | ]}t |ƒ‘qS © )Úfloat)Ú.0Úfldr   r   úx/mnt/filia/a/genomebrowser/www/genomebrowser/fleming/tools/molprobity/modules/cctbx_project/mmtbx/rotamer/n_dim_table.pyú
<listcomp>=   s    z,NDimTable.createFromText.<locals>.<listcomp>c             S   s   g | ]}t |ƒ‘qS r   )r   )r   r   r   r   r   r   @   s    )Ú
isinstanceÚstrÚopenr   ÚreÚsearchÚreadlineÚgroupZourNameÚintÚnDimÚminValÚmaxValÚnBinsÚdoWrapÚwBinÚcompiler   Úappendr   ÚlowerÚstripr   ÚgridÚlookupTableÚsplitÚlenÚ
setValueAtÚwhereIs)ÚinfileÚndtZdata_reÚiÚmatchr%   Z
valueFirstÚsÚfieldsÚvalÚcoordsr   r   r   ÚcreateFromText   sN    


( *  zNDimTable.createFromTextc          	   C   sV   g }xLt | jƒD ]>}| ttt|| | j|  | j|  ƒ| j| d ƒƒ¡ qW |S )z2Given a set of coordinates, return the bin indicesr
   )	r   r!   r(   r    Úminr   r"   r&   r$   )Úselfr8   Úbinr3   r   r   r   r0   G   s    >zNDimTable.whereIsc             C   s   || j |  |¡< dS )z-Given bin indices, set the value in the tableN)r,   Ú	bin2index)r;   r<   r7   r   r   r   r/   O   s    zNDimTable.setValueAtc             C   s    d}xZt | jd ƒD ]H}|  || |¡}|dk s>|| j| krBdS ||7 }|| j|d  9 }qW | jd }|  || |¡}|dk s|| j| kr”dS ||7 }|S )z>Given bin indices, return a single index into the linear arrayr   r
   éÿÿÿÿ)r   r!   Úwrapbinr$   )r;   r<   Úidxr3   ÚiBinr   r   r   r=   T   s     
 zNDimTable.bin2indexc             C   sœ   d}xXt | jd ƒD ]F}|  || |¡}|  d|| j| d ¡}||7 }|| j|d  9 }qW | jd }|  || |¡}|  d|| j| d ¡}||7 }|S )z™Given bin indices, return a single index into the linear array.

        If no bin can be found after wrapping is applied, the edge of the table is used.r   r
   )r   r!   r?   ÚclampInclusiver$   )r;   r<   r@   r3   rA   r   r   r   Úbin2index_limitc   s    
zNDimTable.bin2index_limitc             C   s   t |t||ƒƒS )z>Forces theVal into the range from minVal to maxVal (inclusive))Úmaxr:   )r;   r"   ZtheValr#   r   r   r   rB   s   s    zNDimTable.clampInclusivec             C   s    | j | r|| j|  S |S dS )z>Wrap bin indices for each dimension in which it is appropriateN)r%   r$   )r;   rA   Údimr   r   r   r?   x   s    
zNDimTable.wrapbinc             C   sB   g }x8t | jƒD ]*}| | j| | j| || d   ¡ qW |S )zDReturns coordinates for the center of the bin given by these indicesg      à?)r   r!   r(   r"   r&   )r;   r<   Úptr3   r   r   r   ÚcenterOf„   s    *zNDimTable.centerOfc             C   s,  d}|   |¡}|  |¡}g }g }dg| j }xlt| jƒD ]^}|| || k r`| || d ¡ n| || d ¡ | t|| ||  | j|  ƒ¡ q8W xŒtd| j> ƒD ]z}	d}
xXt| jƒD ]J}|	d|> @ dkrð|| ||< |
d||  9 }
q¾|| ||< |
|| 9 }
q¾W ||
| j|  |¡  7 }qªW |S )a´  Estimates the value of the density trace at a given position,
        using linear interpolation.

        This algorithm basically consults the 2^n bins nearest in space to
        the input point, and weights their contributions according to their
        distances.

        To get a feeling for how it works, work out a linear interpolation in
        one dimension
        ( a...x.......b -- what is x in terms of a and b? )(trivial)
        and then in two dimensions (still fairly easy -- do one dimension
        first, then interpolate between those results).

        In dimensions very near the edge of the table, no interpolation is
        performed in that dimension
        (it would be impossible to do so, anyway, because there's no 2nd
        value to interpolate out *to*).

        pt - the point at which the value should be estimated
        returns - the approximate value of the density trace at the specified
        pointr   r
   g      ð?)	r0   rG   r!   r   r(   Úabsr&   r,   rC   )r;   rF   ÚvalueZva_homeZva_home_ctrZva_neighborZ
va_contribZ
va_currentrE   r<   Úcoeffr   r   r   ÚvalueAtŒ   s*    

 (zNDimTable.valueAtN)Ú__name__Ú
__module__Ú__qualname__Ústaticmethodr9   r0   r/   r=   rC   rB   r?   rG   rK   r   r   r   r   r      s   /r   )Ú
__future__r   r   r   Úscitbx.array_familyr   Úmathr   r   Ú	six.movesr   r   r   r   r   r   Ú<module>   s
   