B
    §dŒ9 ã            
   @   sÜ  d dl mZmZmZ d dl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 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Zd dl Zd dl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ej' (dd¡Z)e	 *e+¡G dd„ dƒƒZ,dˆdd„Z-G dd„ de.ƒZ/d‰dd„Z0dŠd d!„Z1d"d#„ Z2e2ej3_2e2ej4_2e5ej4_5e6ej4_6e7ej4_7e8ej4_8e9ej4_9d‹d$d%„Z:dŒd)d*„Z;dd,d-„Z<dŽd.d/„Z=dd1d2„Z>G d3d4„ d4ej?ƒZ?e	 *ej?¡G d5d„ dƒƒZ,ej@dd6ZAe	 *ejB¡G d7d„ dƒƒZ,G d8d9„ d9ejCƒZCdd:d;„ZDejEeFeGd<ZHG d=d>„ d>e.ƒZIG d?d@„ d@eIƒZJG dAdB„ dBe.ƒZKG dCdD„ dDe.ƒZLG dEdF„ dFe.ƒZMG dGdH„ dHe.ƒZNG dIdJ„ dJe.ƒZOdKdL„ ZPd‘dNdO„ZQG dPdQ„ dQe.ƒZRdRdS„ ZSG dTdU„ dUe.ƒZTd’dWdX„ZUd“dZd[„ZVG d\d]„ d]e.ƒZWd^d_„ ZXd”dadb„ZYdcdd„ ZZdedf„ Z[dgdh„ Z\G didj„ dje.ƒZ]dkdl„ Z^d(dmdnd+dodpdqdrdrej_f
dsdt„Z`d•dvdw„Zad–dxdy„Zbd—dzd{„Zcd˜d|d}„Zdd™d~d„Zedšd€d„Zfd›d„d…„Zgd†d‡„ ZhdS )œé    )Úabsolute_importÚdivisionÚprint_functionN)Úrange)ÚzipÚcctbx_maptbx_ext)Ú*)Úcrystal)Úsgtbx)Úflex)Úmatrix)Údicts)Úadopt_init_args)ÚSorry)Úadptbx)Ú
group_args)Úfftpack)Úapprox_equal)ÚuctbxZ(CCTBX_MAPTBX_DEBUG_PEAK_CLUSTER_ANALYSISÚ c               @   s   e Zd Zdd„ ZdS )Ú_c             C   sš   |   ¡ }|  ¡ }g }g }xxtt|ƒƒD ]h}|d|df |d|df |d|df f}|d|df |d|df |d|df f}| |¡ | |¡ q&W ||fS )zî
    get lists of minimum and maximum coordinates for each connected
    region.
    returns 2 lists of tuples: first is minimum, second is maximum coordinates.
    [(x0, y0, z0), (x1, y1, z1), ...] where 0, 1, ... - number of region
    r   é   é   )Zget_blobs_boundariesZregionsr   ÚlenÚappend)ÚselfZ
boundariesÚregsZmin_boundariesZmax_boundariesÚiZminbZmaxb© r   út/mnt/filia/a/genomebrowser/www/genomebrowser/fleming/tools/molprobity/modules/cctbx_project/cctbx/maptbx/__init__.pyÚget_blobs_boundaries_tuples"   s    ((
z_.get_blobs_boundaries_tuplesN)Ú__name__Ú
__module__Ú__qualname__r    r   r   r   r   r      s   r   ÚexpTc             C   s„  ddl m} |dkst‚d }|dkrê|j| |dd}| ¡  ¡ }| |dkd¡ d	t |¡ d
 }	dt	j
d  |d  }
t |
 |	 ¡}|j| ¡ | d}t| ¡ | ¡ |  ¡ d}|j||d}| ¡  | ¡ }|rè| |dk d¡}n–|dkr€tt | ¡d	 ƒdk st‚t | ¡}|dk r.|dks2t‚|  ¡ }x tdƒD ]}tj|dd qDW x"tdƒD ]}tj|ddd qfW |S )Nr   )Úmiller)r$   Úbox_averager$   T)ÚmapÚcrystal_symmetryÚinclude_000éÿÿÿÿg    _ Bg      ð?g      @é   r   )Údata)Ú	unit_cellÚspace_group_infoÚpre_determined_n_real)Úcrystal_griddingÚfourier_coefficientsg        r&   gíµ ÷Æ°>é   r   )Úmap_dataÚ
index_spang®Gáz®ï?)r3   Úcutoffr4   )Úcctbxr%   ÚAssertionErrorÚstructure_factor_box_from_mapÚ
d_spacingsr,   Úset_selectedr   Úpow2ÚmathÚpir$   Úarrayr0   r-   r.   ÚallÚfft_mapÚapply_volume_scalingÚreal_map_unpaddedÚabsÚmaxÚminÚ	deep_copyr   ÚmaptbxZmap_box_average)r'   r(   Ú
rad_smoothÚmethodZnon_negativer%   Z
map_smoothÚf_mapZdddÚssZb_smoothZsmooth_scaleÚcgr@   Zmminr   r   r   r   Ú
smooth_map4   sP    

rM   c               @   s   e Zd Zddd„Zdd„ ZdS )Úd99Nc             C   sÎ   t | tƒ ƒ |d k	rV|d ks t‚|d k	s,t‚t|dj}ddlm} |j||d| _n||g 	d ¡dkslt‚| j 
¡  ¡ | _
t | j
¡t | j
¡ | _| _tj| j ¡ | j
| j ¡ dd}t| ¡ d| _d S )	N)r3   r   )r%   )r'   r(   r   g®Gáz®ï?)Úfr9   Úhklr5   )rN   )r   Úlocalsr7   Úshift_origin_if_neededr3   r6   r%   r8   rJ   Úcountr9   r,   r   rD   rE   Úd_maxÚd_minÚextrN   Úindicesr   Úresult)r   r'   rJ   r(   r%   Úor   r   r   Ú__init__`   s$    zd99.__init__c             C   s<   d}x2t | jj| jjƒD ]\}}t|||f |d qW d S )Nz%12.6f %8.6f)Úfile)r   rX   Úd_minsÚccsÚprint)r   ÚlogÚfmtrU   Úccr   r   r   Úshowu   s    zd99.show)NNN)r!   r"   r#   rZ   rb   r   r   r   r   rN   _   s   
rN   úMaps have different gridding.c             C   sP   |   ¡ |  ¡ k}|  ¡ | ¡ k}|  ¡ | ¡ k}|||g d¡dkrLt|ƒ‚d S )NTr2   )ÚfocusÚoriginr?   rS   r   )Úmap_1Úmap_2ZSorry_messageÚf1Úf2Úf3r   r   r   Úassert_same_griddingz   s
    rk   c          	   C   sx  | s|r|st ‚d}n"|  ¡ dko4|  ¡ dko4|  ¡  }d }d }|rZ| rd|  ¡ }	|  ¡ }
|  ¡ } n|}	|}
|
}d}|rP| ¡  ¡  	¡ dkr–t
dƒ‚| ¡  ¡ d d… \}}}| ¡  ¡ }|
d |	d  |
d |	d  |
d |	d    }}}| | | g}| ¡  |¡}tt |¡ ƒ}|d k	r<|t | ¡ |¡ }|rX|j|d	}nd }d }nd}d}t| ||||||d
S )NTr   r2   )r   r   r   )r   r   z-Space groups other than P1 are not supported.r   r   )Zcoordinate_offset)r3   Ú
ncs_objectÚ
sites_cartÚ
shift_fracÚ
shift_cartÚoriginal_origin_grid_unitsÚoriginal_origin_cart)r7   Úfocus_size_1dÚndÚ
is_0_basedr?   re   Úshift_originÚspace_groupÚtypeÚnumberr   r-   Ú
parametersÚfractionalization_matrixÚorthogonalizeÚtupler   Úcolr   Úvec3_doubleÚsizerF   r   )r3   rm   r(   rl   Zorigin_grid_unitsZn_xyzZshift_neededrn   ro   ÚNÚOrp   rq   ÚaÚbÚcÚfmZsxZsyÚszr   r   r   rR   ‚   sR    

4
rR   c             C   s   | t |  ¡ |ƒ S )N)Zclosest_grid_pointÚaccessor)r'   Úx_fracr   r   r   Úvalue_at_closest_grid_point¼   s    r‰   c             C   sö   ddl m} ||g d¡dks"t‚||g d¡dks8t‚||g d¡dkrZtj||| dS ||g d¡dkrêt| ¡ | ¡ ƒ}|j|t	dd}|j
||d}| ¡ }|j
||d}| ¡ }t|d	d
 ¡ }	t|d	d
 ¡ }
tj|	|
| dS tdƒ‚dS )zÐ
  Compute CCpeak as described in
    Acta Cryst. (2014). D70, 2593-2606
    Metrics for comparison of crystallographic maps
    A. Urzhumtsev, P. V. Afonine, V. Y. Lunin, T. C. Terwilliger and P. D. Adams
  r   )r%   N)r   r   )rf   rg   r5   g      Ð?)rU   Úsymmetry_flagsÚresolution_factor)r0   r1   i'  )r'   Ún_binsz$Combination of inputs not supported.)r6   r%   rS   r7   rV   Úcc_peakrE   rU   r0   Úuse_space_group_symmetryr@   rB   Úvolume_scaler3   r   )r5   rf   rg   Zmap_coeffs_1Zmap_coeffs_2r%   rU   r0   r@   Zm1_heZm2_her   r   r   r   É   s.    r   é   r   é
   c             C   s   t j| |||||dS )zg
  Good defaults for 2mFo-DFc type maps:
    smearing_b = 1, max_peak_scale = 100, smearing_span = 5
  )Ún_realÚ
smearing_bÚmax_peak_scaleÚsmearing_spanÚuse_exp_tableÚuse_max_map)rV   Úmap_accumulator)r’   r—   r“   r”   r•   r–   r   r   r   r˜   ê   s    r˜   ç      ø?c          
   C   s¤   t  ¡ }| ¡  |¡}xpt||ƒD ]b\}}|  |¡|kr"t| ¡ |  ¡ |  ¡ t  	|g¡t  |gd ¡d}	| 
