ó
M™xTc           @   s+  d  Z  d d l m Z d d l m Z d d l m Z m Z d d l m	 Z	 d d l
 m Z d d l m Z d „  Z d	 e f d
 „  ƒ  YZ d „  Z d „  Z d d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z e d k r'e ƒ  d GHn  d S(   sE  
This code has been specifically developed for the detection of
reticular twin laws. It is a very simple implementation of rotational groups
using the boost rationals. Since reticular twin laws typically have matrix elements
that cannot be handled by the current cctbx implementation, some code duplication was
unavoidable.

iÿÿÿÿ(   t   division(   t   sgtbx(   t   cosetst   sub_lattice_tools(   t   matrix(   t   rational(   t   ifloorc         C   sY   d d d g d „ } |  } | | d d !ƒ d | | d d !ƒ d | | d ƒ } | S(	   Nt   ht   kt   lc         S   s‹  d } d } xxt  |  | ƒ D]g\ } } d } | t j d ƒ k ry| d 7} | t j d ƒ k rç | d k rŸ | t j d ƒ k rŒ | } qŸ t | ƒ | } n  | d k rç | t j d ƒ k rÍ d | } qä d t | ƒ | } qç n  | t j d ƒ k  ry| d k r=| t j d ƒ k r*d | } qst | ƒ | } qv| t j d ƒ k rc| d | 7} qvt | ƒ | } qyn  | | 7} q W| S(   Nt    i    i   t   +iÿÿÿÿt   -(   t   zipR   t   intt   str(   t   rowt   txtt   resultt   partt   nt   jt   nn(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt
   row_as_hkl   s2    
	i    i   t   ,i   (    (   t   opR   t   hklmatt   hkl(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   as_hkl   s     :t   rat_rot_groupc           B   s;   e  Z d  „  Z d e d „ Z d „  Z d „  Z d „  Z RS(   c         C   sš   t  j t j d ƒ t j d ƒ t j d ƒ t j d ƒ t j d ƒ t j d ƒ t j d ƒ t j d ƒ t j d ƒ g	 ƒ |  _ |  j g |  _ d |  _ d  S(   Ni   i    id   (   R   t   sqrR   R   t   unitt   opst   max_ops(   t   self(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   __init__8   s    c         C   s÷   | d  k r |  j d } n  |  j | ƒ s> |  j j | ƒ n  t } x¬ | sò g  } xP |  j D]E } | | } | rƒ | G| G| GHn  |  j | ƒ s] | j | ƒ q] q] Wt | ƒ d k rÁ t } n |  j | |  _ t |  j ƒ |  j k sG t ‚ qG Wd  S(   Ni    (	   t   NoneR    t   is_in_groupt   appendt   Falset   lent   TrueR!   t   AssertionError(   R"   t   new_opt   showt   donet   new_opsR   t   pno(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   expandG   s"    	
	c         C   s3   t  } x& |  j D] } | | k r t } q q W| S(   N(   R'   R    R)   (   R"   t   this_opt   insideR   (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyR%   [   s
    c         C   sH   g  } x2 |  j  D]' } | j ƒ  | | } | j | ƒ q W| |  _  d  S(   N(   R    t   inverseR&   (   R"   t   cb_opR.   R   R+   (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   change_basisb   s
    c         C   s)   x" |  j  D] } t | j ƒ  ƒ GHq
 Wd  S(   N(   R    R   t	   transpose(   R"   R   (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyR,   i   s    N(	   t   __name__t
   __module__R#   R$   R'   R0   R%   R5   R,   (    (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyR   7   s
   			c         C   sL   |  j  ƒ  } g  } x* | D]" } | j t j t | ƒ ƒ ƒ q Wt j | ƒ S(   N(   t   numR&   R   R   R   R   R   (   t   rot_matt   tmp_matt   rational_listt   ij(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   rt_mx_as_rationalo   s
     c         C   s}   |  j  ƒ  j ƒ  j ƒ  } |  j  ƒ  j ƒ  j ƒ  } g  } x1 | D]) } | j t j | ƒ t j | ƒ ƒ q= Wt j | ƒ j	 ƒ  S(   N(
   t   ct   rR9   t   denR&   R   R   R   R   R3   (   R4   R9   RA   R<   t   ii(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   cb_op_as_rationalw   s    'c         C   s„   t  ƒ  } | d  k r3 t j d ƒ } t | ƒ } n  x- |  D]% } t | j ƒ  ƒ } | j | ƒ q: W| j | ƒ | j d t	 ƒ | S(   Ns   a,b,cR,   (
   R   R$   R   t   change_of_basis_opRC   R>   R@   R0   R5   R'   (   t   space_groupR4   t   grt   st   tmp_r(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   construct_rational_point_group�   s    	c         C   sƒ   t  |  j ƒ t  | j ƒ k r{ t } xP |  j D]E } t } x' | j D] } | | k rD t } PqD qD W| s. t } q. q. W| St Sd  S(   N(   R(   R    R)   R'   (   t   sg1t   sg2t   equalt   op1t   this_onet   op2(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   compare_groupsŽ   s    c         C   sƒ   t  |  j ƒ t  | j ƒ k  r{ t } xP |  j D]E } t } x' | j D] } | | k rD t } PqD qD W| s. t } q. q. W| St Sd  S(   N(   R(   R    R)   R'   (   t   subt   supert   subgRM   RN   RO   (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   is_subgroup�   s    c         C   sc   g  } xV | j  D]K } t } x& |  j  D] } | | k r& t } q& q& W| s | j | ƒ q q W| S(   N(   R    R'   R)   R&   (   t   old_sgt   new_sgR.   t   nopt   found_itt   oop(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   extra_operators¬   s    c         C   sc   g  } xV | j  D]K } t } x& |  j  D] } | | k r& t } q& q& W| r | j | ƒ q q W| S(   N(   R    R'   R)   R&   (   RU   RV   t
   common_opsRW   RX   RY   (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   recurring_operators¸   s    c         C   s`   t  t |  | ƒ ƒ } t  t |  | ƒ ƒ } t  | j ƒ } t  |  j ƒ } | | k rX t St Sd  S(   N(   R(   RZ   R\   R    R'   R)   (   RU   RV   t   not   cot   all_nt   all_o(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   is_reticular_polyholohedralÄ   s    c         C   sÍ   g  } xC |  D]; } g  } x | D] } | j  | | ƒ q  W| j  | ƒ q Wg  } xt | D]l } t } xG | D]? }	 t g t | ƒ }
 x# | D] } | |	 k rŒ t } qŒ qŒ Wql W| rY | j  | ƒ qY qY W| S(   N(   R&   R)   R'   R(   (   t   gR   t   setst   giR   t   hit   unique_setst   sett	   is_uniquet
   unique_sett   found_it_arrayR   (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyR   Ï   s"    c         C   sv   t  |  | ƒ } t |  | ƒ } t | ƒ d k r4 d  St | j | ƒ } g  } x# | d D] } | j | d ƒ qW W| S(   Ni    i   (   RZ   R\   R(   R$   R   R    R&   (   RU   RV   R.   R[   R   t   reprRg   (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   build_reticular_twin_lawsó   s    c          C   s  t  t j d ƒ j ƒ  ƒ }  t  t j d ƒ j ƒ  ƒ } t |  | ƒ } t | ƒ d k s] t ‚ x, | D]$ } t | j ƒ  ƒ d k sd t ‚ qd Wt  t j d ƒ j ƒ  ƒ }  t  t j d ƒ j ƒ  ƒ } t |  | ƒ } t | ƒ d k sé t ‚ x, | D]$ } t | j ƒ  ƒ d k sð t ‚ qð Wd  S(   Ns   P 2 2 2s   P 4 2 2 (a,b,2c)i   s   k,-h,ls   P 4 2 2(	   RI   R   t   space_group_infot   groupRl   R(   R*   R   R6   (   RJ   RK   R   RB   (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   tst_build_reticular_twin_laws  s    "c          C   sÆ   t  t j d ƒ j ƒ  ƒ }  t  t j d ƒ j ƒ  ƒ } t  t j d ƒ j ƒ  ƒ } t  t j d ƒ j ƒ  ƒ } t |  | ƒ s� t ‚ t |  | ƒ s— t ‚ t |  | ƒ s­ t ‚ t |  | ƒ sÂ t ‚ d  S(   Ns   P 2 2 2s   P 4 2 2s   P 2 2 2 (a+b,a-b,2c)(   RI   R   Rm   Rn   RP   R*   RT   (   RJ   RK   t   sg3t   sg4(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   tst_compare  s    c    	      C   sÙ   t  j d ƒ }  t  j d ƒ } t j d ƒ j ƒ  } xŸ t |  | ƒ D]Ž \ } } | } d  } y t j d | ƒ j ƒ  } Wn t k
 r‹ n Xt	 | | ƒ } d  } | d  k	 rC t	 | ƒ } t
 | | ƒ sÑ t ‚ qC qC Wd  S(   Ni   s   P 2 2 2s   P 2 2 2 (%s)(   R   t   generate_cb_op_up_to_ordert   generate_matrix_up_to_orderR   Rm   Rn   R   R$   t	   ExceptionRI   RP   R*   (	   t   cb_opst   matst
   base_groupR4   t   matt	   rat_cb_opt   extended_groupt   rbgt   reg(    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt
   tst_groups   s     c           C   s   t  ƒ  t ƒ  t ƒ  d  S(   N(   R~   Rr   Ro   (    (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   run0  s    t   __main__t   OKN(    t   __doc__t
   __future__R    t   cctbxR   t   cctbx.sgtbxR   R   t   scitbxR   t   boostR   t   libtbx.math_utilsR   R   t   objectR   R>   RC   R$   RI   RP   RT   RZ   R\   Ra   Rl   Ro   Rr   R~   R   R7   (    (    (    sL   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/cctbx/sgtbx/reticular_pg_tools.pyt   <module>   s2   	%8		
						$					