B
    §d÷* ã               @   s²  d dl mZmZmZ d dlmZ d dlm  mZ	 d dl
mZ d dl
mZ e	 d¡Zd dlT d dlm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 dlmZ d dlZd dl Zd dl!Z!d dl"m#Z#m$Z$ d dl%Z%d dl"m&Z' d dl(Z(d dlm)Z) d dl*Ze+ej, -¡ d ej.Z/ejj0j1Z2ejj3j4Z5G dd„ deƒZ6dddgdgdddfdd„Z7dCdd„Z8G dd„ de6ƒZ9dDd"d#„Z:e	 ;e<¡G d$d%„ d%ƒƒZ=G d&d'„ d'eƒZ>G d(d)„ d)e!j?ƒZ@G d*d+„ d+eƒZAG d,d-„ d-eƒZBG d.d/„ d/eƒZCG d0d1„ d1eƒZDG d2d3„ d3eƒZEG d4d5„ d5e!j?ƒZFe	 ;eG¡G d6d%„ d%ƒƒZ=G d7d8„ d8eƒZHd9d:„ ZIG d;d<„ d<eHƒZJG d=d>„ d>eHƒZKd?d@„ ZLdAdB„ ZMe	 NejOe	jP¡ e	 ;ejQe	jP¡ dS )Eé    )Úabsolute_importÚdivisionÚprint_function)ÚflexN)Úrange)ÚzipÚcctbx_crystal_ext)Ú*)Úfind_best_cell)Úsgtbx)Úuctbx)Ú
covarianceÚgeometry)ÚOrderedDict)Úobject)Úshared)Ústl)ÚKeepÚSorry)Ú&format_float_with_standard_uncertainty)Úmatrix)Znumber_of_bytesc               @   s¶  e Zd ZdZdndd„Zdd„ Zeedfd	d
„Zdd„ Zdd„ Z	dd„ Z
dd„ Zdodd„Zdpdd„Zdqdd„Zdd„ Zdd„ Zdd„ Zdrd#d$„Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zdsd3d4„Zdtd5d6„Zd7d8„ Zd9d:„ Zdud;d<„Zdvd=d>„Zd?d@„ Z dAdB„ Z!dCdD„ Z"dEdF„ Z#dGdH„ Z$dwdIdJ„Z%dKdL„ Z&dMdN„ Z'dxdPdQ„Z(dydRdS„Z)dTdU„ Z*dVdW„ Z+dzdZd[„Z,d\d]„ Z-d{d^d_„Z.d`da„ Z/d|ddde„Z0dfdg„ Z1dhdi„ Z2djdk„ Z3dldm„ Z4dS )}ÚsymmetryzlThis class represents the symmetry of a crystal and bundles information on its unit cell and space group.
  NFTc	             C   sª  |||g  d¡dkst‚|dk	r8t|tjjƒs8t |¡}|| _|| _| jdkr˜|dk	rftj	|d| _n2|dk	r˜t|tj
ƒrŠtj	|d| _ntj	|d| _|  ¡ dk	r¦|  	¡ dk	r¦|rD|  	¡ }	|	 ¡  ¡ }
|
dkr
|  ¡  ¡ rD|	 ¡  ¡ }| d¡rD|	 ¡ | _n:|
dkrD|  ¡  ¡ rD|	 ¡  ¡ }| d¡rD|	 ¡ | _|rŽ|r||  ¡ sŽtd	t| jƒt| j ¡ ƒf ƒ‚n|  ¡ sŽtd
ƒ‚|r¦|  
¡  | j¡| _dS )a•  Initialises a new crystal.symmetry class object from different input data. Only one of space_group, space_group_info and space_group_symbol may be used.

    :param unit_cell:          object specifying the unit_cell properties
    :type unit_cell:           cctbc.uctbx.ext.unit_cell or tuple(lattice parameters)
    :param space_group_symbol: Hermann-Mauguin symbol of the crystallographic space group
    :type space_group_symbol:  string
    :param space_group_info:   object describing the desired space group
    :type space_group_info:    cctbx.sgtbx.space_group_info
    :param space_group:        the desired space group of the symmetry class
    :type space_group:         cctbx.sgtbx.space_group
    :param correct_rhombohedral_setting_if_necessary: If set to 'True' an automatic conversion between rhombohedral and hexagonal basis will be done
    :type correct_rhombohedral_setting_if_necessary:  boolean
    :param assert_is_compatible_unit_cell: If set to 'True' a consistency check will be performed on the relation of space group to lattice parameters
    :type assert_is_compatible_unit_cell:  boolean
    :param force_compatible_unit_cell:     If set to 'True' the crystal parameters will be averaged to comply with the restrictions of the space group
    :type force_compatible_unit_cell:      boolean

    :returns: a new crystal.symmetry class with desired properties
    :rtype: cctbx.crystal.symmetry
    Né   )Úsymbol)ÚgroupÚPz :RÚRz :HzBThe space group '%s' is incompatible with unit cell parameters %s.z6Space group is incompatible with unit cell parameters.)ÚcountÚAssertionErrorÚ
isinstancer   ÚextÚ	unit_cellÚ
_unit_cellÚ_space_group_infor   Úspace_group_infoÚspace_groupr   Ú!conventional_centring_type_symbolÚis_conventional_hexagonal_basisÚtypeÚlookup_symbolÚendswithÚreference_settingÚ"is_conventional_rhombohedral_basisÚprimitive_settingÚis_compatible_unit_cellr   ÚstrÚ
parametersÚaverage_unit_cell)Úselfr!   Úspace_group_symbolr$   r%   Z)correct_rhombohedral_setting_if_necessaryÚassert_is_compatible_unit_cellÚ%raise_sorry_if_incompatible_unit_cellZforce_compatible_unit_cellÚsgiÚzÚls© r9   úu/mnt/filia/a/genomebrowser/www/genomebrowser/fleming/tools/molprobity/modules/cctbx_project/cctbx/crystal/__init__.pyÚ__init__&   sN    





zsymmetry.__init__c             C   s   |j | _ |j| _d S )N)r"   r#   )r2   Úotherr9   r9   r:   Ú_copy_constructorm   s    zsymmetry._copy_constructorc             C   s*   |t kr| j}|t kr| j}t|||dS )N)r!   r$   r5   )r   r"   r#   r   )r2   r!   r$   r5   r9   r9   r:   Úcustomized_copyq   s      zsymmetry.customized_copyc             C   s   | j S )N)r"   )r2   r9   r9   r:   r!   y   s    zsymmetry.unit_cellc             C   sb   | j }|rZ| ¡ rZ| ¡  ¡ rZ| ¡  ¡  ¡ rZ| ¡  ¡  ¡  ¡ d k	rZ| ¡  ¡  ¡  ¡ S d S d S )N)r#   r   Úinfor(   Únumber)r2   r6   r9   r9   r:   Úspace_group_number|   s    zsymmetry.space_group_numberc             C   s   | j S )N)r#   )r2   r9   r9   r:   r$   …   s    zsymmetry.space_group_infoc             C   s   | j }|d krd S | ¡ S )N)r#   r   )r2   r6   r9   r9   r:   r%   ˆ   s     zsymmetry.space_groupÚ c             C   sR   d}|||   ¡ d k	r$d|   ¡  ¡  nd ||  ¡ d k	rHd|  ¡  ¡  ¡  nd |f S )NzAcrystal.symmetry(
%s  unit_cell=%s,
%s  space_group_symbol=%s
%s)z*(%.10g, %.10g, %.10g, %.10g, %.10g, %.10g)z"%s")r!   r0   r$   r(   r)   )r2   ÚindentÚfmtr9   r9   r:   Ú
as_py_code   s    "zsymmetry.as_py_codec             C   s&   |d krt j}t| j|d|d d S )N)Úprefix)Úfile)ÚsysÚstdoutÚprintÚas_str)r2   ÚfrF   r9   r9   r:   Úshow_summary   s     zsymmetry.show_summaryc             C   s4   |d|   ¡   | d|  ¡ d k	r,|  ¡  ¡ nd   S )NzUnit cell: %s
zSpace group: %s)r!   r$   Úsymbol_and_number)r2   rF   r9   r9   r:   rK   ¡   s    zsymmetry.as_strc             C   s   |   ¡ S )N)rK   )r2   r9   r9   r:   Ú__str__©   s    zsymmetry.__str__c             C   s   | j ddS )Nz  )rC   )rE   )r2   r9   r9   r:   Ú__repr__¬   s    zsymmetry.__repr__c             C   s   | j |ddddS )z& True if identical for self and other r   )Úrelative_length_toleranceÚabsolute_angle_toleranceÚabsolute_length_tolerance)Úis_similar_symmetry)r2   r<   r9   r9   r:   Úis_identical_symmetry¯   s    zsymmetry.is_identical_symmetryç{®Gáz„?ç      ð?ç    €‡ÃÀc             C   s<   |   ¡ r,|  ¡ r,|   ¡  |  ¡ |||¡s,dS |  ¡ | ¡ kS )NF)r!   Úis_similar_tor%   )r2   r<   rQ   rR   rS   r9   r9   r:   rT   ¶   s    zsymmetry.is_similar_symmetryc             C   s   |   ¡  |  ¡ ¡S )N)r%   r.   r!   )r2   r9   r9   r:   r.   Å   s    z symmetry.is_compatible_unit_cellc             C   s   t |  ¡ ddS )NzP 1)r3   )r   r!   )r2   r9   r9   r:   Úcell_equivalent_p1È   s    zsymmetry.cell_equivalent_p1c             C   s4   t |tƒrt |¡}t|  ¡  |¡|  ¡  |¡dS )N)r!   r$   )r   r/   r   Úchange_of_basis_opr   r!   Úchange_basisr$   )r2   Úcb_opr9   r9   r:   r\   Ë   s
    