|  |	¡|k d¡¡ q"W t  |d ¡}
|
dkr d S |
S )Nr   )r-   Ú
fft_n_realÚ
fft_m_realrm   Ú
site_radiiTr   )r   Údoubler-   Úfractionalizer   r‰   Úgrid_indices_around_sitesrd   r?   r~   r   ÚselectrS   Úmin_default)r3   rm   r(   r5   Úatom_radiusÚvÚ
sites_fracÚscÚsfÚselÚrr   r   r   Úpeak_volume_estimateô   s    
 r©   c             C   s8   t | ƒ ¡ }|dkr | | } dS tj| ||||d dS )zñ
  Trunate map inplace by standard deviation (sigma) while scale it with
  specified scale, such as volume (scale_by = 1/volume) or sigma
  (scale_by = 1/standard_deviation). Input map_data is expected to be unscaled (
  right out of FT).
  r   N)r3   Ústandard_deviationÚby_sigma_less_thanÚscale_byÚ	set_value)Ú
statisticsÚsigmarV   Útruncate)r3   r«   r¬   r­   r¯   r   r   r   r°     s    r°   r   c       	      C   sb   | j dd}|d kr,ddlm} ||d}nt | ¡  ¡ |¡}tj| 	¡ | 
¡ ||||| dS )NT)Úsites_mod_positiver   )Úvdw_radii_from_xray_structure)Úxray_structure)r¤   r-   r’   Úmask_value_inside_moleculeÚmask_value_outside_moleculeÚradii)Úexpand_to_p1Zcctbx.masksr²   r   r   Ú
scatterersr   rV   Úmaskr¤   r-   )	r³   r’   r´   rµ   Zsolvent_radiusr¢   Zxrs_p1r²   Z
atom_radiir   r   r   r¹     s    r¹   c               @   s   e Zd Zdd„ ZdS )r®   c             C   s   t j | |¡ d S )N)rV   r®   rZ   )r   r'   r   r   r   rZ   -  s    zstatistics.__init__N)r!   r"   r#   rZ   r   r   r   r   r®   +  s   r®   c               @   s   e Zd Zddd„ZdS )r   Nr   c             C   sr   |d krt j}t|d|  ¡   |d t|d|  ¡   |d t|d|  ¡   |d t|d|  ¡   |d d S )Nzmax %.6g)r[   zmin %.6gz	mean %.6gz
sigma %.6g)ÚsysÚstdoutr^   rD   rE   Úmeanr¯   )r   rO   Úprefixr   r   r   Úshow_summary3  s     z_.show_summary)Nr   )r!   r"   r#   r¾   r   r   r   r   r   0  s   )rŽ   c               @   s   e Zd ZdZdd„ ZdS )r   z3
  Injector for extending cctbx.maptbx.histogram
  c             C   sh  |  ¡ }| ¡ }d}x.t|  ¡ ƒD ]\}}|d |kr"|d }P q"W |dksPt‚|  ¡ | }	| ||	k¡}
tt||d  ƒ|
 ¡ ƒ}t	 
|
¡}|
 |¡}~| ¡ |ksªt‚||  }~
~d}x*t|  ¡ ƒD ]\}}|d |krÊ|}P qÊW |dksôt‚|  ¡ | }| ||k¡}tt||d  ƒ| ¡ d ƒ}t	 
|¡}| |¡}~| ¡ |ksTt‚|| }~~||fS )aŸ  
    For the double-step filtration in cctbx.miller (used as part of the
    procedure for replacing missing F-obs in maps), we need to calculate upper
    and lower cutoffs for the data based on percentile values.  This can be
    done in just a few lines of code by using flex.sort_permutation over the
    entire map, but this has a huge memory overhead (and possibly computational
    overhead as well).  Since we are only interested in subsets of values at
    the extreme ends of the distribution, we can perform the sort for these
    subsets instead, which should cut down on memory use.

    Returns the upper and lower map value cutoffs (as Python floats).
    r*   éd   r   r   g      Y@)Úas_1dr   Ú	enumerateZv_valuesr7   Ú	argumentsr    rE   Úintr   Úsort_permutationZc_values)r   r'   Úvol_cutoff_plus_percentÚvol_cutoff_minus_percentÚ
map_valuesr   Z
i_bin_plusÚi_binÚvalueZcutoffp_lower_limitZ
top_valuesZi_upperÚsZtop_values_sortedÚcutoffpZi_bin_minusZcutoffm_upper_limitZbottom_valuesZi_lowerZbottom_values_sortedÚcutoffmr   r   r   Úget_percentile_cutoffsD  sJ    





z_.get_percentile_cutoffsN)r!   r"   r#   Ú__doc__rÍ   r   r   r   r   r   =  s   c               @   s   e Zd Zddd„ZdS )Ú	peak_listr   r   NTc          	   C   s<   |d kr t j | |||||¡ nt j | ||||||¡ d S )N)rV   rÏ   rZ   )r   r,   ÚtagsÚpeak_search_levelÚ	max_peaksÚpeak_cutoffÚinterpolater   r   r   rZ   |  s
    zpeak_list.__init__)r   r   NT)r!   r"   r#   rZ   r   r   r   r   rÏ   z  s      rÏ   c             C   s   t  | |||¡S )N)rV   Úas_CObjectZYX)Úmap_unit_cellÚfirstÚlastÚapply_sigma_scalingr   r   r   rÕ   ‰  s    rÕ   )Úto_mapÚfrom_mapc            	   @   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„ 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 )#r0   Nr   Tc          	   C   sô   |
