ó
¹™xTc           @   s_   d  d l  m Z d  d l m Z d  d l m Z d  d l Z d  d l Z d d d „  ƒ  YZ d S(   iÿÿÿÿ(   t   division(   t   flex(   t   floorNt	   NDimTablec           B   se   e  Z d  „  Z e e ƒ Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z RS(	   c         C   s  t  |  t j ƒ r$ t |  d ƒ }  n  t ƒ  } t j d |  j ƒ  ƒ j d ƒ | _	 t
 t j d |  j ƒ  ƒ j d ƒ ƒ | _ |  j ƒ  g  | _ g  | _ g  | _ g  | _ g  | _ t j d ƒ } x$t | j ƒ D]} | j |  j ƒ  ƒ } | j j t | j d ƒ ƒ ƒ | j j t | j d ƒ ƒ ƒ | j j t
 | j d ƒ ƒ ƒ | j d ƒ j ƒ  j ƒ  } | d	 k s”| d
 k s”| d k s”| d k r§| j j t ƒ n | j j t ƒ | j j | j | | j | | j | ƒ qÑ Wt j t j | j ƒ d ƒ | _ t j d |  j ƒ  ƒ r*t } n t } |  j ƒ  } xØ | r|  j ƒ  } | j ƒ  } t | ƒ | j k rxq?n  | r¾t | d ƒ }	 g  | d | j d !D] }
 t |
 ƒ ^ q£} n< t | | j ƒ }	 g  | d | j !D] }
 t |
 ƒ ^ qâ} | j | j | ƒ |	 ƒ q?W| S(   s…   Loads rotamer or Ramachandran data from a text file, returning a new object.

        Can pass in either a file handle or a file namet   rs
   : +"(.+)"$i   s	   : +(\d+)$s&   : +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+)$i   i   i   t   truet   yest   ont   1i    t   first(    t
   isinstancet   typest   StringTypest   fileR   t   ret   searcht   readlinet   groupt   ourNamet   intt   nDimt   minValt   maxValt   nBinst   doWrapt   wBint   compilet   ranget   appendt   floatt   lowert   stript   Truet   FalseR   t   gridt   lookupTablet   splitt   lent
   setValueAtt   whereIs(   t   infilet   ndtt   data_ret   it   matchR   t
   valueFirstt   st   fieldst   valt   fldt   coords(    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyt   createFromText   sN    	$*
					0 1! 		 0)c         C   sk   g  } x^ t  |  j ƒ D]M } | j t t t | | |  j | |  j | ƒ |  j | d ƒ ƒ ƒ q W| S(   s2   Given a set of coordinates, return the bin indicesi   (	   R   R   R   R   t   minR   R   R   R   (   t   selfR2   t   binR+   (    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyR'   H   s    Kc         C   s   | |  j  |  j | ƒ <d S(   s-   Given bin indices, set the value in the tableN(   R#   t	   bin2index(   R5   R6   R0   (    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyR&   P   s    c         C   sÐ   d } xs t  |  j d ƒ D]^ } |  j | | | ƒ } | d k  sU | |  j | k rY d S| | 7} | |  j | d 9} q W|  j d } |  j | | | ƒ } | d k  s¾ | |  j | k rÂ d S| | 7} | S(   s>   Given bin indices, return a single index into the linear arrayi    i   iÿÿÿÿ(   R   R   t   wrapbinR   (   R5   R6   t   idxR+   t   iBin(    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyR7   U   s     
 
c         C   sÊ   d } xp t  |  j d ƒ D][ } |  j | | | ƒ } |  j d | |  j | d ƒ } | | 7} | |  j | d 9} q W|  j d } |  j | | | ƒ } |  j d | |  j | d ƒ } | | 7} | S(   s™   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.i    i   (   R   R   R8   t   clampInclusiveR   (   R5   R6   R9   R+   R:   (    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyt   bin2index_limitd   s     
 
c         C   s   t  | t | | ƒ ƒ S(   s>   Forces theVal into the range from minVal to maxVal (inclusive)(   t   maxR4   (   R5   R   t   theValR   (    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyR;   t   s    c         C   s$   |  j  | r | |  j | S| Sd S(   s>   Wrap bin indices for each dimension in which it is appropriateN(   R   R   (   R5   R:   t   dim(    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyR8   y   s    c         C   sO   g  } xB t  |  j ƒ D]1 } | j |  j | |  j | | | d ƒ q W| S(   sD   Returns coordinates for the center of the bin given by these indicesg      à?(   R   R   R   R   R   (   R5   R6   t   ptR+   (    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyt   centerOf…   s    /c         C   sx  d } |  j  | ƒ } |  j | ƒ } g  } g  } d g |  j } x‚ t |  j ƒ D]q } | | | | k  r‚ | j | | d ƒ n | j | | d ƒ | j t | | | | |  j | ƒ ƒ qP Wx¬ t d |  j >ƒ D]— }	 d }
 xj t |  j ƒ D]Y } |	 d | >@d k r2| | | | <|
 d | | 9}
 qõ | | | | <|
 | | 9}
 qõ W| |
 |  j |  j | ƒ 7} qÙ W| S(   s|  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 pointi    i   g      ð?(	   R'   RA   R   R   R   t   absR   R#   R<   (   R5   R@   t   valuet   va_homet   va_home_ctrt   va_neighbort
   va_contribt
   va_currentR?   R6   t   coeff(    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyt   valueAt�   s*     ."(   t   __name__t
   __module__R3   t   staticmethodR'   R&   R7   R<   R;   R8   RA   RJ   (    (    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyR      s   	,							(    (	   t
   __future__R    t   scitbx.array_familyR   t   mathR   R   R   R   (    (    (    sG   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/rotamer/n_dim_table.pyt   <module>   s
   