zsymmetry.change_basisc             C   s   |   ¡  ¡ S )N)r%   Úz2p_op)r2   r9   r9   r:   Ú'change_of_basis_op_to_primitive_settingÒ   s    z0symmetry.change_of_basis_op_to_primitive_settingc             C   s   |   |  ¡ ¡S )N)r\   r_   )r2   r9   r9   r:   r-   Õ   s    zsymmetry.primitive_settingc             C   s   |   ¡  ¡  ¡ S )N)r$   r(   r]   )r2   r9   r9   r:   Ú'change_of_basis_op_to_reference_settingØ   s    z0symmetry.change_of_basis_op_to_reference_settingc             C   s   |   |  ¡ ¡S )N)r\   r`   )r2   r9   r9   r:   Úas_reference_settingÛ   s    zsymmetry.as_reference_settingc             C   s   t | ||d ¡ S )N)Zinput_symmetryÚangular_toleranceÚbest_monoclinic_beta)r
   r]   )r2   rb   rc   r9   r9   r:   Úchange_of_basis_op_to_best_cellÞ   s    z(symmetry.change_of_basis_op_to_best_cellc             C   s   |   | j|d¡S )N)rb   )r\   rd   )r2   rb   r9   r9   r:   Ú	best_cellæ   s    zsymmetry.best_cellc             C   sf   |   ¡  ¡ }| ¡  ¡ }|  ¡  | ¡ | ¡ ¡}| ¡ }t	 
t	 t	 | ¡ d¡¡¡ ¡ }| |¡| S )Né   )r%   r^   Úc_invÚrr!   r\   ÚnumÚdenÚminimum_reductionr   r[   Úrt_mxÚrot_mxÚr_invÚinverseÚnew_denominators)r2   r^   rn   Úp_cellZredÚp2n_opr9   r9   r:   Ú"change_of_basis_op_to_minimum_cellê   s    z+symmetry.change_of_basis_op_to_minimum_cellc             C   s   |   |  ¡ ¡S )N)r\   rs   )r2   r9   r9   r:   Úminimum_celló   s    zsymmetry.minimum_cellc             C   sF   |   ¡  ¡ }| ¡  ¡ }|  ¡  | ¡ | ¡ ¡}| ¡ }| 	|¡| S )N)
r%   r^   rg   rh   r!   r\   ri   rj   Ú!change_of_basis_op_to_niggli_cellrp   )r2   Úrelative_epsilonÚiteration_limitr^   rn   rq   rr   r9   r9   r:   ru   ö   s
    z*symmetry.change_of_basis_op_to_niggli_cellc             C   s   |   | j||d¡S )N)rv   rw   )r\   ru   )r2   rv   rw   r9   r9   r:   Úniggli_cellÿ   s    zsymmetry.niggli_cellc             C   s   |   ¡  ¡  ¡ S )N)r$   r(   Úchange_of_hand_op)r2   r9   r9   r:   Ú"change_of_basis_op_to_inverse_hand  s    z+symmetry.change_of_basis_op_to_inverse_handc             C   s   |   |  ¡ ¡S )N)r\   rz   )r2   r9   r9   r:   Úinverse_hand	  s    zsymmetry.inverse_handc             C   s   t |  ¡ |  ¡ j|ddS )N)Úanomalous_flag)r!   r%   )r   r!   r%   Ú(build_derived_reflection_intensity_group)r2   r|   r9   r9   r:   Úreflection_intensity_symmetry  s    z&symmetry.reflection_intensity_symmetryc             C   s   t |  ¡ |  ¡  ¡ dS )N)r!   r%   )r   r!   r%   Úbuild_derived_patterson_group)r2   r9   r9   r:   Úpatterson_symmetry  s    zsymmetry.patterson_symmetryc             C   s   |   ¡  ¡ |   ¡ kS )N)r%   r   )r2   r9   r9   r:   Úis_patterson_symmetry  s    
zsymmetry.is_patterson_symmetryc       	      C   sz   t |  ¡ |  ¡ |d}|d kr"|S |dkr4| }|}n|}| }| ¡ }| ¡ }|d kr\| ¡ }|d krl| ¡ }t |||dS )N)r!   r$   r5   F)r   r!   r$   )	r2   Úother_symmetryÚforcer5   Zsame_resultZstrongZweakr!   r$   r9   r9   r:   Újoin_symmetry  s*    zsymmetry.join_symmetryc             C   s$   |   ¡ }| |  ¡ j| |¡d¡S )N)Útranslation_frac)r!   Úorthogonalizer$   Ú)subtract_continuous_allowed_origin_shiftsÚfractionalize)r2   Ztranslation_cartÚucr9   r9   r:   r‡   7  s    z2symmetry.subtract_continuous_allowed_origin_shiftsc             C   s   |   ¡  ¡ j|  ¡ dS )N)r!   )r$   Údirect_space_asuZdefine_metricr!   )r2   r9   r9   r:   rŠ   =  s    zsymmetry.direct_space_asué   c       	      C   s0   ddl m} |j|  ¡ |||||  ¡ |||d	S )Nr   )Úmaptbx)	r!   Úd_minÚresolution_factorÚstepÚsymmetry_flagsr$   Úmandatory_factorsÚ	max_primeÚassert_shannon_sampling)ÚcctbxrŒ   Úcrystal_griddingr!   r$   )	r2   r   rŽ   r   r   r‘   r’   r“   rŒ   r9   r9   r:   ÚgriddingA  s    zsymmetry.griddingc             C   s(   dd l }tj|  ¡ |  ¡ j|d|dS )Nr   )Úis_inside_epsilon)r%   ÚasuÚbuffer_thickness)Zcctbx.crystal.direct_space_asurŠ   Úasu_mappingsr%   Úas_float_asu)r2   r™   Úasu_is_inside_epsilonr”   r9   r9   r:   rš   T  s    zsymmetry.asu_mappingsc          	   C   s2   ddl m} | |  ¡ |  ¡  | |  ¡ |¡¡¡S )Nr   )Úadptbx)r”   r   Zu_star_as_u_cartr!   r%   Úaverage_u_starÚu_cart_as_u_star)r2   Úu_cartr   r9   r9   r:   Úaverage_u_cart\  s    
zsymmetry.average_u_cartc             C   s   | j |dS )N)r    )r¡   )r2   Úb_cartr9   r9   r:   Úaverage_b_cartb  s    zsymmetry.average_b_cartç      à?r   c             C   s   t | |||dS )N)Úcrystal_symmetryÚmin_distance_sym_equivÚu_star_toleranceÚassert_min_distance_sym_equiv)Úspecial_position_settings)r2   r¦   r§   r¨   r9   r9   r:   r©   e  s
    z"symmetry.special_position_settingsc             C   s   ddl m} |j| ||dS )Nr   )Úmiller)r¥   Úindicesr|   )r”   rª   Úset)r2   r«   r|   rª   r9   r9   r:   Ú
miller_seto  s
    zsymmetry.miller_setc             C   s   ddl m} |j| |||dS )Nr   )rª   )r¥   r|   r   Úd_max)r”   rª   Ú	build_set)r2   r|   r   r®   rª   r9   r9   r:   Úbuild_miller_setv  s    zsymmetry.build_miller_setc             C   sÀ   t dƒ‚d}|  ¡ d k	r¼|  ¡ d k	r¼|  ¡ }t| ¡ ƒ}x‚t|  ¡ ƒD ]r\}}| ¡ }x`tdƒD ]T}|d|d |d ||d  ||d d  ||d d  ||d  ||  f 7 }q`W qFW |S )Nz(do not use this method - not tested yet!rB   é   z0REMARK 290   SMTRY%d%4d%10.6f%10.6f%10.6f%15.5f
rf   r   é	   )r   r%   r!   Úlistr0   Ú	enumerateÚas_double_arrayr   )r2   Úoutlr‰   ÚparamsÚiÚsÚmatÚjr9   r9   r:   Úas_pdb_remark_290~  s"    
"zsymmetry.as_pdb_remark_290Úmmcifú%.3fc             C   sˆ  ddl m} | ¡ }|dks t‚|dkr.d}nd}| d¡s@t‚| ¡ }d| }|  ¡ d k	rL|jtd	| d
 t	dt
|  ¡ ƒd ƒfd	| d dd„ |  ¡ D ƒffƒd}	| |	¡ d| }
|  ¡  ¡ }| ¡ }| ¡  ¡ ||
d < | ¡ ||
d < | ¡ ||
d < | ¡ ||
d < d| }
| ¡ ||
d < | ¡ ||
d < | ¡ ||
d < |  ¡ d k	r„|  ¡ }t| ¡ ƒ}| ¡ }|d k	r| ¡ }x<t	dƒD ]0}|| dkr’t|| t || ¡ƒ||< q’W t | ¡ ¡}t | ¡ ¡}||   |¡}t|t |¡ƒ}d}|\}}}}}}|| ||d < || ||d < || ||d < || ||d < || ||d < || ||d  < || ||d! < |S )"Nr   )Úmodel)Úcorecifr½   r½   Ú.Ú_ú%z_cell%sÚ_space_group_symopÚidrf   Zoperation_xyzc             S   s   g | ]}|  ¡ ‘qS r9   )Úas_xyz)Ú.0r¹   r9   r9   r:   ú
<listcomp>¦  s    z)symmetry.as_cif_block.<locals>.<listcomp>)Údataz_space_group%sÚcrystal_systemZ	IT_numberzname_H-M_altZ	name_Hallz_symmetry%szspace_group_name_H-MZspace_group_name_HallZInt_Tables_numberé   z%sZlength_aZlength_bZlength_cÚangle_alphaZ
angle_betaZangle_gammaÚvolume)!Ú	iotbx.cifr¿   Úlowerr   Ú
startswithÚblockr%   Úloopr   r   ÚlenÚadd_loopr$   r(   r   rÊ   r@   r)   Úhall_symbolr!   r³   r0   rÍ   Úmatrix_packed_u_diagonalÚformat_float_with_suÚmathÚsqrtr   ÚrowÚd_volume_d_paramsÚsqrÚmatrix_packed_u_as_symmetricÚdot)r2   Úcell_covariance_matrixÚformatZnumeric_formatr¿   ÚwformatÚ	separatorÚ	cif_blockZcell_prefixZsym_loopZ	sg_prefixZsg_typeÚsgr‰   r·   rÍ   Údiagr¸   Zd_v_d_paramsZvcvZvar_vÚaÚbÚcÚalphaÚbetaÚgammar9   r9   r:   Úas_cif_block“  sf    



"
zsymmetry.as_cif_blockc       	      C   s²   ddl m} t ¡ }x˜|D ]}xŠ|  ¡  ¡ D ]z}| ¡  ¡ }| |¡}| 	¡  ¡ }| 
|d |d |d f¡}t |  ¡  |¡g¡}| |  ¡  |j| | ¡d ¡ q,W qW |S )Nr   )r   rf   r   )Úscitbxr   r   Úvec3_doubler%   Úsmxrh   Ú	as_doublerÜ   ÚtÚcolr!   rˆ   Úappendr†   Úelems)	r2   Ú
sites_cartr   ÚresultÚ	site_cartrï   Úm3rñ   Ú	site_fracr9   r9   r:   Úexpand_to_p1Î  s    

*zsymmetry.expand_to_p1c             C   s  |   ¡ }|d krdS | ¡ }td|d  ƒdk rZtd|d  ƒdk rZtd|d  ƒdk ptd|d  ƒdk r˜td|d  ƒdk r˜td|d  ƒdk ptd|d  ƒdk rÖtd|d	  ƒdk rÖtd|d
  ƒdk ptd|d  ƒdk otd|d	  ƒdk otd|d
  ƒdk }|S )NFg      ð?r   gü©ñÒMbP?rf   r   g        r±   é   r‹   )r!   r0   Úabs)r2   r‰   Zucprö   r9   r9   r:   Úis_nonsenseÛ  s"    zsymmetry.is_nonsensec             C   s   |   ¡ d ko|  ¡ d kS )N)r!   r$   )r2   r9   r9   r:   Úis_emptyî  s    zsymmetry.is_emptyc             C   s   |   ¡ d kp|  ¡ d kS )N)r!   r%   )r2   r9   r9   r:   Úis_incompleteñ  s    zsymmetry.is_incomplete)NNNNFTFT)rB   )NrB   )rB   )rV   rW   rX   )NT)N)NN)NN)FF)NNNNNr‹   T)N)r¤   r   T)N)Nr½   r¾   )5Ú__name__Ú
__module__Ú__qualname__Ú__doc__r;   r=   r   r>   r!   rA   r$   r%   rE   rM   rK   rO   rP   rU   rT   r.   rZ   r\   r_   r-   r`   ra   rd   re   rs   rt   ru   rx   rz   r{   r~   r€   r   r„   r‡   rŠ   r–   rš   r¡   r£   r©   r­   r°   r¼   rì   rú   rý   rþ   rÿ   r9   r9   r9   r:   r   #   s’          
?	


	  
 

	 
 
 
      

  

  
8r   Fg      ð?g    €‡ÃÀc             C   s.  | |g| | }|  d¡t|ƒkr*tdƒ‚t|ƒdkr
|r
d}d}	xD|dkrŠ|	t|ƒk rŠ||	 }|dk	r€| ¡ s|| ¡ r€d}|	d7 }	qHW x|||	d… D ]l}
|
rš|
 ¡ sš|
 ¡ sš|j|