d krr||g  d ¡dkst‚|d k	r4|d }d}n|d kr@d}|d k	rT|d k	sTt‚|d kr`d}t|ƒdks–t‚n$|d ks~t‚|d ksŠt‚|d ks–t‚t| tƒ dd |
d k	r¶|
| _n:|d k	rÜt||||| ¡ |||	ƒ| _nt||||||	ƒ| _d S )	Nr   r   g      à?gUUUUUUÕ?)r   r   r   r2   T)Úhide)rS   r7   r   r   rQ   Ú_n_realZdetermine_griddingrw   )r   r-   rU   r‹   ÚsteprŠ   r.   Úmandatory_factorsÚ	max_primeÚassert_shannon_samplingr/   r   r   r   rZ   ’  s4    
  zcrystal_gridding.__init__c             C   sD   |j | _ |j| _|j| _|j| _|j| _|j| _|j| _|j| _d S )N)Ú
_unit_cellÚ_d_minÚ_resolution_factorÚ_symmetry_flagsÚ_space_group_infoÚ_mandatory_factorsÚ
_max_primerÝ   )r   Úotherr   r   r   Ú_copy_constructor·  s    z"crystal_gridding._copy_constructorc             C   s   | j S )N)râ   )r   r   r   r   r-   Á  s    zcrystal_gridding.unit_cellc             C   s   | j S )N)rã   )r   r   r   r   rU   Ä  s    zcrystal_gridding.d_minc             C   s   | j S )N)rä   )r   r   r   r   r‹   Ç  s    z"crystal_gridding.resolution_factorc             C   s   | j S )N)rå   )r   r   r   r   rŠ   Ê  s    zcrystal_gridding.symmetry_flagsc             C   s   | j S )N)ræ   )r   r   r   r   r.   Í  s    z!crystal_gridding.space_group_infoc             C   s(   |  ¡  |  ¡ ¡|  ¡ kst‚|| _d S )N)ÚgroupÚrefine_griddingr’   r7   ræ   )r   r.   r   r   r   Úchange_space_groupÐ  s    z#crystal_gridding.change_space_groupc             C   s   | j S )N)rç   )r   r   r   r   rß   Õ  s    z"crystal_gridding.mandatory_factorsc             C   s   | j S )N)rè   )r   r   r   r   rà   Ø  s    zcrystal_gridding.max_primec             C   s   | j S )N)rÝ   )r   r   r   r   r’   Û  s    zcrystal_gridding.n_realc             C   s   |   ¡ d k	st‚|   ¡  ¡ S )N)r.   r7   rë   )r   r   r   r   rv   Þ  s    zcrystal_gridding.space_groupc             C   s&   |   ¡ d k	st‚tj|  ¡ |   ¡ dS )N)r-   r.   )r.   r7   r	   Úsymmetryr-   )r   r   r   r   r(   â  s    z!crystal_gridding.crystal_symmetryc             C   s"   d}x|   ¡ D ]}||9 }qW |S )Nr   )r’   )r   rX   Únr   r   r   Ún_grid_pointsè  s    zcrystal_gridding.n_grid_pointsc             C   s   t | ƒS )N)Úcrystal_gridding_tags)r   r   r   r   rÐ   î  s    zcrystal_gridding.tags)	NNNNNNr   TN)r!   r"   r#   rZ   rê   r-   rU   r‹   rŠ   r.   rí   rß   rà   r’   rv   r(   rð   rÐ   r   r   r   r   r0     s.           

r0   c               @   s&   e Zd Zdd„ Zdd„ Zd	dd„ZdS )
rñ   c             C   s^   t  | |¡ | ¡ d k	st‚t|  ¡ d| _| jj|  ¡  	¡ |  ¡ d | j 
¡ dksZt‚d S )N)Údim)Úspace_group_typerŠ   r   )r0   rê   rŠ   r7   Z	grid_tagsr’   Ú_tagsÚbuildr.   rw   Zn_grid_misses)r   Úgriddingr   r   r   rZ   ó  s    
zcrystal_gridding_tags.__init__c             C   s   | j S )N)rô   )r   r   r   r   rÐ   ü  s    zcrystal_gridding_tags.tagsTc             C   sÌ   |d krt ƒ }|r*tjjr*| j |¡s*t‚| ¡  ¡ rJt	|t
 | ¡ ¡ƒ}t|| j ¡ | ¡ | ¡ | ¡ | ¡ d}| ¡ d kr„|S t|tj|  ¡ | ¡ d| ¡ | ¡ | ¡ | ¡ | ¡ | ¡ | ¡ d	S )N)r,   rÐ   rÑ   rÒ   rÓ   rÔ   )r(   Úmin_distance_sym_equiv)	rÏ   Úspecial_position_settingsÚgeneral_positions_onlyÚeffective_resolutionÚsignificant_height_fractionÚcluster_height_fractionÚmin_cross_distanceÚmax_clustersÚmin_cubicle_edge)Úpeak_search_parametersÚlibtbxÚenvÚfull_testingrô   Úverifyr7   r‡   Ú	is_paddedÚcopyr   Úgridrd   rÏ   Z	tag_arrayrÑ   rÒ   rÓ   rÔ   r÷   Úpeak_cluster_analysisr	   rø   r(   rù   rú   rû   rü   rý   rþ   rÿ   )r   ry   r'   Úverify_symmetryZ
grid_peaksr   r   r   Úpeak_searchÿ  s6    
z!crystal_gridding_tags.peak_searchN)T)r!   r"   r#   rZ   rÐ   r
  r   r   r   r   rñ   ñ  s   	rñ   c               @   s&   e Zd Zd	dd„Zdd„ Zdd„ ZdS )
Úboxes_by_dimensionNr   c             C   s~   || _ |d |d  }|d |d  }|d |d  }t|| ƒ}	t|| ƒ}
t|| ƒ}|  |	|
|¡}|t| jƒkszt‚d S )Nr   r   r   )r’   rÃ   Ú_generate_boxesr   Ústartsr7   )r   r’   Úabcrò   r_   r½   Zstep_1Zstep_2Zstep_3Zi_step_1Zi_step_2Zi_step_3Ún_boxesr   r   r   rZ     s    zboxes_by_dimension.__init__c          	   C   sÖ   dd„ }g }x@t |||gƒD ].\}}| j| j| |d}||ƒ}| |¡ qW g | _g | _xp|d D ]d}x^|d D ]R}	xL|d D ]@}
| j |d |	d |
d g¡ | j |d |	d |
d g¡ q€W qrW qdW t| jƒS )Nc             S   s”   | t | ƒd  d }t|t | ƒ ƒ}g }xftt | ƒƒD ]V}|dkrLd}|}n2|t | ƒd krj|| }|}n|| }|d | }| ||g¡ q6W |S )Nr   r   )r   rÃ   r   r   )ÚbeÚmaxerÞ   rX   r   Úlr¨   r   r   r   Úregroup0  s    z3boxes_by_dimension._generate_boxes.<locals>.regroup)Ú	n_real_1drÞ   r   r   r   )rÁ   Ú
_box_edgesr’   r   r  Úendsr   )r   ÚbaÚbbÚbcr  r  r   rƒ   Úbe_ÚjÚkr   r   r   r  /  s    *z"boxes_by_dimension._generate_boxesc             C   s–   g }xt d||ƒD ]}| |¡ qW | |¡ g }x^t t|ƒƒD ]N}|dkrd| |d |d g¡ q@|t|ƒd kr@| || ||d  g¡ q@W |S )Nr   r   )r   r   r   )r   r  rÞ   Úlimitsr   Úbox_1dr   r   r   r  N  s     
  zboxes_by_dimension._box_edges)Nr   )r!   r"   r#   rZ   r  r  r   r   r   r   r    s    
r  c               @   s*   e Zd ZdZddd„Zdd„ Zd	d
„ ZdS )Úboxesz]
  Split box defined by n_real into boxes where each box is a fraction of the
  whole box.
  NéÐ  r   c          	   C   s
  || _ d}d}g }x ||kr²td| tdt|d | ƒƒƒtd| tdt|d | ƒƒƒtd| tdt|d | ƒƒƒ  }	}
}|  |	|
|¡}| |¡dkržP | |¡ |d7 }qW |t| jƒksÆt	‚|rt
|d||d t
|d	|	|
||d t
|d
t| jƒ|d d S )Nr   g    eÍÍAr‘   r2   r   r   zn1, n2, n3 (n_real)  :)r[   zpoints per box edge:znumber of boxes    :)r’   rE   rD   rÃ   r  rS   r   r   r  r7   r^   )r   r’   Úfractionr_   Z	max_boxesr½   r   r  Zn_boxes_r  r  r  r   r   r   rZ   ]  s$    
( 
zboxes.__init__c          	   C   sÖ   dd„ }g }x@t |||gƒD ].\}}| j| j| |d}||ƒ}| |¡ qW g | _g | _xp|d D ]d}x^|d D ]R}	xL|d D ]@}
| j |d |	d |
d g¡ | j |d |	d |
d g¡ q€W qrW qdW t| jƒS )Nc             S   s”   | t | ƒd  d }t|t | ƒ ƒ}g }xftt | ƒƒD ]V}|dkrLd}|}n2|t | ƒd krj|| }|}n|| }|d | }| ||g¡ q6W |S )Nr   r   )r   rÃ   r   r   )r  r  rÞ   rX   r   r  r¨   r   r   r   r  w  s    z&boxes._generate_boxes.<locals>.regroup)r  rÞ   r   r   r   )rÁ   r  r’   r   r  r  r   )r   r  r  r  r  r  r   rƒ   r  r  r  r   r   r   r  v  s    *zboxes._generate_boxesc             C   s–   g }xt d||ƒD ]}| |¡ qW | |¡ g }x^t t|ƒƒD ]N}|dkrd| |d |d g¡ q@|t|ƒd kr@| || ||d  g¡ q@W |S )Nr   r   )r   r   r   )r   r  rÞ   r  r   r  r   r   r   r  •  s     
  zboxes._box_edges)NNr   r   )r!   r"   r#   rÎ   rZ   r  r  r   r   r   r   r  X  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„ 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   r   r   NTFr   c             C   s   t | tƒ dd d S )NT)rÜ   )r   rQ   )r   rÑ   rÒ   rÓ   rÔ   r÷   rù   rú   rû   rü   rý   rþ   rÿ   r   r   r   rZ   ¡  s    zpeak_search_parameters.__init__c             C   sd   |j | _ |j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j	| _	|j
| _
|j| _d S )N)Ú_peak_search_levelÚ
_max_peaksÚ_peak_cutoffÚ_interpolateÚ_min_distance_sym_equivÚ_general_positions_onlyÚ_effective_resolutionÚ_significant_height_fractionÚ_cluster_height_fractionÚ_min_cross_distanceÚ_max_clustersÚ_min_cubicle_edge)r   ré   r   r   r   rê   ¯  s    z(peak_search_parameters._copy_constructorc             C   s   | j S )N)r"  )r   r   r   r   rÑ   ½  s    z(peak_search_parameters.peak_search_levelc             C   s   | j S )N)r#  )r   r   r   r   rÒ   À  s    z peak_search_parameters.max_peaksc             C   s   | j S )N)r$  )r   r   r   r   rÓ   Ã  s    z"peak_search_parameters.peak_cutoffc             C   s   | j S )N)r%  )r   r   r   r   rÔ   Æ  s    z"peak_search_parameters.interpolatec             C   s   | j S )N)r&  )r   r   r   r   r÷   É  s    z-peak_search_parameters.min_distance_sym_equivc             C   s   | j S )N)r'  )r   r   r   r   rù   Ì  s    z-peak_search_parameters.general_positions_onlyc             C   s   | j S )N)r(  )r   r   r   r   rú   Ï  s    z+peak_search_parameters.effective_resolutionc             C   s   | j S )N)r)  )r   r   r   r   rû   Ò  s    z2peak_search_parameters.significant_height_fractionc             C   s   | j S )N)r*  )r   r   r   r   rü   Õ  s    z.peak_search_parameters.cluster_height_fractionc             C   s   | j S )N)r+  )r   r   r   r   rý   Ø  s    z)peak_search_parameters.min_cross_distancec             C   s   | j S )N)r,  )r   r   r   r   rþ   Û  s    z#peak_search_parameters.max_clustersc             C   s   | j S )N)r-  )r   r   r   r   rÿ   Þ  s    z'peak_search_parameters.min_cubicle_edge)r   r   NTNFNNNNNr   )r!   r"   r#   rZ   rê   rÑ   rÒ   rÓ   rÔ   r÷   rù   rú   rû   rü   rý   rþ   rÿ   r   r   r   r   r   Ÿ  s2              
r   c               @   s   e Zd Zdd„ ZdS )Úcluster_site_infoc             C   s"   || _ || _|| _|| _|| _d S )N)Úpeak_list_indexÚ
grid_indexÚgrid_heightÚsiteÚheight)r   r/  r0  r1  r2  r3  r   r   r   rZ   ã  s
    zcluster_site_info.__init__N)r!   r"   r#   rZ   r   r   r   r   r.  á  s   r.  c               @   sâ   e Zd Zd7dd„Zdd„ ZeZd8d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d„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd9d)d*„Zd+d,„ Zd-d.„ Zd:d/d0„Zd1d2„ Zd3d4„ Zd;d5d6„ZdS )<r  FNr   c
       
      C   sæ   |d k	r |d krd}|d kr d}|d kr0|  ¡ }t| tƒ dd | jd k	sNt‚| ¡ | _|d k	rtt | 	¡ d¡| _
nd | _
|d k	sŠtdkr’d | _n"| jj| j| j  ¡ | j| jd| _t ¡ | _d| _t ¡ | _t ¡ | _t ¡ | _d S )	Ngš™™™™™É?gUUUUUUÕ?T)rÜ   FZuse_old)rý   Úmin_self_distancerù   rÿ   r   )r÷   r   rQ   r+  r7   rö   Z	_griddingr   Úboolr   Ú_is_processedÚdebug_peak_cluster_analysisÚ_site_cluster_analysisÚ_special_position_settingsÚsite_cluster_analysisr'  r-  Úsize_tÚ_peak_list_indicesÚ_peak_list_indexr~   Ú_sitesr   Ú_heightsÚ_fixed_site_indices)
r   rÏ   rø   rù   rú   rû   rü   rý   rþ   rÿ   r   r   r   rZ   ì  s4    	



zpeak_cluster_analysis.__init__c             C   s   | j d k	r|  ¡ S |  ¡ S d S )N)r(  Únext_with_effective_resolutionÚnext_site_cluster_analysis)r   r   r   r   Ú__next__  s    
zpeak_cluster_analysis.__next__c             C   s&   | j d k	r| j|dS | j|dS d S )N)rþ   )r(  Úall_with_effective_resolutionÚall_site_cluster_analysis)r   rþ   r   r   r   r?     s    
zpeak_cluster_analysis.allc             c   s"   xt | ƒ}|d krP |V  qW d S )N)Únext)r   Z	site_infor   r   r   Ú__iter__"  s
     zpeak_cluster_analysis.__iter__c             C   s   | j S )N)Ú
_peak_list)r   r   r   r   rÏ   (  s    zpeak_cluster_analysis.peak_listc             C   s   | j S )N)r9  )r   r   r   r   rø   +  s    z/peak_cluster_analysis.special_position_settingsc             C   s   | j S )N)r'  )r   r   r   r   rù   .  s    z,peak_cluster_analysis.general_positions_onlyc             C   s   | j S )N)r(  )r   r   r   r   rú   1  s    z*peak_cluster_analysis.effective_resolutionc             C   s   | j S )N)r)  )r   r   r   r   rû   4  s    z1peak_cluster_analysis.significant_height_fractionc             C   s   | j S )N)r*  )r   r   r   r   rü   7  s    z-peak_cluster_analysis.cluster_height_fractionc             C   s   | j S )N)r+  )r   r   r   r   rý   :  s    z(peak_cluster_analysis.min_cross_distancec             C   s   | j S )N)r,  )r   r   r   r   rþ   =  s    z"peak_cluster_analysis.max_clustersc             C   s   | j S )N)r8  )r   r   r   r   r:  @  s    z+peak_cluster_analysis.site_cluster_analysisc             C   s   | j S )N)r<  )r   r   r   r   Úpeak_list_indicesC  s    z'peak_cluster_analysis.peak_list_indicesc             C   s   | j S )N)r@  )r   r   r   r   Úfixed_site_indicesF  s    z(peak_cluster_analysis.fixed_site_indicesc             C   s   | j S )N)r>  )r   r   r   r   ÚsitesI  s    zpeak_cluster_analysis.sitesc             C   s   | j S )N)r?  )r   r   r   r   ÚheightsL  s    zpeak_cluster_analysis.heightsc             C   s    | j  ¡ dkrd S | j  ¡ d S )Nr   )rH  r   rL  )r   r   r   r   Úmax_grid_heightO  s    z%peak_cluster_analysis.max_grid_heightr   c             C   sX   | j d k	r| j j|d | j | j ¡ ¡ | j |¡ | j |¡ | j | j ¡ ¡ d S )N)Úoriginal_site)	r8  Úinsert_fixed_site_fracr@  r   r>  r   r?  r<  rH  )r   r2  r3  r   r   r   Úappend_fixed_siteT  s    
z'peak_cluster_analysis.append_fixed_sitec             C   sH   | j  ¡ dkst‚| jd k	r&| j ¡  | j  ¡  | j ¡  | j ¡  d S )Nr   )r<  r   r7   r8  Údiscard_lastÚpop_backr>  r?  )r   r   r   r   rQ  \  s    



z"peak_cluster_analysis.discard_lastc             C   s´   x®| j }|| j ¡ krd S |  j d7  _ | jj| j ¡ | d}| ¡ }| jj||dsZq| j 	¡ | }| j
 |¡ | j |¡ | j |¡ t|| j |¡| j ¡ | ||dS d S )Nr   )r2  )rN  Úsite_symmetry_ops)r/  r0  r1  r2  r3  )r=  rH  r   r9  Úsite_symmetryrK  Ú
exact_siter8  Úprocess_site_fracrL  r<  r   r>  r?  r.  Úgrid_indicesÚgrid_heights)r   r/  rT  r2  r3  r   r   r   rB  d  s,      
z0peak_cluster_analysis.next_site_cluster_analysisc             C   sB   |d kr| j }|d k	st‚x"| j ¡ |kr,P |  ¡ d krP qW | S )N)r,  r7   r>  r   rB  )r   rþ   r   r   r   rE  z  s      z/peak_cluster_analysis.all_site_cluster_analysisc             C   s’  xŠ| j }|| j ¡ krd S |  j d7  _ | jd k	rJ| j| r@qd| j|< | j |¡}| j ¡ | }| j ¡ | }| j ¡ | }| j 	|¡}| j
rœ| ¡ sœq| ¡ }t |¡}d}| j ¡ dkrÖdd l}	|	jdtd x.| jD ]$}
t ||
¡ ¡ }|| jk rÞd}P qÞW |dkr| jd k	rT| j ¡ dks@|| jd | j k rT|  ||||¡\}}| j |¡ | j |¡ | j |¡ t|||||dS qW d S )	Nr   Téú   r   zHThis function should not be used for processing a large number of peaks.)ÚmessageÚcategoryF)r/  r0  r1  r2  r3  )r=  rH  r   r6  rW  rX  rK  rL  r9  rT  r'  Úis_point_group_1rU  r
   Úsym_equiv_sitesr>  ÚwarningsÚwarnÚRuntimeWarningÚmin_sym_equiv_distance_infoÚdistr+  r(  r?  r)  Ú_accumulate_significantr<  r   r.  )r   r/  r0  r1  r2  r3  rT  Úequiv_sitesÚkeepr^  rÊ   rb  r   r   r   rA  ƒ  s\     

 



z4peak_cluster_analysis.next_with_effective_resolutionc             C   s,  |   ¡  ¡ }|j}|j}t ||ƒ¡| }|}	|| j }
xât| j| j	 
¡ ƒD ]Ì}| j| r\qL| j	 ¡ | }||
k rtP | j	 ¡ | }| j |¡}| jr¨| ¡ s¨d| j|< qL| ¡ }t ||¡}| ¡ }|| jk rLd| j|< | t |g¡¡d }| ¡ | }|t ||ƒ¡| 7 }|	|7 }	qLW |||	 ƒ|fS )NTr   )rø   r-   r{   rž   r   r}   r*  r   r=  rH  r   r6  rL  rK  r9  rT  r'  r\  rU  r
   ra  rb  r+  Úapplyr   r~   Ú
special_op)r   r2  r3  rT  rd  r-   ÚorthÚfracZsum_w_sitesÚsum_wZheight_cutoffr   Zother_heightZ
other_siteZother_site_symmetryZ	dist_inforb  Z
close_siter   r   r   rc  ²  s:    

  


z-peak_cluster_analysis._accumulate_significantc             C   sB   |d kr| j }|d k	st‚x"| j ¡ |kr,P |  ¡ d krP qW | S )N)r,  r7   r>  r   rA  )r   rþ   r   r   r   rD  Ï  s      z3peak_cluster_analysis.all_with_effective_resolution)FNNNNNr   )N)r   )N)N)r!   r"   r#   rZ   rC  rF  r?   rG  rÏ   rø   rù   rú   rû   rü   rý   rþ   r:  rI  rJ  rK  rL  rM  rP  rQ  rB  rE  rA  rc  rD  r   r   r   r   r  ê  s@         
 


	/r  c       %      C   sˆ  |   |¡}| ¡ }| ¡ }| ¡ }	ddlm}
 ddlm}m} |  	¡ }dddg}dddg}dddg}dddg}xòt
dƒD ]æ}|| |	|  }|| }||| |	|  | ƒ}||| |	|  | ƒ}|| d }|
j|dd||< || |	| k r6|| | d }|| ||< || | ||< || |	|  ||< qx|	| ||< d||< || ||< d||< qxW |  |¡}|| }dd	lm} |jtjt|ƒ|dd …  d
d|d}|j|d |j|d ¡ }t| ¡ | ¡ |d}ddlm} |j||d} |  ¡  |  ¡ }!t| ¡ ||||d}"t||t  |¡t  |¡ t  d¡ d}#|# !¡ |! !¡ ksXt"‚t#j$|! %|"¡|# %|"¡d}$|$ &¡ s€d S |$ '¡ S )Nr   )r   )ÚifloorÚiceilr2   r   r   )Úmin_gridrà   r   )ÚxrayÚP1)r-   Úspace_group_symbol)r(   r¸   )rm   )rU   )r-   r.   r/   )r%   )r0   r1   )r-   rš   r›   rm   rœ   )r   r   r   )rÖ   r×   rØ   )ÚxÚy)(rž   rE   rD   rd   Úscitbxr   Úlibtbx.math_utilsrk  rl  ry   r   Zadjust_griddingr{   r6   rn  Ú	structurer	   rî   r|   Zset_sites_cartÚstructure_factorsÚf_calcr0   r-   r.   r%   r@   rÙ   rB   rŸ   r  r   r}   r?   r7   r   Úlinear_correlationr    Úis_well_definedÚcoefficient)%Zlarge_unit_cellZlarge_d_minZlarge_density_maprm   rœ   Zwork_scatterersZsites_frac_largeZlarge_frac_minZlarge_frac_maxZlarge_n_realr   rk  rl  Z	large_ucpZsmall_n_realZsmall_origin_in_large_gridZ	small_abcZsites_frac_shiftr   Ú	grid_stepÚbufferZgrid_minZgrid_maxrm  Z	shift_minZsites_cart_shiftZsites_cart_smallrn  Zsmall_xray_structureZsmall_f_calcZsmall_griddingr%   Zsmall_fft_mapZ	small_maprW  Zsmall_copy_from_large_mapÚcorrr   r   r   Úregion_density_correlationØ  s‚    





"
r~  é'  c       	      C   sš   |r$t | |d ¡ } t ||d ¡ }|d k	rz| | } || }| dk }|dk }|  |d¡} | |d¡}dd„ }|| ||dS tj|  ¡ | ¡ |d ¡ S d S )N)r'   rŒ   r   c             S   sH   | dk}|dk}||B }|  ¡ }|  |¡}| |¡}tj|||d ¡ S )Nr   )rq  rr  Úsubtract_mean)Ú
iselectionr    r   rx  rz  )rq  rr  ÚcenteredÚs1Ús2rÊ   Zx_Zy_r   r   r   r}  /  s    

zccv.<locals>.corr)rq  rr  r‚  )rq  rr  r€  )r   r3   r:   r   rx  rÀ   rz  )	rf   rg   Zmodifiedr‚  r5   rŒ   rƒ  r„  r}  r   r   r   Úccv$  s    	r…  c               @   s    e Zd Zd	dd„Zd
dd„ZdS )Úspherical_variance_around_pointé(   TNc          
   C   s’  || _ || _|dkst‚g }|\}	}
}xÀtd|d ƒD ]®}dd|d  t|d ƒ  }t |¡}|dksp||krvd}n(|dt |d||   ¡  dtj  }| 	|	t 
|¡t 
|¡  |
t |¡ |t |¡t 
|¡  f¡ |}q6W t ¡ }x,|D ]$}|j|d}| |¡}| 	|¡ qöW t |¡| _t |¡| _t |¡| _| ¡ | _|d k	rŽt|dƒ}x$t|ƒD ]\}}| d| ¡ qjW | ¡  d S )	Nr   r   r*   r   gÍÌÌÌÌÌ@)Ú	site_cartÚwz=HETATM    1  O   HOH A   1     %7.3f %7.3f %7.3f  1.00 20.00
)rˆ  Úradiusr7   r   Úfloatr<   ÚacosÚsqrtr=   r   ÚsinÚcosr   r   rž   Útricubic_interpolationrE   rD   r¼   Ú standard_deviation_of_the_samplerª   ÚopenrÁ   ÚwriteÚclose)r   Úreal_mapr-   rˆ  rŠ  Ún_pointsZspline_interpolationZwrite_sphere_points_to_pdb_fileZsphere_pointsrq  rr  Úzr  ÚhÚthetaÚphiZold_phirÇ   ÚpointÚ	site_fracZvalue_at_pointrO   r   r   r   r   rZ   >  s@    

(




z(spherical_variance_around_point.__init__r   c             C   sb   |d krt j}td|| jd | jd | jd | jf |d td|| j| j| j| jf |d d S )Nz4%sMap values around point [%g, %g, %g], radius = %g:r   r   r   )r[   z6%s  min = %.2f  max = %.2f  mean = %.2f  stddev = %.2f)	rº   r»   r^   rˆ  rŠ  rE   rD   r¼   rª   )r   Úoutr½   r   r   r   rb   k  s     z$spherical_variance_around_point.show)r‡  TN)Nr   )r!   r"   r#   rZ   rb   r   r   r   r   r†  =  s     
&r†  c                sT   t ˆˆ|ˆ |¡d‰t ˆ¡‰ ‡‡fdd„}‡fdd„}‡ fdd„}t|||dS )	N)r3   r-   rŠ  rœ  c                  s   t ˆ ˆddS )Ngš™™™™™¹?)r3   r-   r5   )Úcenter_of_massr   )r•  r-   r   r   Úcenter_of_mass_~  s    z2principal_axes_of_inertia.<locals>.center_of_mass_c                  s   ˆ S )Nr   r   )Ústr   r   Úinertia_tensor  s    z1principal_axes_of_inertia.<locals>.inertia_tensorc                  s   ˆ S )Nr   r   )Úesr   r   Úeigensystemƒ  s    z.principal_axes_of_inertia.<locals>.eigensystem)rž  r¡  r£  )Zsphericity_tensorrž   r   r£  r   )r•  rˆ  r-   rŠ  rŸ  r¡  r£  r   )r¢  r•  r   r-   r   Úprincipal_axes_of_inertias  s    
r¤  c               @   s   e Zd Zddd„ZdS )Úlocal_scaleNc             C   sN  ||g  d ¡dkst‚|d k	rFdd l}|jj||d}| ¡  | ¡ }d | _d | _t	| 
¡ dd}	t t |	j
¡¡| _xzt|	j|	jƒD ]h\}
}t||
|ƒ}| t | ¡ ¡¡ | ¡  ¡  ¡ \}}}||k rÜt|dd ¡ }t|| j|
|d q†W | j ¡ }| j| | _|d k	rJ|}|d k	r4| ¡ }|j|d	}|j| jd
ddd| _d S )Nr   r   )r0   r1   g¸…ëQ¸ž?)r’   r!  iè  )r'   rŒ   )Zmap_data_fromZmap_data_toÚstartÚend)rU   TF)r'   Ú	use_scaleÚanomalous_flagÚuse_sg)rS   r7   Úcctbx.millerr%   r@   rÙ   rB   Z
map_resultZmap_coefficientsr  r’   r   r   r  r   r  r  r  Úreshaper?   rÀ   Úmin_max_meanÚas_tupler   r3   Zset_boxÚsample_standard_deviationrU   Úcomplete_setÚstructure_factors_from_map)r   r0   r(   rJ   r3   Úmiller_arrayrU   r6   r@   rƒ   rÊ   ÚeÚboxÚmiÚmaÚmeÚsdr°  r   r   r   rZ   ‹  sJ    	


zlocal_scale.__init__)NNNN)r!   r"   r#   rZ   r   r   r   r   r¥  Š  s      r¥  é   c             C   s‚   t  ¡ }xTtdd|ƒD ]D}x>tdd|ƒD ].}tjj||||d\}	}
}| |	|
|g¡ q(W qW t| |||d}t| 	¡ | 
¡ dS )Nr   ih  )r¨   Ús_degÚt_degÚcenter)r3   Úcenter_cartÚpoints_on_sphere_cartr-   )Úrhor]   )r   r~   r   rs  r<   Úpoint_on_spherer   Zsphericity2r   Zrho_min_max_meanZccs_min_max_mean)r3   r-   r½  rŠ  Ús_angle_sampling_stepÚt_angle_sampling_stepr¾  rÊ   ÚtÚxcÚycÚzcrY   r   r   r   Úsphericity_by_heuristics¼  s    rÇ  ç{®Gáz„?c          
   C   sæ   t  ¡ }t  ¡ }t|d ƒd }t|d ƒ}x°td||ƒD ] }	|	d }	| |	¡ t  ¡ }
xptdd|ƒD ]`}xZtdd|ƒD ]J}tjj|	|||d\}}}| |||g¡\}}}|
 |  	|||g¡¡ qxW qfW | t  
|
¡¡ q:W ||fS )Nr¿   r   r   g      Y@ih  )r¨   rº  r»  r¼  )r   r   rÃ   r   r   rs  r<   rÀ  rž   Úeight_point_interpolationr¼   )r3   r-   r½  rŠ  rÞ   rÁ  rÂ  Zrho_1drb  r¨   r¿  rÊ   rÃ  rÄ  rÅ  rÆ  ÚxfZyfÚzfr   r   r   Úmap_peak_3d_as_2dÐ  s     
rÌ  c               @   s   e Zd Zddd„Zdd„ ZdS )	Ú+positivity_constrained_density_modificationr¿   ç      Ð?Nc          	   C   s   || _ || _d | _|| _ddlm} | jd kr:| j  ¡ | _|d krR| j j| jd}| jd krx| j j||d d d ddd| _| j  ¡ | _xvt	|ƒD ]j}	|j
| j| j|d}
|d k	r¶|
 ¡  |
 ¡ | _t| jdƒ |j| jdddd	| _| j j| jddd
| _qŽW d S )Nr   )r%   )rU   r   T)rU   r‹   r{  rŠ   rß   rà   rá   )r0   r1   Úf_000F)r'   r¨  r©  rª  )ré   ÚscaleÚreplace_phases)rO   rU   r'   r0   r6   r%   r°  rF   Úf_modr   r@   rA   rB   Zconvert_to_non_negativer±  Úcomplete_with)r   rO   rÏ  Zn_cyclesr‹   rU   r0   r°  r%   r   r@   r   r   r   rZ   ë  sF    
 

 