||d}|sšd}|d| ¡ | ¡ f 7 }|d|
 ¡ |
 ¡ f 7 }td| ƒ‚qšW t	ddd	}| dk	r.|j
| d
d}|dk	rF|j
|d
d}| ¡ dkr”x>|D ]6}|dk	rZ| ¡ }|dk	rZt	|| ¡ d
d}P qZW x&|D ]}|dk	rš|j
|d
d}qšW | ¡ dkrxB|D ]:}d}|dk	rê| ¡ }|dk	rÐt	| ¡ |d
d}P qÐW | ¡ rdS | ¡ r*dS |S )zBSelect/construct a crystal symmetry from a list of various optionsNz.No unit cell and symmetry information suppliedr   rf   )rR   rS   z3Crystal symmetry mismatch between different files.
z%s %s
z%s)r!   r$   F)r‚   rƒ   )r!   r$   r4   )r   rÓ   r   rý   rþ   rT   r!   r$   r   r   r„   )Zfrom_command_lineZfrom_parameter_fileZfrom_coordinate_filesZfrom_reflection_filesZenforce_similarityrR   rS   ÚtmpZcs0r¸   ÚcsZis_similar_csÚmsgrö   r¥   r!   r$   r9   r9   r:   Úselect_crystal_symmetryô  sz    














r  ç      à?c          	   C   s"   t tj| |||||dt ¡ dS )N)rõ   Úsites_cart_minÚsites_cart_maxÚbuffer_layerÚdefault_buffer_layerÚmin_unit_cell_length)r!   r%   )r   r   Únon_crystallographic_unit_cellr   r%   )rõ   r	  r
  r  r  r  r9   r9   r:   Únon_crystallographic_symmetry<  s    r  c            	   @   s–   e Zd Zd'dd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Zd(dd„Z	dd„ Z
d)dd„Zd*dd„Zd+dd„Zd,dd„Zd-dd „Zd.d"d#„Zd/d%d&„ZdS )0r©   ç      à?r   Tc             C   s"   t  | |¡ || _|| _|| _d S )N)r   r=   Ú_min_distance_sym_equivÚ_u_star_toleranceÚ_assert_min_distance_sym_equiv)r2   r¥   r¦   r§   r¨   r9   r9   r:   r;   O  s    z"special_position_settings.__init__c             C   s(   t  | |¡ |j| _|j| _|j| _d S )N)r   r=   r  r  r  )r2   r<   r9   r9   r:   r=   X  s    z+special_position_settings._copy_constructorc             C   s   | j S )N)r  )r2   r9   r9   r:   r¦   ^  s    z0special_position_settings.min_distance_sym_equivc             C   s   | j S )N)r  )r2   r9   r9   r:   r§   a  s    z*special_position_settings.u_star_tolerancec             C   s   | j S )N)r  )r2   r9   r9   r:   r¨   d  s    z7special_position_settings.assert_min_distance_sym_equivc             C   s$   t t | |¡|  ¡ |  ¡ |  ¡ dS )N)r¥   r¦   r§   r¨   )r©   r   r\   r¦   r§   r¨   )r2   r]   r9   r9   r:   r\   g  s
    