z4positivity_constrained_density_modification.__init__c             C   sR   ddl m} | j| j }}| |¡\}}t|ƒ ¡ }t|ƒ ¡ }|||ƒsNt‚d S )Nr   )r   )Úlibtbx.test_utilsr   rO   rÒ  Úcommon_setsrC   r,   r7   )r   r   rq  rr  r   r   r   Úassert_equal  s    z8positivity_constrained_density_modification.assert_equal)r¿   rÎ  NNN)r!   r"   r#   rZ   rÖ  r   r   r   r   rÍ  ê  s    
$rÍ  c             C   s*   t  dd„ |  ¡ D ƒg¡}t | |¡¡S )Nc             S   s   g | ]}|d  d ‘qS )r   r   r   )Ú.0r   r   r   r   ú
<listcomp>  s    z d_min_corner.<locals>.<listcomp>)r   Úmiller_indexr?   r   Úd_star_sq_as_dÚmax_d_star_sq)r3   r-   Ú	max_indexr   r   r   Úd_min_corner  s    rÝ  ç      à?c             C   sX   |  ¡ d d… \}}}|  ¡ \}}}|| | || | || |   }	}
}t|	|
|ƒS )Nr2   )ry   r?   rD   )r3   r-   r‹   r‚   rƒ   r„   ÚnxÚnyZnzÚd1Úd2Zd3r   r   r   Úd_min_from_map  s    

rã  c             C   sH   t |  ¡ tjƒst‚t| ¡ | ¡ |d}| j|t	d}| 
¡  | ¡ S )N)r-   r.   r/   )r0   rŠ   )Ú
isinstancer,   r   Úcomplex_doubler7   r0   r-   r.   r@   rŽ   rA   rB   )Ú
map_coeffsr(   r’   rL   r@   r   r   r   Úmap_coefficients_to_map%  s    rç  c       	   	   C   sØ   dd l }t dd„ |  ¡ D ƒ¡}t| t | ¡ ¡ |  	¡ ¡ƒ}| 
t | ¡ ¡ | ¡ ¡¡ | |¡}tj| ¡ | ¡  ¡ d||ddd}| ¡ d | ¡ d  | ¡ d  }|jj|d| ¡ d	j| ¡ | d
}|S )Nr   c             S   s   g | ]}|‘qS r   r   )r×  r   r   r   r   rØ  3  s    z+map_to_map_coefficients.<locals>.<listcomp>FT)r-   ró   r©  rU   Úcomplex_mapÚconjugate_flagZ$discard_indices_affected_by_aliasingr   r   )r(   r©  rW   )r,   )r«  r   Úreal_to_complex_3dr?   r  r   r  Úm_realÚ	set_focusrd   r¬  r’   Úforwardrv  rÛ   r-   rv   rw   r%   ÚsetÚmiller_indicesr>   r,   )	ÚmÚcsrU   r6   ÚfftZmap_boxZbox_structure_factorsrï   ræ  r   r   r   Úmap_to_map_coefficients1  s*    

$ró  c             C   sà   ddl m}m} d}t |||dddfd¡}t |¡}|j| dt |¡d}	t	 
|	g¡}
| ||
¡}|j|d t| ¡ | ¡ d	d
}|j|dd ¡ }|j||| ¡ d}| ¡  | ¡ }dd„ }|||d}|dk	sÜt‚|S )zN
  Estimate atom radius as half-width of the central peak of Fourier image.
  r   )rn  r%   g      D@éZ   zP 1)r   r   r   )Úscattering_typer2  Úu)Útablegš™™™™™¹?)r-   r.   rÞ   Údirect)rU   Ú	algorithm)r0   r1   rÏ  c             S   sŠ   d}d}d }d }xt||kr„|   || ddg¡}|d k	rF||krF|| S |d krR|}|| dkrf|| S |dk rv|| S ||7 }|}qW d S )Ng        g{®Gáz„?r   g      Y@)rÉ  )r3   rò   rq  rÞ   Zmv_maxZmv_prevÚmvr   r   r   Úsearch_curveb  s"    
    z7atom_radius_as_central_peak_width.<locals>.search_curve)r3   rò   N)r6   rn  r%   r	   rî   rø   Ú	scattererr   Úb_as_ur   Úxray_scattererru  Úscattering_type_registryr0   r-   r.   rv  rw  r@   rÏ  rA   rB   r7   )ÚelementÚb_isorU   Úscattering_tablern  r%   rò   rñ  Úspr¥   r¸   ÚxrsrL   Úfcr@   r3   rû  rŠ  r   r   r   Ú!atom_radius_as_central_peak_widthH  s4    
r  c               @   s„   e Zd ZdZd$dd„Zdd„ Zdd	„ Zd
d„ Zd%dd„Zdd„ Z	dd„ Z
d&dd„Zd'dd„Zdd„ Zdd„ Zd(dd „Zd)d"d#„ZdS )*Úatom_curveszz
Class-toolkit to compute various 1-atom 1D curves: exact electron density,
Fourier image of specified resolution, etc.
  Úwk1995Nc             C   sH   t | tƒ ƒ | j| jg d ¡dks&t‚| jddd ¡ | _| jj	| _
d S )Nr   r   )r´  rƒ   )r   rQ   r  Úscattering_dictionaryrS   r7   Úget_xray_structurerÿ  ÚscrZ unique_form_factors_at_d_star_sqÚuff)r   rõ  r  r	  r   r   r   rZ   z  s    zatom_curves.__init__c       	      C   sŠ   t  |||dddfd¡}t  |¡}ddlm} |j| jdt |¡d}t	 
|g¡}| ||¡}| jd k	rx|j| jd n|j| jd |S )	Nrô  zP 1r   )rn  )r   r   r   )rõ  r2  rö  )r÷  )Úcustom_dict)r	   rî   rø   r6   rn  rü  rõ  r   rý  r   rþ  ru  r  rÿ  r	  )	r   r´  rƒ   rñ  r  rn  r¥   r¸   r  r   r   r   r
    s    