z&special_position_settings.change_basisNc             C   sN   ||g  d ¡dkst‚|d k	r,|  ¡  |¡}t |  ¡ |  ¡ ||  ¡ |  ¡ ¡S )Nrf   )	r   r   r!   rˆ   r   Úsite_symmetryr%   r¦   r¨   )r2   Úsiter÷   r9   r9   r:   r  n  s    z'special_position_settings.site_symmetryc             C   s   t  |  |¡¡S )N)r   Úsym_equiv_sitesr  )r2   r  r9   r9   r:   r  y  s    z)special_position_settings.sym_equiv_sitesc             C   s^   |d k|d kkst ‚|d kr,|  ¡ j|d}t ¡ }|j|  ¡ |  ¡ |||  ¡ |  ¡ d |S )N)rõ   )r!   r%   Zoriginal_sites_fracÚ$unconditional_general_position_flagsr¦   r¨   )	r   r!   rˆ   r   Úsite_symmetry_tableÚprocessr%   r¦   r¨   )r2   Ú
sites_fracrõ   r  rö   r9   r9   r:   r  |  s    z-special_position_settings.site_symmetry_tablec             C   s   dd l m  m} || |dS )Nr   )r©   Ú
scatterers)Zcctbx.xray.structureÚxrayÚ	structure)r2   r  rÂ   r9   r9   r:   Úxray_structureŽ  s    z(special_position_settings.xray_structurec             C   sr   t j| ||d}|d k	s |d k	rn|d ks4|d ks4t‚|d krL|  ¡ j|d}|d kr`| j|d}|j||d |S )N)r™   rœ   )rõ   )r  )Zoriginal_sitesr  )r   rš   r   r!   rˆ   r  Zprocess_sites_frac)r2   r™   r  rõ   r  rœ   rš   r9   r9   r:   rš   ’  s    z&special_position_settings.asu_mappingsFc       	      C   sB   |d k	s|d k	st ‚|d kr |}| j|||||d}t|||dS )N)r™   r  rõ   r  rœ   )rš   Údistance_cutoffÚminimal)r   rš   Úneighbors_fast_pair_generator)	r2   r  r  rõ   r  Úasu_mappings_buffer_thicknessrœ   r   rš   r9   r9   r:   Úpair_generator¦  s    z(special_position_settings.pair_generatorr‹   c	             C   sf   |d k	s|d k	st ‚|d kr |}| j|||||d}	t|	d}
|d krR|	 ¡  ¡ }|
j|||d |
S )N)r™   r  rõ   r  rœ   )rš   )r  Úmin_cubicle_edgeÚepsilon)r   rš   Úpair_asu_tabler˜   r—   Úadd_all_pairs)r2   r  r  rõ   r  r"  rœ   r$  Zdistance_cutoff_epsilonrš   rö   r9   r9   r:   r&  ¼  s"    	
z(special_position_settings.pair_asu_tableéÿÿÿÿc             C   s6   t |  ¡ |  ¡ j|d|||d}| j|_| j|_|S )N)r—   )r%   r˜   r  r"  Úcubicle_epsilon)Úincremental_pairsr%   rŠ   r›   r  r¦   r  r¨   )r2   r  rœ   r"  r)  rö   r9   r9   r:   r*  ×  s    z+special_position_settings.incremental_pairsrû   c
             C   sz   |d kr|}|d kr|}|d kr$|}|d k	s0t ‚|d k	s<t ‚t|  ¡ |  ¡ j|d|||||||	d	}
| j|
_| j|
_|
S )N)r—   )	r%   r˜   Úmin_cross_distanceÚmin_self_distanceÚgeneral_positions_onlyÚestimated_reduction_factorr"  r$  r)  )	r   Úsite_cluster_analysisr%   rŠ   r›   r  r¦   r  r¨   )r2   Zmin_distancer+  r,  r-  r.  rœ   r"  r$  r)  rö   r9   r9   r:   r/  ç  s,    
   z/special_position_settings.site_cluster_analysis)r  r   T)NN)NNN)N)NNNN)NNNNNF)NNNNNr‹   N)Nr(  r(  )	NNNFrû   Nr(  r‹   r(  )r   r  r  r;   r=   r¦   r§   r¨   r\   r  r  r  r  rš   r#  r&  r*  r/  r9   r9   r9   r:   r©   M  sV     

  

   
     
      
  
        r©   rf   ú&Excessive special position correction:c       
      C   sÜ   |d k|d kkst ‚|  ¡ }|d kr.| |¡}|| }| ||¡}	|	|krÆ|dt|ƒ 7 }|dt|  ¡ ƒ 7 }|dt|ƒ 7 }|d k	r’|d| 7 }|dt|ƒ 7 }|dt|ƒ 7 }|d|	 7 }t |ƒ‚|d krÒ|S | |¡S )Nz
  unit_cell: %sz
  space_group_info: %sz
  special_op: %sz
  site_label: %sz
  site_frac: %sz
  site_special_frac: %sz
  distance_moved: %g)r   r!   rˆ   Údistancer/   r$   r†   )
r¥   Ú
special_oprù   r÷   Z
site_labelÚ	toleranceZerror_messager!   Zsite_special_fracÚdistance_movedr9   r9   r:   Úcorrect_special_position  s(    
r5  c               @   s<   e Zd Zdd„ Zddd„Zddd„Zdd	d
„Zddd„ZdS )rÂ   c       	      C   st   g }xjt |  ¡ ƒD ]Z\}}|g}x@| ¡ D ]4\}}|g}x|D ]}| t|ƒ¡ q>W | |¡ q*W | |¡ qW |S )N)r´   ÚtableÚitemsró   r³   )	r2   rö   Úi_seqÚ
j_seq_dictZ
i_seq_listÚj_seqÚj_sym_groupZ
j_seq_listÚj_symsr9   r9   r:   Úas_nested_lists%  s    
z_.as_nested_listsNc             C   s   |d krt j}|d kr„xjt|  ¡ ƒD ]Z\}}td||d xB| ¡ D ]6\}}td||d x|D ]}tdt|ƒ|d q`W qDW q$W n˜t|ƒ|  ¡  ¡ ksœt	‚x~t|  ¡ ƒD ]n\}}td|| |f |d xL| ¡ D ]@\}}td|| |f |d x|D ]}tdt|ƒ|d qúW qÔW qªW d S )Nzi_seq:)rG   z  j_seq:z    j_syms:z%s(%d)z  %s(%d))
rH   rI   r´   r6  rJ   r7  r³   rÓ   Úsizer   )r2   rL   Úsite_labelsr8  r9  r:  r;  r<  r9   r9   r:   Úshow1  s      
 
z_.showFc          	   C   s   t | ||||||dS )N)r&  r?  r  rõ   Úshow_cartesianÚkeep_pair_asu_tableÚout)Úshow_distances)r2   r?  r  rõ   rA  rB  rC  r9   r9   r:   rD  C  s    z_.show_distancesc             C   s   t | |||||dS )N)r&  r?  r  rõ   rB  rC  )Úshow_angles)r2   r?  r  rõ   rB  rC  r9   r9   r:   rE  S  s    z_.show_anglesç333333û?éª   c          	   C   s   t | ||||||dS )N)r&  r?  r  rõ   Úmax_dÚ	max_anglerC  )Úshow_dihedral_angles)r2   r?  r  rõ   rB  rH  rI  rC  r9   r9   r:   rJ  a  s    z_.show_dihedral_angles)NN)NNNFFN)NNNFN)NNNFrF  rG  N)r   r  r  r=  r@  rD  rE  rJ  r9   r9   r9   r:   rÂ   "  s(   
     
    

      rÂ   c               @   s&   e Zd Zd	dd„Zdd„ Zdd„ ZdS )
Úcalculate_distancesTNc             C   sB   t  | tƒ ¡ t ¡ | _| jd k	r.t ¡ | _nd | _t ¡ | _	d S )N)
ÚlibtbxÚadopt_init_argsÚlocalsr   ÚdoubleÚ	distancesÚcovariance_matrixÚ	variancesÚsize_tÚpair_counts)r2   r&  r  Úskip_j_seq_less_than_i_seqrQ  rß   Úparameter_mapr9   r9   r:   r;   t  s    

zcalculate_distances.__init__c             C   s   t | ƒS )N)Únext)r2   r9   r9   r:   Ú__iter__ƒ  s    zcalculate_distances.__iter__c             c   sŠ  G dd„ dt ƒ}| j ¡ }| ¡ }| jd k	rL| jd k	s:t‚t | j|| j¡}x6t	| j 
¡ ƒD ]"\}}| |d¡ ¡ }| j| }d}	t ¡ }
g }x’| ¡ D ]†\}}| jr´||k r´qœ| j| }xbt	|ƒD ]V\}}|	| ¡ 7 }	|d }| | ||¡¡}| ||| ¡}|
 |¡ | ||f¡ qÈW qœW tj|
d}x@t ||¡D ].\}}| j| }|| }|| }xt	|ƒD ]ú\}}| | ||¡¡}|| }t | |¡| |¡f¡}|j}| j |¡ | jd k	rNt t ||f¡|| j¡}| jd k	r2| |||¡}|dks||kr@|  ¡ s@| || j||¡}n| |||¡}| j! |¡ nd }|||||	|||dV  qrW qBW | j" |	¡ q^W d S )Nc               @   s   e Zd Zddd„ZdS )z.calculate_distances.__next__.<locals>.distanceNc             S   s   t  | tƒ ¡ d S )N)rL  rM  rN  )r2   r1  r8  r:  Ú
pair_countÚrt_mx_jiÚi_j_symÚvariancer9   r9   r:   r;   ‰  s    z7calculate_distances.__next__.<locals>.distance.__init__)NNN)r   r  r  r;   r9   r9   r9   r:   r1  ˆ  s     r1  r   )rÉ   g¼‰Ø—²Ò¬<)r\  )#r   r&  rš   r!   rQ  rV  r   r   Úorthogonalize_covariance_matrixr´   r6  Ú	get_rt_mxro   r  r   rO  r7  rU  r>  Úmultiplyr1  ró   Úsort_permutationÚselectr   r†   Údistance_modelrP  Ú#extract_covariance_matrix_for_sitesrS  rß   r\  Ú
is_unit_mxrR  rT  )r2   r1  rš   r!   Úcov_cartr8  Úasu_dictÚrt_mx_i_invÚsite_frac_irY  ZdistsZj_seq_i_groupr:  Új_sym_groupsÚsite_frac_jZi_groupr;  Új_symrZ  ÚdistÚpermutationr[  Úsite_frac_jiÚdÚcovÚvarr9   r9   r:   Ú__next__†  sf    


 


"zcalculate_distances.__next__)TNNN)r   r  r  r;   rX  rr  r9   r9   r9   r:   rK  r  s      
	rK  c               @   s    e Zd ZdddgZddd„ZdS )	rD  r&  Údistances_infoÚhave_symNFc	             C   s¬  ||g  d ¡dkst‚|d kr$tj}|r0|| _nd | _| ¡ }	|	 ¡ }