zatom_curves.get_xray_structurec             C   s   | j  | j¡ ||¡S )N)r  Úgaussianrõ  Úelectron_density)r   r¨   r  r   r   r   Úexact_density_at_r‘  s    zatom_curves.exact_density_at_rc             C   s   | j  | j¡j||||dS )N)r¨   rÃ  Út0r  )r  r  rõ  Úgradient)r   r¨   rÃ  r  r  r   r   r   Úexact_gradient_at_r”  s    zatom_curves.exact_gradient_at_rç      @çü©ñÒMbP?c             C   s`   d}t  ¡ }t  ¡ }| j | j¡}x0||k rR| | ||¡¡ | |¡ ||7 }q$W t||dS )Ng        )r¶   Údensity)r   r   r  r  rõ  r   r  r   )r   r  Ú
radius_maxÚradius_stepr¨   r  r¶   Úedr   r   r   Úexact_density˜  s    

zatom_curves.exact_densityc             C   s&   d| }|   |¡d t | | ¡ S )Né   r   )r  r<   r$   )r   rK   r  Zdssr   r   r   Úform_factor£  s    zatom_curves.form_factorc                s   ‡ ‡‡fdd„}|S )Nc                sj   | d d }t ˆƒdkrHdˆ |  ˆ |ˆ ¡ t dtj ˆ |  ¡ S dtj | d  ˆ |ˆ ¡ S d S )Nr   g•Ö&è.>r  )rC   r  r<   rŽ  r=   )rÊ   rK   )r  r¨   r   r   r   Úcompute¨  s    0z&atom_curves.integrand.<locals>.computer   )r   r¨   r  r  r   )r  r¨   r   r   Ú	integrand§  s    zatom_curves.integrandr   r   c          
   C   s^  d}ddl m} | j|d||d}	|j|	j|	j|||d\}
}}}}}t ¡ }g g g   }}}xTt|
||ƒD ]D\}}}t	|ƒdk slt	|ƒdk r’qlql| 
|¡ | 
|¡ | 
|¡ qlW |||  }
}}x€|	jD ]v}d}d}xZt|
||ƒD ]J\}}}t	|ƒdk r||j|||dd7 }qæ|||j|||dd 7 }qæW | 
|| ¡ qÌW t|	j|	j||
||dS )	Nr   )Úbcr)rU   r  r  r  )Zdensrb  ÚmxpÚepscÚkpresgíµ ÷Æ°>)ÚBÚCr¨   r  )r#  ÚRr¨   r  )r¶   Úimage_valuesÚbcr_approx_valuesr#  r$  r%  )Zcctbx.maptbx.bcrr  ÚimageZget_BCRr&  r¶   r   r   r   rC   r   ÚgaussÚchir   )r   rU   r  r  r   r!  r"  r  r  ZimZbpeakZcpeakZrpeakr   r'  Zbpeak_Zcpeak_Zrpeak_ZbiZciÚrir¨   r×   Úsecondr#  r$  r%  r   r   r   Ú
bcr_approx°  s8      

zatom_curves.bcr_approxéÐ  c             C   sŠ  |}|dkst ‚|d krd}	nd| }	|dks2t ‚d| }
t ¡ }t ¡ }xD||k rŽtjj|  ||¡|	|
|d}| |¡ | |¡ ||7 }qLW d }d }| ¡ }t ¡ }xÈt	|ƒD ]¼}|dkrð||d k rð||d  ||d   d||   }n<|dkrd||d   d||   }n||d  |d  }|d kr\|dkr\||d  ||  d }|}| ||d  ¡ q²W t
|||||d |dS )	Ng        r   g      ð?)rO   r‚   rƒ   rï   r   r   g       @)r¶   r&  Úfirst_inflection_pointÚi_first_inflection_pointrŠ  Úsecond_derivatives)r7   r   r   rs  r<   Úsimpsonr  r   r   r   r   )r   rU   r  rT   Z
radius_minr  r  Zn_integration_stepsr¨   Ús_minÚs_maxr&  r¶   rÊ   r/  r0  r   r1  r   Zdxxr   r   r   r(  Ö  sH     


&
zatom_curves.imagec             C   sà   t  ¡ }t  ¡ }xB|D ]:}| | j| |¡d |d¡ | dtj |d  ¡ qW t  ¡ }	t  ¡ }
d}xb||k rÊd}x0t|||ƒD ] \}}}||t || ¡ 7 }q„W |
 |¡ |	 |d ¡ ||7 }qjW t	|
|	| 
¡  dS )Nr  )rK   r  r   g        r   )r¶   r&  )r   r   r   r  Ú	d_star_sqr<   r=   r   r  r   Úvolume)r   rï  r  Úucr  r  Úp2Útmprµ  rú  Úradr—  rX   Zp2iZtmpir   r   r   Úimage_from_miller_indices  s     


z%atom_curves.image_from_miller_indicesc             C   s¸   ddl m} | j||d}|j|dd ¡ }	t|||td}
|j|
|	d}| ¡  | 	¡ }t
 ¡ }t
 ¡ }d}x<||k rª| || ddg¡}| |¡ | |¡ ||7 }qpW t||dS )	Nr   )r%   )r´  rƒ   rø  )r³   rù  )r-   r.   rÞ   rŠ   )r0   r1   )r¶   r&  )r6   r%   r
  Ú!structure_factors_from_scatterersrw  r0   rŽ   r@   rA   rB   r   r   rÉ  r   r   )r   r´  rƒ   rÞ   r-   r.   r²  r%   r  r  rL   r@   r3   rú  r¶   r¨   Zmv_r   r   r   Úimage_from_3d  s.    


zatom_curves.image_from_3dc             C   s8   dt j ||  }||d  t  t j | |d  ¡ S )Nr  g      ø?r   )r<   r=   r$   )r   r¨   ÚA0ÚB0rƒ   Zcmnr   r   r   Úone_gaussian_exact1  s    zatom_curves.one_gaussian_exactTc             C   s  | j |dddd}|r|j}nBd }x<t|j ¡ ƒD ]*}|j| dkr2|j|d  }|d }P q2W |d k	slt‚tjj	|jd |… |jd |… d}dtj
d  |j }	|j|jtj
 d	  }
t ¡ }x*|jD ] }| j||
|	|d
}| |¡ qÊW t||||j ¡ dS )Nr   r   g{®Gáz„?)rU   r  r  r  r   )rq  rr  r  r   g      ø?)r¨   r>  r?  rƒ   )Zimage_b0Zimage_approx_at_bÚi_cutr–  )r(  r0  r   r¶   r   r&  r7   rs  r<   Úgaussian_fit_1d_analyticalr=   rƒ   r‚   r   r   r@  r   r   )r   rU   rƒ   Zuse_inflection_pointZib0rA  r   Zrad_cutr¨   r?  r>  Zimage_approx_valuesr:  r£   r   r   r   Úone_gaussian_approximation5  s*    z&atom_curves.one_gaussian_approximation)r  N)r  r  )r   r  r   )Nr   r  r  r.  )r   )T)r!   r"   r#   rÎ   rZ   r
  r  r  r  r  r  r-  r(  r;  r=  r@  rC  r   r   r   r   r  t  s&    


%    
'
r  c       #      C   sè  ddl m} |j| ¡ | d}|j|d ¡ }|j|dddj}td|ƒ t||ƒ |j	dd	}|j|d ¡ }| 
¡  ¡ }d
}	d }
| ¡  ¡ }xXdd„ tddƒD ƒD ]@}||k }| |d¡}|j|d}|j|d}||	kr¦|}	|}
q¦W td|
ƒ |j|d ¡ }|j|
d}t| ¡  ¡ | ¡  ¡ |d}|j|d ¡ }d
}	d }dt | 
¡  ¡ ¡ d }| ¡ }x~tdddƒD ]n}|j	|d	}t | | ¡}|j|| d}|j|d ¡ }tj| ¡ | ¡ d ¡ }||	krv|}	|}qvW td|ƒ |j|d}dt | 
¡  ¡ ¡ d }d| }t | | ¡}|j| ¡ | d}|jdd}| ¡ }|j d| d |j|d}| !¡  | ¡ }dd l"} | j#j$|| %¡ dd }!||!j& }dd!l'm(}" |"j)d"| | ¡ | *¡ |t +d#g¡d$ ||fS )%Nr   )r%   )r(   r'   )r³   r¿   g        )ré   Ú	bin_widthÚ
fsc_cutoffzd_fsc_model:)rÉ   iüÿÿc             S   s   g | ]}|d  ‘qS )g      $@r   )r×  r   r   r   r   rØ  d  s    zsharpen2.<locals>.<listcomp>r‘   )r,   )ré   zBest d:)rU   )r-   r.   rU   )r0   g      ð?g      @r   iô  )rq  rr  zBest B:r*   ÚF)Úcolumn_root_labelz%s.mtz)Ú	file_nameg       @)r³   r’   rH   )Úmrcfilez%s.ccp4r   )rH  r-   rv   r3   Úlabels),r6   r%   r8   r(   r<  rw  Úd_min_from_fscrU   r^   Ú	set_b_isor9   r,   rF   r   r:   Úcustomized_copyÚmap_correlationrv  Úresolution_filterr0   r-   r.   r@   rB   r   r;   r$   rx  rÀ   rz  Úas_mtz_datasetÚ
mtz_objectr“  rÙ   Zmmtbx.masksÚmasksZsmooth_maskr?   Zmask_smoothÚiotbxrI  Úwrite_ccp4_maprv   Ú
std_string)#r'   r³   Ú
resolutionZfile_name_prefixr%   Úfor  Zd_fsc_modelr9   ra   Zd_bestr,   Údr§   Údata_Zfc_Zcc_Zfc1Úfc2rL   Zmap2rƒ   rK   Zb_r¥   Zmap1Zfo_sharpZB_sharpÚmtz_datasetrQ  r@   r3   ÚmmtbxZmask_objectrI  r   r   r   Úsharpen2N  sŽ    








r]  g      @Úfsci8ÿÿÿiô  gçû©ñÒMÂ?Fc       -         sL  |dkst ‚ddlm} ddlm} dd l}ddlm} |  ¡  ¡  	¡ }| |d  } | |  
¡  } |j| ¡ | ¡ |  ¡  ¡ d}| ¡ }| ¡ }|j|d}|jjd	|d
d | ¡  ¡ }|dkrÐ| ¡  ¡ }nd }t ¡ }t ¡ }|j|d}ddlm} || ||  ¡ |
d}xÊ|D ]À}| |¡ ¡ }| |¡}| |¡} || |d}|jdd | ¡ j|  ¡ dd | ¡ j!|d | ¡  "¡  |j#|  ¡  $¡  %¡ | ¡  &¡ d}!|dkrÖ|!j'|d}!|  ¡  $¡ j(dd |!j)|  ¡  $¡ d *¡ }"d}#d}$d}%|dkr|"j+|!d|	dj,}$nL|dkr||" -¡  .¡ }&d
t /|&¡ d }'|j0|! .¡ |" .¡ |&|'t d d!„ t1d"dƒD ƒ¡dd#\}$}%nê|dkrf|" -¡  .¡ }&d
t /|&¡ d }'d }(d })d }*d$‰ t2|ˆ  ƒ}+t3|+d% t2|ˆ  ƒƒ},x‚‡ fd&d!„t1|+|,ƒD ƒD ]f}#|j0|" .¡ |! .¡ |&|'t d'd!„ t1t2|d( ƒdƒD ƒ¡|#d#\}$}%|)d ksH|%|)krð|%})|$}(|#}*qðW |)}%|(}$|*}#|r‚t4d)|$|#|%f |d* | 5|$¡ | 5|#¡ | 6|  ¡  $¡ ¡ |dkrÌ| 7||#¡}| 7||$¡}n| 7||$¡}qW t4t 8|¡t 3|¡t 9|¡|d* t4t 8|¡t 3|¡t 9|¡|d* | ¡  :|¡ |dkrH| ¡  ;|¡ |S )+N)r^  ÚrsccÚrscc_d_min_br   )rG   )r%   )Úmap_model_managerr   )r-   r.   r/   )r(   Zelectrong      ð?)r  r³   rU   r`  )Úresidues_per_chunk)Úmap_manager)r3   Úunit_cell_crystal_symmetryÚunit_cell_gridÚwrapping)Úmodelrc  r2   )Zbox_cushiong      @)rg  Zmask_atoms_atom_radius)Úsoft_mask_radius)r(   r'   )rU   g        )rÉ   )r³   r^  r¿   )ré   rD  rE  r_  g      @c             S   s   g | ]}|d  ‘qS )g      $@r   )r×  r   r   r   r   rØ    s    zloc_res.<locals>.<listcomp>é   )Zf_1Zf_2r9   rK   r\   r  r¹  r   c                s   g | ]}|ˆ  ‘qS r   r   )r×  r   )rÐ  r   r   rØ    s    c             S   s   g | ]}|d  ‘qS )g      $@r   )r×  r   r   r   r   rØ    s    r‘   zCHUNK d_min %s b %s cc %s)r[   )<r7   r6   rG   r%   Zmmtbx.utilsZiotbx.map_model_managerra  rÀ   r­  r®  r¯  r0   r-   r.   r‡   r?   Zget_hierarchyrF   Úextract_xray_structureÚutilsZsetup_scattering_dictionariesÚatomsÚ	extract_bÚextract_occr   r   Úchunk_selectionsÚiotbx.map_managerrc  r    Z*box_all_maps_around_model_and_shift_originZcreate_mask_around_atomsrg  Z	soft_maskZ
apply_maskr8   r
  r(   r3   rO  rL  r<  rw  rK  rU   r9   r,   r;   Zcc_complex_complexr   rÃ   rD   r^   r   Úadopt_xray_structurer:   rE   r¼   Úset_bÚset_occ)-r'   rg  r(   Ú
chunk_sizerh  rI   Z
hard_d_minZb_range_lowZb_range_highrE  rf  Úverboser_   rG   r%   r\  ra  ÚmmmrL   Úpdb_hierarchyZph_dcr  ÚbsÚoccsZ	results_bÚresultsro  rc  ÚmmZ	chunk_selZph_selZxrs_selZ	model_selrW  r  r  rU   ra   r9   rK   Z
d_min_bestZcc_bestZb_bestZ	low_valueZ
high_valuer   )rÐ  r   Úloc_res¦  sØ    





 



""
r|  çš™™™™™¹?c             C   s0   t |  ¡ ƒdkst‚t| ƒ}||kr(dS dS dS )aE   Determine if this map is bounded on all sides by values that are
       zero or a constant, within relative tolerance of relative_sd_tol to
       the SD of the map as a whole

       Returns True if map boundary values are nearly constant,
         and False if they vary

       Requires that map is at origin (0,0,0)
    )r   r   r   FTN)r|   re   r7   Úrelative_sd_on_edges)r3   Zrelative_sd_tolZrelative_sdr   r   r   Úis_bounded_by_constant0  s
    r  c          	   C   sê  t |  ¡ ƒdkst‚|  ¡  ¡ }t|  ¡ ƒ}t ¡ }d}ddl	m
} x~d|d d fD ]j}|| t |ddfƒt ||d |d fƒƒ}	| |	 ¡ ¡ t||	 ¡  ¡ td|ƒ ƒ}|dk	rV||krV|S qVW x~d|d d fD ]j}
|| t d|
dfƒt |d |
|d fƒƒ}	| |	 ¡ ¡ t||	 ¡  ¡ td|ƒ ƒ}|dk	rÖ||krÖ|S qÖW x„d|d d fD ]p}|| t dd|fƒt |d |d |fƒƒ}	| |	 ¡ ¡ t||	 ¡  ¡ td|ƒ ƒ}|dk	rV||krV|S qVW |rÔ|S | ¡ td|ƒ S dS )zw
     Determine relative SD of values on edges to the map as a whole

     Requires that map is at origin (0,0,0)

    )r   r   r   r   )r  r   r   g»½×Ùß|Û=N)r|   re   r7   rÀ   r‘  Úlistr?   r   r   Úcctbx.maptbxr  ÚextendrD   )r3   Zskip_if_greater_thanÚuse_maximumZ