|d krZ|
j|d}|d krˆtd| 	¡ d  ƒ}d| }|d7 }n,d}x|D ]}t
|t|ƒƒ}q’W d|d  }t|||d| _d| _tƒ }xÔ| jD ]È}|j|j }}|j}d	d
lm} ||k}|r¤| |¡ |d kr0||d  }n|||  }|d|j 7 }|| }|rndd„ |
 |¡D ƒ}ndd„ |D ƒ}td|d  | dd |¡ d |d |d krÌtd||d  d d|d ntd||| d  d|d td|j d|d |jd	krd}nd}|||  }|r:dd„ |
 |¡D ƒ}ndd„ |D ƒ}|dd |¡ d 7 }| ¡ s~|dt|ƒ 7 }d| _t||d |rÚ|jd	krÚtd |d qÚW d S )!Nrf   )rõ   z%dzsite_%%0%ddr‹   z%%-%ds)rU  Fr   )r   z pair count: %3dc             S   s   g | ]}d | ‘qS )z %7.2fr9   )rÇ   Úxr9   r9   r:   rÈ   ÿ  s   z+show_distances.__init__.<locals>.<listcomp>c             S   s   g | ]}d | ‘qS )z %7.4fr9   )rÇ   ru  r9   r9   r:   rÈ     s    é   z<<ú,z>>)rG   ú ú:)ÚendrG   z%8.4fzsym. equiv.z           c             S   s   g | ]}d | ‘qS )z %7.2fr9   )rÇ   ru  r9   r9   r:   rÈ     s   c             S   s   g | ]}d | ‘qS )z %7.4fr9   )rÇ   ru  r9   r9   r:   rÈ     s    z (ú)z sym=Tz  no neighbors)r   r   rH   rI   r&  rš   r!   rˆ   rÓ   r>  ÚmaxrK  rs  rt  r¬   r8  r:  rZ  Úscitbx.array_familyr   ÚaddrY  r†   rJ   Újoinr1  r[  rd  r/   )r2   r&  r?  r  rõ   rA  rB  rU  rC  rš   r!   Ú	label_lenÚ	label_fmtÚlabelZi_seqs_doneZdir8  r:  rZ  r   Zfirst_time_i_seqr¹   rh  Úformatted_sitern  r9   r9   r:   r;   Ð  sx    	 






zshow_distances.__init__)NNNFFFN)r   r  r  Ú	__slots__r;   r9   r9   r9   r:   rD  Ì  s   
      rD  c               @   s&   e Zd Zd	dd„Zdd„ Zdd„ ZdS )
Úcalculate_anglesTNc             C   sL   t  | tƒ ¡ t ¡ | _| jd k	r.t ¡ | _nd | _t ¡ | _t 	¡ | _
d S )N)rL  rM  rN  r   rO  rP  rQ  rR  ÚanglesrS  rT  )r2   r&  r  rU  rQ  rß   rV  Úconformer_indicesr9   r9   r:   r;     s    


zcalculate_angles.__init__c             C   s   t | ƒS )N)rW  )r2   r9   r9   r:   rX  /  s    zcalculate_angles.__iter__c             c   s  G dd„ dt ƒ}| j ¡ }| ¡ }| jd k	rL| jd k	s:t‚t | j|| j¡}xºt	| j 
¡ ƒD ]¦\}}| |d¡ ¡ }| j| }t ¡ }	xx| ¡ D ]j\}
}| j|
 }xT|D ]J}xBt	|ƒD ]4\}}| | |
|¡¡}|| }x| ¡ D ] \}}| jr|
|k rqô||
kr,| ¡ dkr,qô||
kr8qô| j| }x°|D ]¦}xœt	|ƒD ]Ž\}}|
|kr~||kr~q\||kr–|dkr–q\| jd k	r¼| j|
 | j| kr¼q\| | ||¡¡}|| }t | |¡| |¡| |¡f¡}|j}| j |¡ | jd k	rÌt t |
||f¡|| j¡}| jd k	r¦| |||t  ¡ |f¡}|dksˆ||
krt| !¡ rˆ||kr¾| !¡ s¾| || j||t  ¡ |f¡}n| |||t  ¡ |f¡}| j" |¡ nd }|||
||f|||dV  q\W qJW qôW qÄW q²W q–W q^W d S )Nc               @   s   e Zd Zddd„ZdS )z(calculate_angles.__next__.<locals>.angleNc             S   s   t  | tƒ ¡ d S )N)rL  rM  rN  )r2   ÚangleÚi_seqsrZ  Úrt_mx_kir\  r9   r9   r:   r;   5  s    z1calculate_angles.__next__.<locals>.angle.__init__)NNN)r   r  r  r;   r9   r9   r9   r:   rˆ  4  s     rˆ  r   rf   gVçž¯â<)r\  )#r   r&  rš   r!   rQ  rV  r   r   r]  r´   r6  r^  ro   r  r   rO  r7  r_  rU  r>  r‡  r   rˆ  r†   Úangle_modelr†  ró   rc  rS  rß   r\  r   rl   rd  rR  )r2   rˆ  rš   r!   re  r8  rf  rg  rh  r†  r:  ri  rj  r;  r[  rk  rZ  rn  Úk_seqÚk_sym_groupsZsite_frac_kÚk_sym_groupZi_k_symÚk_symrŠ  Zsite_frac_kiræ   Úangle_rp  rq  r9   r9   r:   rr  2  s~    	



  
 
   

zcalculate_angles.__next__)TNNNN)r   r  r  r;   rX  rr  r9   r9   r9   r:   r…    s       

r…  c               @   s   e Zd Zddd„ZdS )rE  NFc             C   sú  ||g  d ¡dkst‚|d kr$tj}|r0|| _nd | _g }|d krhtd| ¡ d  ƒ}	d|	 }
|	d7 }	n4d}	x|D ]}t|	t|ƒƒ}	qrW d|	d  }
|
d9 }
t||ƒ}x|D ]ú}|j	\}}}|j
}|j}|d krä|
|d  d }nª|| }|| }|| }| ¡ s>||kr | |¡d }n| |¡ t|ƒ}|d	| 7 }| ¡ s€||krb| |¡d }n| |¡ t|ƒ}|d	| 7 }|
|||f }|d
|j 7 }t||d q®W |j| _|j| _x8t|ƒD ],\}}td	|d  d|d t||d qÆW d S )Nrf   z%dzsite_%%0%ddr‹   z%%-%dsrû   r±   ry  z*%sz %6.2f)rG   rx  )rz  rG   )r   r   rH   rI   r&  rÓ   r>  r|  r…  r‰  rZ  rŠ  rd  Úindexró   rˆ  rJ   r†  rP  r1  r´   )r2   r&  r?  r  rõ   rA  rB  rC  Úrt_mxsr€  r  r‚  r†  ræ   r:  r8  rŒ  rZ  rŠ  r¹   Zi_labelZj_labelZk_labelr»   Úkr¸   rl   r9   r9   r:   r;   ~  s\    	 








zshow_angles.__init__)NNNFFN)r   r  r  r;   r9   r9   r9   r:   rE  |  s        rE  c               @   s   e Zd Zdd„ ZdS )Údihedral_angle_defc             C   s   t  | tƒ ¡ d S )N)rL  rM  rN  )r2   Úseqsr’  r9   r9   r:   r;   ½  s    zdihedral_angle_def.__init__N)r   r  r  r;   r9   r9   r9   r:   r”  ¼  s   r”  c               @   s&   e Zd Zddd„Zdd„ Zd	d
„ ZdS )Úcalculate_dihedralsNTçffffffþ?rG  c             C   s8   t  | tƒ ¡ | jd k	r$t ¡ | _nd | _t ¡ | _d S )N)rL  rM  rN  rQ  r   rO  rR  Ú	dihedrals)r2   r&  r  Údihedral_defsrU  rQ  rß   rV  r‡  rH  rI  r9   r9   r:   r;   Á  s
    
zcalculate_dihedrals.__init__c             C   s   |   ¡ S )N)rW  )r2   r9   r9   r:   rX  Ó  s    zcalculate_dihedrals.__iter__c       3      c   sj  G dd„ dt ƒ}| j ¡ }| ¡ }| jd k	rL| jd k	s:t‚t | j|| j¡}| j	d k	rDxæ| j	D ]Ü}g }x<t
ddƒD ].}|j| | j|j|   }| | |¡¡ qtW t |¡}	|	j}
| j |
¡ | jd k	r"t t |j¡|| j¡}| jd k	r|	 |||j¡}n|	 |||j¡}| j |¡ nd }||
|j|j|dV  q`W d S | j ¡ }xt|ƒD ]\}}| |d¡ ¡ }| j| }xÞ| ¡ D ]Ð\}}||k r¢qŠ| |d¡ ¡ }x¤|D ]š}xt|ƒD ]‚\}}| | ||¡¡}|| j|  }xT||  ¡ D ]B\}}||k rq| j d k	rD| j | | j | krDq| |d¡ ¡ }| |¡}xæ|D ]Ü}xÒt|ƒD ]Ä\}} | | || ¡¡}!|!| j|  }"|"|kr°qx| !||"¡| j"krÈqx|! |¡}#xf||  ¡ D ]T\}$}%|$|k rúqâ| j d k	r | j | | j |$ kr qâx|%D ]}&xþt|&ƒD ]ð\}'}(|# | |$|(¡¡})|)| j|$  }*|*||fkrvq:| #|||"¡| j$ks:| #||"|*¡| j$kr¦q:t% &¡ ||!|)g}+|||"|*g}||||$g},ddddg}-xNt|+ƒD ]B\}.}/x6t
|.d dƒD ]$}0|/|+|0 krü|-|.  d7  < qüW qäW |- 't(|-ƒ¡}1|+|1  ¡ }2xXt
ddƒD ]J}|+|  ¡ ||  ||< |2 |+| ¡|+|< | |+| ||  ¡||< qPW t |¡}	|	j}
| j |
¡ | jd k	rt t |,¡|| j¡}| jd k	rø|	 |||+¡}n|	 |||+¡}| j |¡ nd }||
|,|+|dV  q:W q(W qâW qxW qfW qW qÌW qºW qŠW qZW d S )Nc               @   s   e Zd Zddd„Zdd„ ZdS )z*calculate_dihedrals.next.<locals>.dihedralNc             S   s   t  | tƒ ¡ d S )N)rL  rM  rN  )r2   rˆ  r‰  r’  r\  r9   r9   r:   r;   Ù  s    z3calculate_dihedrals.next.<locals>.dihedral.__init__c             S   sD   x>t ddƒD ]0}| j| |j| ks8| j| |j| krdS qW dS )Nr   rû   FT)r   r‰  r’  )r2   r<   r¸   r9   r9   r:   Ú__eq__ß  s    (z1calculate_dihedrals.next.<locals>.dihedral.__eq__)N)r   r  r  r;   rš  r9   r9   r9   r:   ÚdihedralØ  s   
r›  r   rû   )r\  rf   ))r   r&  rš   r!   rQ  rV  r   r   r]  r™  r   r’  r  r•  ró   r†   r   r›  Zdihedral_modelr˜  rc  r   rS  rß   r\  rR  r6  r´   r^  ro   r7  r_  r‡  r1  rH  rˆ  rI  r   rl   r‘  r|  )3r2   r›  rš   r!   re  ZadÚsitesr¸   rù   ræ   r  rp  rq  r6  r8  Z
i_asu_dictrg  Zi_site_fracr:  ri  Zrt_mx_j0_invr;  Z	j_sym_idxrk  Zrt_mx_jZj_site_fracrŒ  r  Zrt_mx_k0_invZrt_mx_kjrŽ  Z	k_sym_idxr  Zrt_mx_kZk_site_fracZrt_mx_lkZl_seqZl_sym_groupsZl_sym_groupZ	l_sym_idxZl_symZrt_mx_lZl_site_fracr’  r•  Z
rtmx_countÚidxrl   Zidx1Zmax_idxZ	rt_mx_invr9   r9   r:   rW  Ö  sÄ    





 
 



  
zcalculate_dihedrals.next)NTNNNNr—  rG  )r   r  r  r;   rX  rW  r9   r9   r9   r:   r–  À  s          
r–  c               @   s   e Zd Zddd„ZdS )rJ  NFç333333û?rG  c	             C   s’  ||g  d ¡dkst‚|d kr$tj}g }	|d krVtd| ¡ d  ƒ}
d|
 }|
d7 }
n,d}
x|D ]}t|
t|ƒƒ}
q`W d|
d  }t||||d}xÂ|D ]º}|d kr¼||jd d  d	 }n|d
}xvt	|jƒD ]h\}}|||  }|j
| }| ¡ s,||	kr|	 |¡d }n|	 |¡ t|	ƒ}|d| 7 }||7 }qÌW |d|j 7 }t||d q˜W |j| _x.t	|	ƒD ]"\}}td|d |f |d qhW d S )Nrf   z%dzsite_%%0%ddr‹   z%%-%dsrû   )rH  rI  r   ry  rB   z*%sz %6.2f)rG   z*%s %s)r   r   rH   rI   rÓ   r>  r|  r–  r‰  r´   r’  rd  r‘  ró   rˆ  rJ   r˜  )r2   r&  r?  r  rõ   rA  rH  rI  rC  r’  r€  r  r‚  r†  ro  r¹   r  r8  rl   r»   r¸   r9   r9   r:   r;   K  sB    
 







zshow_dihedral_angles.__init__)NNNFrž  rG  N)r   r  r  r;   r9   r9   r9   r:   rJ  I  s         rJ  c               @   s&   e Zd ZdddgZdd„ Zdd„ ZdS )	Úsym_pairr8  r:  rZ  c             C   s   || _ || _|| _d S )N)r8  r:  rZ  )r2   r8  r:  rZ  r9   r9   r:   r;   ~  s    zsym_pair.__init__c             C   s   | j | jfS )N)r8  r:  )r2   r9   r9   r:   r‰  ƒ  s    zsym_pair.i_seqsN)r   r  r  r„  r;   r‰  r9   r9   r9   r:   rŸ  z  s   
rŸ  c               @   sz   e Zd Zdd„ Zdd„ Zddd„Zddd	„Zd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 ) rÂ   c             c   sN   xHt | ƒD ]<\}}x2| ¡ D ]&\}}x|D ]}t|||dV  q*W qW q
W d S )N)r8  r:  rZ  )r´   r7  rŸ  )r2   r8  Úpair_sym_dictr:  Úsym_opsrZ  r9   r9   r:   Úiterator‰  s    
z
_.iteratorc             C   sî   t |  ¡ d}xÚt| ƒD ]Î\}}xÄ| ¡ D ]¸\}}g }xj|D ]b}||krT|| }	}
n||| ¡   }	}
}x4|D ]}|j|drnP qnW |j|	|
|d}| |¡ q<W ||	 }tƒ ||
< ||
 }x$t	dd„ |D ƒƒD ]}| |¡ qÐW q*W qW |S )N)r>  )rZ  )r8  r:  rZ  c             S   s   g | ]}|  ¡ d  ‘qS )r   )Úget)rÇ   Úsepi_objr9   r9   r:   rÈ   ¤  s    z_.tidy.<locals>.<listcomp>)
Úpair_sym_tabler>  r´   r7  ro   Úis_equivalentÚ%symmetry_equivalent_pair_interactionsró   Úpair_sym_opsÚsorted)r2   r  rö   r8  r   r:  r¡  Z	sepi_objsrZ  r¸   r»   r¤  ÚriÚrijr9   r9   r:   Útidy  s(    


z_.tidyNc             C   s2  t |  ¡ d}xt| ƒD ]\}}|| }xü| ¡ D ]ð\}}| |¡}|d krbtƒ ||< || }|| }	|	 |¡}
|
d krŽtƒ |	|< |	| }
x–|D ]Ž}|d krÂ| |¡ ||krÀ|
 | ¡ ¡ q”|j}x$||||d ¡ D ]}| |¡ qÜW ||kr”x*|||| ¡ d ¡ D ]}|
 |¡ qW q”W q6W qW |S )N)r>  )r8  r:  rZ  )	r¥  r>  r´   r7  r£  r¨  ró   ro   r§  )r2   r  rö   r8  r   rª  r:  r¡  r«  ZrjZrjirZ  Úsepir¹   r9   r9   r:   Úfull_connectivity¨  s>    





z_.full_connectivityc                s>  ˆd k	rt ˆƒ|  ¡ kst‚|d k	rDt |ƒ|  ¡ ks8t‚|d k	sDt‚|d k	rd| ¡  ¡ |  ¡ ksdt‚ˆ d krrtj‰ ‡ ‡‡fdd„}‡ ‡‡fdd„}x¤t| ƒD ]–\‰}|ƒ  x„| ¡ D ]v\‰}	|ƒ  |d krd|d krúx„|	D ]}
td|
ˆ d qâW nht |	ƒdkr2t	dd	„ |	D ƒƒ}d
| }x>|	D ]6}
| 
|ˆ |
|ˆ  ¡}t|t|
ƒ|f ˆ d q(W qºd}g }xD|	D ]<}
|jˆˆ|
d ¡ }| |¡ t	|t	dd	„ |D ƒƒƒ}qrW |dkrºd| }xn|D ]f}d}d}xV|D ]N}|d k	rd| 
|ˆ ||ˆ  ¡ }t|t|ƒ||f  ¡ ˆ d d}qÚW qÈW qºW qžW d S )Nc                  s4   ˆd krt dˆˆ d nt dˆˆ ˆf ˆ d d S )Nzi_seq:)rG   z%s(%d))rJ   r9   )rL   r8  r?  r9   r:   Úshow_i×  s    z_.show.<locals>.show_ic                  s4   ˆd krt dˆˆ d nt dˆˆ ˆf ˆ d d S )Nz  j_seq:)rG   z  %s(%d))rJ   r9   )rL   r:  r?  r9   r:   Úshow_jÜ  s    z_.show.<locals>.show_jz   )rG   r   c             S   s   g | ]}t t|ƒƒ‘qS r9   )rÓ   r/   )rÇ   rÂ   r9   r9   r:   rÈ   ê  s    z_.show.<locals>.<listcomp>z    %%-%ds  %%8.4f)r8  r:  rZ  c             S   s   g | ]}t t|ƒƒ‘qS r9   )rÓ   r/   )rÇ   rÂ   r9   r9   r:   rÈ   ÷  s    z    %%-%ds%%s%%srB   z  %8.4fz  sym. equiv.)rÓ   r>  r   r«   rH   rI   r´   r7  rJ   r|  r1  r/   r§  r£  ró   Úrstrip)r2   rL   r?  r  r  r!   r¯  r°  r   r¡  rZ  Úmax_lenrD   ro  Zsepisr­  Úer¹   r9   )rL   r8  r:  r?  r:   r@  Ê  sX     


 