sd_overallr?   Zboundary_datar~  r  r   Únew_map_datar  r  r   r   r   r~  G  sV    



r~  c             C   sÖ   |   ¡  ¡ dk}|  |¡}tdd|  ƒ}|j|d| ¡ d | ¡  ¡ }t| ¡  	¡ ƒ}| 
¡  | ¡ }t|| ƒ}d}	xV|D ]N}
| ¡  |
¡}| |¡}| ¡ j}| ¡ }|	|7 }	|	|kr€|	|d k r€|S q€W d S )Ng»½×Ùß|Û=g      à?r‘   g     ˆÃ@)rŒ   rT   rU   r   r   )Ú
amplitudesr,   r    rÃ   Úsetup_binnerrU   r9   r€  ÚbinnerÚ
range_usedÚreverser   Ú	selectionr­  rD   )r¶  Úminimum_fraction_data_pointsr§   Zma_with_datarŒ   ZdsdZ	ibin_listZ
total_dataZminimum_data_pointsZtotal_foundrÈ   Zsel2ÚddrT   rï   r   r   r   Ú-get_resolution_where_significant_data_present„  s(    



r  c             C   s
  ddl m} tt|  ¡ ƒdddg ƒ}| |d¡}td|  ¡  ¡ ƒ}|  ¡  	¡ j
}| | | } ddl m} |j|| dd}t|||  ¡ d	} |j|| dd}t||d
}	|j|	d}
t|
||  ¡ d	}| | }| ¡  ¡ }t|dd}tdtd|d d ƒƒ}d| }|S )a  
      Evaluate consistency of high-pass filtered difference map analysis
      with that expected for a map that is periodic.

      The difference map is difference between the map and the map lacking high-
      resolution terms.  This difference map shows only high-frequency
      information

      A map that is periodic should give a difference map that is more or less
      uniform everywhere.  A non-periodic map should have a discontinuity at the
      borders and have high variation in the difference map at the edges.
    r   )r	   g     €V@r   g#B’¡œÇ;)r%   N)r(   r'   rU   )ræ  r(   r’   )r‹  )rU   T)rƒ  )r6   r	   r|   r€  r?   rî   rD   rÀ   r‘  r­  r¼   r%   r8   rç  r  rO  r~  rE   )r3   r‹  r	   Zdummy_uc_parametersrñ  r¸  r¼   r%   r¶  Zd_min_valueZfiltered_maZfiltered_mapZdiff_mapZdiff_sdZdiff_relative_sd_on_edgesZdiff_score_towards_aperiodicÚdiff_score_towards_periodicr   r   r   Úget_diff_score_towards_periodicœ  sD    r  c          	   C   s  t |  ¡ ƒ}t ¡ }t ¡ }t ¡ }t ¡ }t ¡ }t ¡ }d}	ddlm}
 g }xªdd|d d fD ]”}||krz| |¡ |
| t|ddfƒt||d |d fƒƒ}|dkrÂ| ¡ }| 	| ¡ ¡ qd|dkrâ| ¡ }| 	| ¡ ¡ qd| ¡ }| 	| ¡ ¡ qdW t
|	t|||dƒ}	t|ƒdks"t‚g }x²dd|d d fD ]œ}||krR| |¡ |
| td|dfƒt|d ||d fƒƒ}|dkrœ| ¡ }| 	| ¡ ¡ n8|dkr¾| ¡ }| 	| ¡ ¡ n| ¡ }| 	| ¡ ¡ q:W t|ƒdksìt‚t
|	t|||dƒ}	g }x²dd|d d fD ]œ}||kr0| |¡ |
| tdd|fƒt|d |d |fƒƒ}|dkrz| ¡ }| 	| ¡ ¡ n8|dkrœ| ¡ }| 	| ¡ ¡ n| ¡ }| 	| ¡ ¡ qW t|ƒdksÊt‚t
|	t|||dƒ}	|rê|	}nt|||d}tdt
d|ƒƒ}|S )zú
      Measure of whether facing edges have correlated data with correlation
     similar to that found for adjacent planes and different than randomly
     chosen points

     If use_minimum is set, take minimum of values on all pairs of faces

    g      ð?r   )r  r   r   )Úboundary_zero_dataÚboundary_one_dataÚone_datar2   )r€  r?   r   r   r  r  r   r|   rÀ   r‚  rE   Úget_relative_ccr   r7   rD   )r3   Zuse_minimumr?   r’  Zmiddle_plus_one_dataZmiddle_datar  Zboundary_zero_one_datar‘  Zlowest_relative_ccr  Zunique_listr   r„  Zboundary_zero_data_localZone_data_localZboundary_one_data_localr  r  Úrelative_ccÚedge_score_towards_periodicr   r   r   Úget_edge_score_towards_periodicð  sš     


 




 



r–  c             C   s^   t  | |¡ ¡ }t  | |¡ ¡ }| t  t|ƒ¡¡}t  | |¡ ¡ }|| td|| ƒ }|S )Ng»½×Ùß|Û=)r   rx  rz  r    Úrandom_permutationr   rD   )r  r‘  r’  Zcc_boundary_zero_oneZcc_positive_controlZone_data_random_permZcc_negative_controlr”  r   r   r   r“  U  s    



r“  çš™™™™™É?ç      Ð?c             C   st   t |  ¡ ƒdkst‚t| |d}|d| kr0dS ||k r<dS t| ƒ}d||  }|d| kr`dS ||k rldS dS dS )a(  
       Determine if this map is periodic.  If values on opposite faces are
       about as similar as values on adjacent planes, it is probably periodic.

       Two tests are used: (1) correlation of facing edges of map and
        (2) test whether difference map between original and map without
        high resolution data shows most variation at edges (due to mismatch
        of edge data at facing edges of map).

       Map edge correlation score:
       Normally values on adjacent planes are very highly correlated (> 0.9)
       and random points in a map have very low correlation (< 0.1). This
       allows a test based on correlation of facing edges of a map and comparison
       to random pairs of points in map.

       Difference map score:
       If a map is boxed then if it is treated as a periodic map, there will
       be a discontinuity at the edges of the map.  This can be detected by
       calculating the Fourier transform of the high-resolution map coefficients
       for the map and detecting if this high-pass filtered map is dominated by
       features at the edge of the map.

       Returns True if periodic, False if not, and None if map gridding is
       too small (too few planes) or sampling is insufficiently fine to tell.

       Requires that map is at origin (0,0,0)
    )r   r   r   )r‹  r   TFg      à?N)r|   re   r7   r  r–  )r3   r‹  Zhigh_confidence_deltaZmedium_confidence_deltarŽ  r•  Zsum_score_towards_periodicr   r   r   Úis_periodico  s    !
rš  c             C   sþ   |dkst ‚| |¡}| |d |d ¡}||k s:t dƒ‚d}t ¡ }t ¡ }x¢|dkrð|d \}	}
}|d \}}}|	|||	   }|
|||
   }||||   }| |¡ | |||g¡}|dkrÒ|  |¡}n
|  |¡}| |¡ ||7 }qPW t||dS )zX
  Calculate interpolated map values along the line connecting two points in
  space.
  )Úeight_pointZtricubicr   r   z;step cannot be greater than the distance between two pointsgzo ð?r›  )rb  Úvals)	r7   rž   Údistancer   r   r   rÉ  r  r   )r3   Zpoints_cartrÞ   r-   ÚinterpolationZpoints_fracrb  Zalprœ  Úx1Úy1Úz1Úx2Úy2Úz2ÚxpZypZzpZpfrú  r   r   r   Ú+map_values_along_line_connecting_two_points®  s*    




r¦  )r$   T)rc   )NNNNNN)NNNN)r   r   r‘   T)r™   )r   )r   r   r   N)T)Nr  )r¹  r¹  )rÈ  r‘   r‘   )rÞ  )r}  )NN)r}  )N)T)NNN)r}  r˜  r™  )iÚ
__future__r   r   r   Úcctbx.sgtbxr6   Úboost_adaptbx.boost.pythonÚboostÚpythonÚbpÚ	six.movesr   r   Ú
import_extrV   r   r	   r
   Úcctbx.array_familyr   rs  r   Zscitbx.python_utilsr   r  r   Úlibtbx.utilsr   Úlibtbx.load_envr<   rº   ÚosÚscitbx.mathr   r   r   rÔ  r   r   ÚenvironÚgetr7  Úinject_intoZconnectivityr   rM   ÚobjectrN   rk   rR   r‰   rÃ   r   rÉ  Z(eight_point_interpolation_with_gradientsZ&quadratic_interpolation_with_gradientsr  Z%tricubic_interpolation_with_gradientsr   r˜   r©   r°   r¹   r®   Úsearch_symmetry_flagsrŽ   Ú	histogramrÏ   rÕ   ZeasyZstructure_factors_to_mapr±  rv  r0   rñ   r  r  r   r.  r  r~  r…  r†  r¤  r¥  rÇ  rÌ  rÍ  rÝ  rã  rç  ró  r  r  r]  r»   r|  r  r~  r  r  r–  r“  rš  r¦  r   r   r   r   Ú<module>   sâ   
 
*
     
5
! 



   

=
a+<GB	 oL
67 
  
.
	, [[
 
<

T
e  
  
<