z_.showFc
          	      sŠ  ˆ|g  d ¡dkst‚|	d kr$tj}	ˆd kr8ˆj|d‰|d krftdˆ ¡ d  ƒ}
d|
 }|
d7 }
n$tdtdd„ |D ƒƒƒ}
d|
d  }|r”d }ndd	d„ t|  ¡ ƒD ƒ}xLt	| ƒD ]@\‰}x6| 
¡ D ]*\}}|ˆkrÆˆ|k sât‚||  ˆ¡ qÆW q´W t ¡ }x‚t	| ƒD ]t\‰}ˆˆ ‰g ‰ ‡ ‡‡‡‡‡fd
d„}x0| 
¡ D ]$\}}x|D ]}|||ƒ qPW qBW |d k	r®x8|ˆ D ],}x$| | ˆ D ]}||| ¡ ƒ qW q~W ˆ  ¡  |rÆtˆ ƒ}ntdd„ ˆ D ƒƒ}|d krð|ˆd  }n||ˆ  }|d| 7 }|r$dd„ ˆ ˆ¡D ƒ}ndd„ ˆD ƒ}td|
d  | dd |¡ d |	d xˆ D ]ú\}}}}d}xæ|D ]Þ}|d kr¤td||d  d d|	d ntd||| d  d|	d td| d|	d |}d}|ˆ|  }|rdd„ ˆ |¡D ƒ}ndd„ |D ƒ}|dd |¡ d 7 }| ¡ s@|dt|ƒ 7 }t||	d |rxP qxW qbW |d krvtd!|	d | |¡ qW |S )"Nrf   )rõ   z%dzsite_%%0%ddr‹   c             S   s   g | ]}t |ƒ‘qS r9   )rÓ   )rÇ   rÂ   r9   r9   r:   rÈ     s    z$_.show_distances.<locals>.<listcomp>z%%-%dsc             S   s   g | ]
}t ƒ ‘qS r9   )r¬   )rÇ   rÂ   r9   r9   r:   rÈ     s    c                s>   |ˆ|   }ˆj ˆ| |d ¡ }ˆ  ˆ ˆ|¡| ||g¡ d S )N)r8  r:  rZ  )r§  r£  ró   r1  )r:  rZ  rn  r­  )Údistance_infor8  rh  r  r  r!   r9   r:   Údistance_info_append&  s    
z._.show_distances.<locals>.distance_info_appendc             S   s   g | ]\}}}}t |ƒ‘qS r9   )rÓ   )rÇ   rÂ   r­  r9   r9   r:   rÈ   :  s    z pair count: %3dc             S   s   g | ]}d | ‘qS )z %7.2fr9   )rÇ   ru  r9   r9   r:   rÈ   A  s   c             S   s   g | ]}d | ‘qS )z %7.4fr9   )rÇ   ru  r9   r9   r:   rÈ   D  s    rv  z<<rw  z>>)rG   z           rx  ry  )rz  rG   z%8.4fzsym. equiv.c             S   s   g | ]}d | ‘qS )z %7.2fr9   )rÇ   ru  r9   r9   r:   rÈ   S  s   c             S   s   g | ]}d | ‘qS )z %7.4fr9   )rÇ   ru  r9   r9   r:   rÈ   V  s    z (r{  z sym=r   z  no neighbors)r   r   rH   rI   rˆ   rÓ   r>  r|  r   r´   r7  r~  r   rS  ro   ÚsortÚsumr†   rJ   r  rd  r/   ró   )r2   r!   r  r?  r  rõ   rA  rU  Zskip_sym_equivrC  r€  r  Zback_interactionsr   r:  r¡  rT  rµ  rZ  Úrt_mx_ji_invrY  r¹   rƒ  r1  rÂ   r­  Z	sym_equivZrt_mx_ji_equivZsite_frac_ji_equivr9   )r´  r8  rh  r  r  r!   r:   rD    sŠ    
 
	







z_.show_distancesc             C   sR   d}xHt | ƒD ]<\}}x2| ¡ D ]&\}}x|D ]}| ¡ s.|d7 }q.W q W qW |S )Nr   rf   )r´   r7  rd  )r2   rö   r8  r   r:  r¡  Úsym_opr9   r9   r:   Ú"number_of_pairs_involving_symmetryb  s    
z$_.number_of_pairs_involving_symmetryc             C   sZ   g }xPt | ƒD ]D\}}x:| ¡ D ].\}}x$|D ]}| ¡ r.| ||f¡ P q.W q W qW |S )N)r´   r7  rd  ró   )r2   rö   r8  r   r:  r¡  r¹  r9   r9   r:   Úsimple_edge_listk  s    
z_.simple_edge_listc             C   sZ   g }xPt | ƒD ]D\}}x:| ¡ D ].\}}x$|D ]}| ¡ s.| |||f¡ q.W q W qW |S )N)r´   r7  rd  ró   )r2   rö   r8  r   r:  r¡  r¹  r9   r9   r:   Úsymmetry_edge_listu  s    
z_.symmetry_edge_listc             C   sr   g }g }x`t | ƒD ]T\}}xJ| ¡ D ]>\}}x4|D ],}| ¡ rN| ||f¡ q2| |||f¡ q2W q$W qW ||fS )N)r´   r7  rd  ró   )r2   ÚsimpleÚsymr8  r   r:  r¡  r¹  r9   r9   r:   Úboth_edge_list~  s    
z_.both_edge_listc             C   sr   t  |  ¡ ¡}x^t| ƒD ]R\}}xH| ¡ D ]<\}}x2|D ]*}| ¡ r8||  |¡ ||  |¡ P q8W q*W qW |S )N)r   Ústl_set_unsignedr>  r´   r7  rd  Úinsert)r2   rö   r8  r   r:  r¡  r¹  r9   r9   r:   Úfull_simple_connectivityŠ  s    
z_.full_simple_connectivityc             C   s2   | |   ¡ dkrdS x| D ]}||krdS qW dS )Nr   TF)r>  )r2   r8  r   r9   r9   r:   Ú	is_paired•  s     
 z_.is_pairedc             C   sV   t ƒ }t ¡  ¡ }x>t| ƒD ]2\}}tƒ }x| ¡ D ]}|||< q4W | |¡ qW |S )N)r¥  r   r%   Úall_opsr´   r   Úkeysró   )r2   rö   r¡  r8  Úself_pair_sym_dictro  r:  r9   r9   r:   Údiscard_symmetry›  s    z_.discard_symmetryc             C   sn   |   ¡ }|  ¡ |kst‚xPt| |ƒD ]B\}}x8| ¡ D ],\}}||k sJt‚| |¡ ||  |¡ q6W q$W d S )N)r>  r   r   r7  Ú
setdefaultÚextend)r2   r<   Z	self_sizerÆ  Zother_pair_sym_dictr:  Zother_sym_opsr9   r9   r:   Úadd_pair_sym_table_in_place¥  s    
z_.add_pair_sym_table_in_place)N)NNNNN)NNNFFFN)r   r  r  r¢  r¬  r®  r@  rD  rº  r»  r¼  r¿  rÂ  rÃ  rÇ  rÊ  r9   r9   r9   r:   rÂ   †  s.   
"    
9      
U	
	
c               @   s   e Zd Zdd„ Zdd„ ZdS )Ú_clustering_mix_inc             C   s   | j  ¡ j| jdS )N)r  )r©   r!   r†   r  )r2   r9   r9   r:   rõ   °  s    
z_clustering_mix_in.sites_cartc             C   s˜   t  ¡ }x| jD ]}| t|ƒ¡ qW t j|dd}t j| j|d}g }xDt|ƒD ]8\}}t|ƒdkrhP t  |¡}| | t j|d¡¡ qRW || _| S )NT)Úreverse)Úsequencerm  r   )rÉ   )r   rS  Úindex_groupsró   rÓ   r`  ra  r´   )r2   Úcluster_sizesÚigrm  Úsorted_index_groupsrÎ  r¸   r9   r9   r:   Útidy_index_groups_in_place´  s     
z-_clustering_mix_in.tidy_index_groups_in_placeN)r   r  r  rõ   rÒ  r9   r9   r9   r:   rË  ®  s   rË  c          	   C   sŒ   t  ¡ }x|D ]}| t|ƒ¡ qW t j|dd}t j||d}t  ¡ }x>t|ƒD ]2\}}t  |¡}| | t j|  |¡dd¡¡ qRW |S )NT)rÌ  )rÍ  rm  )rÉ   rÌ  )r   rS  ró   rÓ   r`  ra  r´   rÉ  )ÚscoresrÎ  rÏ  rÐ  rm  rÑ  Ú
prioritiesr¸   r9   r9   r:   Ú!_priorities_based_on_cluster_sizeÄ  s    

rÕ  c               @   s   e Zd Zddd„ZdS )Úincremental_clusteringNFr   c       )      C   s4  || _ || _| ¡ }|j|d}	|j|	d}
|s^xx|
 ¡ D ]}|
 |¡ ¡ |	|  |	|< q:W nLt 	|	 
¡ |
 ¡ ¡ }|
 |¡}
|
 ¡ dksŽt‚|	 |¡}	|d k	rª| |¡}|rè| ¡  ¡ j|	d}|
 |¡}
|	 |¡}	|d k	rè| |¡}|	 
¡ }t t|ƒ¡}|}dd„ t|ƒD ƒ}| ¡ dƒg| }|j}x¾t|ƒD ]°\}}|dkrNP |j||	|
d}t|d}|j|d	 |d kr†| ¡ }||kr tj|d
d}nt||d}x8|D ].}|| }|dkrô|t|ƒd krôt|| ƒ|k rôq´| |d¡}||	|  }| ¡ | }xÆ| ¡ D ]¸\}}|| }||krDq$|dkrv|t|ƒd krvt|| ƒ|k rvq$|d }d } xJ|D ]B}!|!d }"| ||"¡}#|#|	|  }$|||$ƒ}%||%krˆ|%}|#} qˆW | d k	sÜt‚| }#t|| ƒt|| ƒkrf||   | !¡   |#  ||  !¡ ¡¡¡}&x:|| D ].}'||  "|'¡ |||'< |&  ||' ¡||'< q*W g ||< nn||   |# !¡   |  ||  !¡ ¡¡¡}&x:|| D ].}'||  "|'¡ |||'< |&  ||' ¡||'< q–W g ||< |}|d8 }q$W q´W q8W |dksüt‚x&t|	ƒD ]\}}(|| |( |	|< qW |	| _#|| _$d S )N)rõ   )r  r   c             S   s   g | ]
}|g‘qS r9   r9   )rÇ   r8  r9   r9   r:   rÈ   û  s    z3incremental_clustering.__init__.<locals>.<listcomp>rf   )r™   r  r  )rš   )r  T)rÉ   rÌ  )rÓ  rÎ  gzo ð?)%r©   Údistance_cutoffsr!   rˆ   r  Úspecial_position_indicesr£  r2  r   Úboolr>  ra  Ún_special_positionsr   rŠ   r›   Zis_inside_fracrS  r   r%   r1  r´   rš   r&  r'  rT  r`  rÕ  rÓ   r^  r6  r7  r_  ro   ró   r  rÎ  ))r2   r©   rõ   r×  rÓ  Údiscard_special_positionsZdiscard_not_strictly_inside_asuZinitial_required_cluster_sizer!   r  r  r8  Ú	selectionÚn_sitesÚassignmentsÚ
n_clustersrÎ  Úsymmetry_opsÚget_distanceZi_distance_cutoffr  rš   Úpair_asu_tabrÔ  Ú	i_clusterZrt_mx_ipZsite_ipr9  r:  r;  Ú	j_clusterZsmallest_distanceZbest_rt_mx_jpr<  rk  Zrt_mx_jpZsite_jpr1  Úrt_mx_cÚc_seqrù   r9   r9   r:   r;   Õ  sÎ    






 




 






zincremental_clustering.__init__)NFFr   )r   r  r  r;   r9   r9   r9   r:   rÖ  Ó  s      rÖ  c               @   s   e Zd Zddd„ZdS )Údistance_based_clusteringFc       "      C   sD  || _ || _| ¡ }|j|d}|j|d}|s^xf| ¡ D ]}| |¡ ¡ ||  ||< q:W n:t 	| 
¡ | ¡ ¡ }	| |	¡}| ¡ dksŽt‚| |	¡}| 
¡ }
t t|
ƒ¡}|
}dd„ t|
ƒD ƒ}| ¡ dƒg|
 }|j|||d}t|d}|j|d | ¡ }g }t ¡ }|j}xd| ¡ D ]X}||j }||j }|j| }|||ƒ}||d	 ksbt|ƒ‚| |¡ | |¡ q W tj|d
}xr|D ]h}|dkr¢P || }|j}|j}|| }|| }||krÔqt|| ƒt|| ƒkrR||  |j ||  ¡ ¡¡}x:|| D ].} ||  | ¡ ||| < | ||  ¡|| < qW g ||< nf||  |j ¡  ||  ¡ ¡¡}x:|| D ].} ||  | ¡ ||| < | ||  ¡|| < q~W g ||< |d8 }t ||| ||  || ||  ƒ||  ƒdk st‚qW |dkst‚x&t!|ƒD ]\}}!|| |! ||< qW || _"|| _#d S )N)rõ   )r  r   c             S   s   g | ]
}|g‘qS r9   r9   )rÇ   r8  r9   r9   r:   rÈ   b  s    z6distance_based_clustering.__init__.<locals>.<listcomp>)r™   r  r  )rš   )r  gzo ð?)rÉ   rf   gíµ ÷Æ°>)$r©   r  r!   rˆ   r  rØ  r£  r2  r   rÙ  r>  ra  rÚ  r   rS  r   r%   rš   r&  r'  Úextract_pair_sym_tablerO  r1  r¢  r8  r:  rZ  ró   r`  rÓ   r_  ro   rü   r´   r  rÎ  )"r2   r©   rõ   r  rÛ  r!   r  r  r8  rÜ  rÝ  rÞ  rß  rÎ  rà  rš   râ  Zpair_sym_tabZ	sym_pairsrP  rá  ÚpairZsite_iZsite_jZsite_jir1  rÔ  Zi_pairr:  rã  rä  rå  ræ  rù   r9   r9   r:   r;   I  sš    








 
 


,z"distance_based_clustering.__init__N)F)r   r  r  r;   r9   r9   r9   r:   rç  G  s   rç  c                sˆ  ddl m} ddlm‰ | |  ¡ ¡}| |  ¡ ¡}|| }| ‡ ‡fdd„|D ƒ¡}|ˆ  }|| d }	|	|d  }
| |
 dˆ   }t |¡}t 	| 
¡ d¡}dd„ t| ¡ ƒD ƒ}xNt|ƒD ]B\}}d	d„ t||ƒD ƒ}||ƒ}||  d
7  < ||  |¡ qÀW tj|dd}| |¡}|  ¡ | }d}x"|D ]}||7 }||kr4P q4W ~~t 	¡ }x$||k ¡ D ]}| || ¡ qlW |S )Nr   )r   )Úiceilc                s   g | ]}ˆ|ˆ  ƒ‘qS r9   r9   )rÇ   ru  )Úbox_sizerê  r9   r:   rÈ   ¢  s    z#cluster_erosion.<locals>.<listcomp>r   g      ð?c             S   s   g | ]}t  ¡ ‘qS r9   )r   rS  )rÇ   r¸   r9   r9   r:   rÈ   ©  s    c             S   s$   g | ]\}}t d tt|ƒ|ƒƒ‘qS )r   )r|  ÚminÚint)rÇ   r¸   Únr9   r9   r:   rÈ   «  s    rf   T)rÉ   rÌ  )rí   r   Úlibtbx.math_utilsrê  rò   rì  r|  r   ÚgridrS  Úsize_1dr   r>  r´   r   ró   r`  ra  Ú
iselectionrÉ  )rõ   rë  Zfraction_to_be_retainedr   Z
lower_leftZupper_rightÚ
sites_spanZn_boxesZbox_spanZsites_centerZ
box_originZbox_coordinatesZbox_gridZ
box_countsZbox_membersr8  ru  Zbox_index_3dZbox_index_1dÚpermZbox_counts_sortedÚ	thresholdZ
sum_countsZrequired_countsZsite_selectionZi_boxr9   )rë  rê  r:   Úcluster_erosionœ  s@    



rö  c              C   s0   t jdd} t d¡}ddlm} |j|| dS )NÚP1)r   )rf   rf   rf   éZ   rø  rø  r   )Úcrystal)r!   r$   )r   r$   r   r!   r”   rù  r   )rä   r‰   rù  r9   r9   r:   Úunit_crystal_symmetry¾  s    
rú  )NNNNr  r   )NNNrf   r0  )RÚ
__future__r   r   r   Úcctbx.array_familyr   Úboost_adaptbx.boost.pythonÚboostÚpythonÚbpÚ	six.movesr   r   Ú
import_extr    r   Zcctbx.crystal.find_best_cellr
   r”   r   r   r   r   Úlibtbx.containersr   Úlibtbx.forward_compatibilityr   r}  r   rí   r   Úscitbx.stl.setÚscitbx.stl.vectorrL  Úlibtbx.utilsr   r   rH   r   r×   rØ   r   Zscitbx.cubicle_neighborsZ"cubicles_max_memory_allocation_setZcubicle_neighborsZ"cubicles_max_memory_allocation_getÚstl_vector_rt_mxr¨  ÚvectorÚset_unsignedZpair_asu_j_sym_groupsr¬   ÚunsignedZpair_asu_j_sym_groupr   r  r  r©   r5  Úinject_intor&  rÂ   rK  Úslots_getstate_setstaterD  r…  rE  r”  r–  rJ  rŸ  r¥  rË  rÕ  rÖ  rç  rö  rú  ÚinjectZneighbors_simple_pair_generatorÚpy3_make_iteratorr!  r9   r9   r9   r:   Ú<module>   s’   


   UB     
 <    
PZP`@ 
1  *tU"