B
    dޟ                @   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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mZ d dlm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&m'Z'm(Z(m)Z) d dlm*Z*m+Z+ d dl,Zd dl-m.Z. d dl/Z/d dl0Z0d dl1Z1d dl2Z2d dl3Z3d dl4m5Z5 d dlm6Z6 ej17 Z8ej9Z9dd Z:G dd dej;Z;e5dd d!d"d#gZ<G d$d% d%e=Z>d&d' Z?dLd*d+Z@dMd,d-ZAG d.d/ d/ejBZCdNd0d1ZDd2d3 ZEG d4d5 d5e=ZFd6d7 ZGG d8d9 d9eCZHG d:d; d;ZIG d<d= d=e=ZJG d>d? d?e=ZKG d@dA dAejLZMdOdBdCZNdPdDdEZOdQdFdGZPdRdHdIZQG dJdK dKe=ZRdS )S    )absolute_importdivisionprint_functionN)range)zipcctbx_miller_extZcctbx_asymmetric_map_ext)*)crystal)maptbx)sgtbx)lattice_symmetry)uctbx)r_free_utils)flex)fftpack)distributions)iround)complex_math)store)adopt_init_args)show_string)SorryKeepplural_s)
group_argsAuto)count)
namedtuple)matrixc             C   s&   t |tkst| d krd S | |S )N)typesliceAssertionError__getitem__)arrayslice_object r%   t/mnt/filia/a/genomebrowser/www/genomebrowser/fleming/tools/molprobity/modules/cctbx_project/cctbx/miller/__init__.py_slice_or_none+   s     r'   c            
   @   s   e Zd Zdd Zdd Zd#ddZd	d
 Zd$ddZdd Zdd Z	dd Z
dd Zd%ddZd&ddZd'ddZd(d!d"ZdS ))binnerc             C   sj   t j| ||  d| _| | _| | _|  dkrJ| | _	n
| | _	d | _
d | _d| _d S )NTr   F)extr(   __init__indicesZ__getstate_manages_dict__space_group_infoanomalous_flagsized_min_completeness_d_min_counts_given_counts_complete_have_format_strings)selfbinning
miller_setr%   r%   r&   r*   2   s    


zbinner.__init__c             C   s6   t |  |  ttj|  | jd|  | jdfS )N)	unit_cellr,   )crystal_symmetryr+   r-   )	r5   r7   limitssetr	   symmetryr,   miller_indicesr-   )r4   r%   r%   r&   __getinitargs__?   s    zbinner.__getinitargs__    c             C   sf   x`|   D ]T}| ||k r
x&|   D ]}td|| |f  q&W td||| ||f q
W d S )NzBIN: %s  COUNTS: %s z3Bin %s required to have %s or more counts has %s
%s)
range_usedr   printr   )r4   Z
min_countsZerror_stringi_binZj_binr%   r%   r&   require_all_bins_have_dataK   s    z!binner.require_all_bins_have_datac             C   s:   | j d kr4g | _ x"|  D ]}| j | | qW | j S )N)r1   	range_allappendr   )r4   rB   r%   r%   r&   counts_givenV   s
    
zbinner.counts_givenTư>c             C   sv   | j d krp| jdkstttj|  | jd| j| jd|  d}|sN|	 }|sZ|
 }t| |d}| | _ | j S )N)FT)r7   r,   r>   )r8   r-   r/   )r5   r6   )r2   r-   r!   	build_setr	   r;   r7   r,   r0   select_acentricselect_centricr(   rF   )r4   Zinclude_centricZinclude_acentricd_min_tolerancecomplete_setZbinner_completer%   r%   r&   counts_complete]   s    

zbinner.counts_completec             C   s   |  |   S )N)array_indicesi_bin_d_too_larger.   )r4   r%   r%   r&   n_bin_d_too_largeq   s    zbinner.n_bin_d_too_largec             C   s   |  |   S )N)rN   i_bin_d_too_smallr.   )r4   r%   r%   r&   n_bin_d_too_smallt   s    zbinner.n_bin_d_too_smallc             C   s   |   |   S )N)rP   rR   )r4   r%   r%   r&   n_bin_d_too_large_or_smallw   s    z!binner.n_bin_d_too_large_or_smallc             C   s   | j sd| _ tdtt|  }d| | _dd| d d  d | _td	| dd
  }d| | _d| }d	|d| jg| _
d	| jd| jg| _d	| jd|g| _dttt|   | _dttt|   | _d| j d | j d | _d S )NT   z
bin %%%dd:    r>      zunused:z%.4fr   z%%%d.4f-z%%%ddz%%-%dd[/])r3   maxlenstrZn_bins_usedfmt_bin
fmt_unusedbin_d_rangeZfmt_bin_rangejoinfmt_bin_range_firstfmt_bin_range_usedfmt_bin_range_lastrF   Zfmt_counts_givenrM   Zfmt_counts_completefmt_both_counts)r4   nZblank_dr%   r%   r&   _setup_format_stringsz   s    

zbinner._setup_format_stringsNdc	                sz  |d k	r|}d}|dkst |dkr0 d k	s0t |   ||  k}	||  k}
g }|r~|	s`|
rn|| j n|| j|  | |}|r<|dkrdd |D }nJ|dkrdd |D }n2|d	krd
d |D }n|dkr fdd|D }|	r|| j|d   n0|
r(|| j	|d   n|| j
t|  |rb|| j| j| | j| f  |rrd|S |S d S )Nri   )ri   	d_star_sqstolstol_sq	two_thetarm   rj   c             S   s   g | ]}t |qS r%   )r   d_as_d_star_sq).0bin_dr%   r%   r&   
<listcomp>   s    z%binner.bin_legend.<locals>.<listcomp>rk   c             S   s   g | ]}t t |qS r%   )r   Zd_star_sq_as_stolrn   )ro   rp   r%   r%   r&   rq      s   rl   c             S   s   g | ]}t t |qS r%   )r   Zd_star_sq_as_stol_sqrn   )ro   rp   r%   r%   r&   rq      s   c                s"   g | ]}t jt | d dqS )T)
wavelengthdeg)r   Zd_star_sq_as_two_thetarn   )ro   rp   )rr   r%   r&   rq      s   r>   r   rU   )r!   rh   rO   rQ   rE   r`   r_   ra   rc   re   rd   tuplerf   r1   r2   rb   )r4   rB   show_bin_numbershow_bin_rangeshow_d_rangeshow_countsbin_range_asrr   join_stringZis_firstZis_lastresultZ	bin_ranger%   )rr   r&   
bin_legend   sL    	




zbinner.bin_legendc	       
      C   sH   |d krt j}x4|  D ](}	t|| j|	||||||d |d qW d S )N)rB   ru   rv   rw   rx   ry   rr   )file)sysstdoutrD   rA   r|   )
r4   ru   rv   rw   rx   ry   rr   fprefixrB   r%   r%   r&   show_summary   s    	 zbinner.show_summaryc          
   C   s  t ||  kst|
d kr"tj}
|r0|  }n|  }d }x|D ]}| j|||||||	d}|| g}|| d k	rt|| t	s|d kr|
t	||  nNt|t	r|
|||   n0|| ||d}|d k	rt |dkr|
t	| td||
d qBW |d k	rt |S d S )N)rB   ru   rv   rw   rx   ry   rr   )r(   rB   datar   rU   )r}   )r]   
n_bins_allr!   r~   r   rD   r@   r|   
isinstancer^   rE   rA   rb   )r4   r   data_fmtru   rv   rw   rx   show_unusedry   rr   r   r   i_binslegendrB   partssr%   r%   r&   	show_data   s:     



 
 zbinner.show_data---Fc             C   s   t ||  kst|r"|  }n|  }g }x|D ]}	| j|	|ddddddd}
|
}||	 dk	rt||	 tsx|dkr|||	  qt|tr||||	   q|| |	|d}|| n
|| || q4W dd|g}t	j
j||d	S )
z2
    Export table rows for display elsewhere.
    TNri   F)rB   ru   rv   rw   rx   ry   rr   rz   )r(   rB   r   zResolution rangezN(obs)/N(possible))Zcolumn_headers
table_rows)r]   r   r!   rD   r@   r|   r   r^   rE   libtbxZtable_utilsZsimple_table)r4   r   
data_labelr   replace_none_withru   r   r   r   rB   r   rowr   labelsr%   r%   r&   as_simple_table   s:    





zbinner.as_simple_table)r>   r?   )TTrG   )TTNTri   NT)TTNTri   NNr?   )
NTTNTTri   NNr?   )Nr   FF)__name__
__module____qualname__r*   r=   rC   rF   rM   rP   rR   rS   rh   r|   r   r   r   r%   r%   r%   r&   r(   0   sR    

  
      
.       
         
!   r(   AnomalousProbabilityPlotResultslopeZ	interceptn_pairsexpected_deltac            
   @   s*   e Zd ZdddZdddZdd	d
ZdS )binned_dataNc             C   s   || _ || _|| _d S )N)r(   r   r   )r4   r(   r   r   r%   r%   r&   r*   /  s    zbinned_data.__init__Tri   r?   c             C   s2   |d kr| j }| jj| j|||||||||	|
dS )N)r   r   ru   rv   rw   rx   r   ry   rr   r   r   )r   r(   r   r   )r4   r   ru   rv   rw   rx   r   ry   rr   r   r   r%   r%   r&   show4  s     zbinned_data.showc             C   s"   |dkr| j }| jj| j||dS )zE
    Export table rows for display elsewhere.  (Used in Xtriage)
    N)r   r   r   )r   r(   r   r   )r4   r   r   r%   r%   r&   r   M  s     zbinned_data.as_simple_table)N)
NTTNTTri   NNr?   )N)r   r   r   r*   r   r   r%   r%   r%   r&   r   -  s   
         
r   c             C   s*   i }x t t| D ]}||| | < qW |S )N)r   r]   )r+   r{   ir%   r%   r&   make_lookup_dictY  s    r   r>   Fc             C   s   | dkrdddggS | dkrhdddgdddgdddgdddgdddgdddgg}|rd| dddg |S g }xxt|  | d D ]d}x^t|  | d D ]J}xDt|  | d D ]0}|s|dks|dks|dkr| |||f qW qW q~W |S )Nr   r>   )rE   r   )layersinclude_originoffset_listixZiyizr%   r%   r&   get_offset_list_  s      r   c             C   sN   ddl m} ||}ttt|   |  	 }| j
||  dS )Nr   )col)r+   r   )scitbx.matrixr   r   miller_indexlistvec3_intr+   as_vec3_doubler   as_intcustomized_copyr   )r#   offsetr   r+   r%   r%   r&   offset_indicesu  s    r   c               @   sJ  e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
eeeeefddZdddZdd ZdddZdddZdddZdd d!Zd"d# Zdd$d%Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zdd4d5Zd6d7 Zd8d9 Zdd:d;Zd<d= Z d>d? Z!d@dA Z"dBdC Z#dDdE Z$ddGdHZ%dIdJ Z&ddLdMZ'dNdO Z(dPdQ Z)dRdS Z*ddTdUZ+dVdW Z,dXdY Z-dZd[ Z.d\d] Z/d^d_ Z0ddadbZ1ddddeZ2dfdg Z3ddhdiZ4djdk Z5dldm Z6ddndoZ7ddpdqZ8ddsdtZ9ddvdwZ:ddxdyZ;ddzd{Z<dd|d}Z=dd~dZ>dddZ?dddZ@dddZAdddZBdd ZCdddZDdddZEdddZFdd ZGdddZHdddZIdd ZJdddZKdd ZLdddZMdddZNdd ZOdddZPdddZQdddZRdddZSdddZTdddZUdd ZVdd ZWdd ZXddĄ ZYddƄ ZZdddȄZ[dddʄZ\dd̄ Z]dd΄ Z^ddЄ Z_dS )r:   a  
  Basic class for handling sets of Miller indices (h,k,l), including sorting
  and matching functions, symmetry handling, generation of R-free flags, and
  extraction of associated statistics.  Does not actually contain data, but
  this can be added using the array(...) method.
  Nc             C   s0   |dkst tj| | || _|| _d | _d S )N)NFT)r!   r	   r;   _copy_constructor_indices_anomalous_flag_binner)r4   r8   r+   r-   r%   r%   r&   r*     s
    zset.__init__c             C   s(   t j| | |j| _|j| _d | _d S )N)r	   r;   r   r   r   r   )r4   otherr%   r%   r&   r     s    zset._copy_constructorc             C   s   | j S )zz
    Return a reference to the internal array of indices.

    :returns: a cctbx.array_family.flex.miller_index array
    )r   )r4   r%   r%   r&   r+     s    zset.indicesc             C   s   | j S )z6Indicate whether the set or array is anomalous or not.)r   )r4   r%   r%   r&   r-     s    zset.anomalous_flagc             C   s   |    S )z5Return the number of reflections in the set or array.)r+   r.   )r4   r%   r%   r&   r.     s    zset.sizec             C   s   t | | j| jdS )zd
    Create a copy of the set, keeping references to the same crystal symmetry
    and indices.
    )r8   r+   r-   )r:   r   r   )r4   r%   r%   r&   copy  s    zset.copyc             C   sb   |   }|dk	r tj | d}|  dkr2d}nt|  }ttj||d|  	 | 
 dS )z
    Create a copy of the set, also copying the crystal symmetry and indices.

    :returns: a set object with all-new attributes.
    N)
parameters)r7   space_group_symbol)r8   r+   r-   )r7   r   r   r,   r^   r:   r	   r;   r+   	deep_copyr-   )r4   r7   r   r%   r%   r&   r     s    
zset.deep_copyc             C   sL   |t kr| }|t kr|  }|t kr,|  }tjj|||d}t|||dS )z
    Create a copy of the set, optionally changing the symmetry, indices,
    and/or anomalous flag (default = keep all unmodified).
    )r7   r,   )r8   r+   r-   )r   r+   r-   r	   r;   r   r:   )r4   r8   r+   r-   r7   r,   r%   r%   r&   r     s    
   zset.customized_copyc             C   sJ   |dk	r|  | j  kst|dk	r<|  | j  ks<tt| ||dS )z
    Create an array object, given data and/or sigma arrays of identical
    dimensions to the indices array.

    :param data: a flex array (any format) or None
    :param sigmas: a flex array (any format, but almost always double) or None
    N)r6   r   sigmas)r.   r   r!   r#   )r4   r   r   r%   r%   r&   r#     s
    z	set.arrayc             C   s<   t |tkst|  d k	s tt| |  ||  dS )N)r8   r+   r-   )r   r    r!   r+   r:   r"   r-   )r4   r$   r%   r%   r&   r"     s    zset.__getitem__r?   c             C   sT   |dkrt j}t|d t|  |d t|d |  |d tjj| ||d | S )zMinimal Miller set summaryNzNumber of Miller indices:)r}   zAnomalous flag:)r   r   )	r~   r   rA   r]   r+   r-   r	   r;   r   )r4   r   r   r%   r%   r&   r     s     zset.show_summaryFc          
   C   sJ  |dk	st |  }|r&|   }n|  }t }t }t }x>t|D ]2\}}	||	d  ||	d  ||	d  qPW d}
tt	||
 tt	||
 tt	||
   }}}|  
 }d}d}t|dX}xPt|D ]D\}}	||	}t||||d |
 |d |
 |d |
 f |d	 qW W dQ R X dS )
ak  
    Write out Miller indices as pseudo-waters for visualization.  Note that
    this treats the indices as literal coordinates (times a scale factor),
    and the distances between points will not correspond to the distances
    in reciprocal space.

    See cctbx/miller/display.py and crys3d/hklview for an alternative (but
    less lightweight) approach.
    Nr   r>   rT   d   z/CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f P1        zCHETATM%5d  O   HOH %5d    %8.3f%8.3f%8.3f  1.00  1.00           O  w)r}   )r!   r7   expand_to_p1r+   r   int	enumeraterE   r\   absreciprocal_parametersopenreciprocal_space_vectorrA   )r4   	file_namer   ucr+   hkli_mimiscaleshskslrpZc1fmtfmtZofrsvr%   r%   r&   miller_indices_as_pdb_file  s,    
 $
zset.miller_indices_as_pdb_filec             C   s  |dkrt j}| j||d |  }|  dk	r| }|   }|d}t	|d ||d |dkr| j
| d}t	|d |d |  d}t	|d	 ||d |  dk	r| }t	|d
|  |d |  dk	r|   dkr|r|jdd |jdd}	|	j}
|
 d dks.t|
 d dksDt|
 d }|
 d }|dkr|d |d krt	|d||   |d ||
 d 7 }|dkrt	|d||   |d |  r|  s|  rt	|d|    |d |  dk	r| r|r| \}}t	|d |  |d t	|d | | |d t| tr|  rt	|d|    |d | S )z1Display comprehensive Miller set or array summaryN)r   r   TzSystematic absences:)r}   r   )	selectionz.Systematic absences not included in following:zCentric reflections:zResolution range: %.6g %.6gr>   )n_bins)use_binningrT   z&Completeness in resolution range: %.6gz&Completeness with d_max=infinity: %.6gz0Anomalous completeness in resolution range: %.6gzBijvoet pairs:zLone Bijvoet mates:zMean anomalous difference: %.4f)!r~   r   r   r   r,   is_unique_set_under_symmetrysys_absent_flagsr   r   rA   selectcentric_flagsr7   resolution_ranger+   r.   setup_binnercompletenessr(   rF   r!   rM   r-   is_xray_intensity_arrayis_xray_amplitude_arrayanomalous_completenessmatch_bijvoet_matespairs	n_singlesr   r#   is_real_arrayanomalous_signal)r4   r   r   
no_sys_absr   r   	n_sys_abs	n_centric	d_max_minZcompleteness_d_max_d_minr(   Zn_obs
n_completeasumatchesr%   r%   r&   show_comprehensive_summary  sd     



zset.show_comprehensive_summary  c             C   s   |dkrt j}| j|d x|   D ]v}|  |}| |}| \}}|j|d}|	d}	|  j
|ddd}
d}t|||
||	f |d |  q(W dS )	z6
    Display the completeness in resolution bins.
    N)reflections_per_bin)d_maxTF)rB   ru   rx   z%3d: %-17s %4.2f %6d)r}   )r~   r   r   r(   r@   r   r   r   r   r   r|   rA   flush)r4   r   outrB   selZself_selr   r/   ZcomplZn_refd_ranger   r%   r%   r&   show_completenessG  s     

zset.show_completenessc             C   s8   |   dks|   dkst| jtjj| |   ddS )NFT)r-   )r8   )r-   r!   r   r	   r;   reflection_intensity_symmetry)r4   r%   r%   r&   r   Y  s    z!set.reflection_intensity_symmetryc             C   s2   |   }|r|j|  d}| j||  dS )z
    Generate a boolean Miller array flagging those reflections which are
    systematically absent under the current symmetry.
    )r-   )r   )space_groupZ(build_derived_reflection_intensity_groupr-   r#   is_sys_absentr+   )r4   integral_onlyZeffective_groupr%   r%   r&   r   _  s
    zset.sys_absent_flagsc             C   s   t | |  |  S )zG
    Generate a boolean Miller array flagging centric reflections.
    )r#   r   
is_centricr+   )r4   r%   r%   r&   r   k  s    zset.centric_flagsc             C   s   t | |  |  |  S )a  
    Generate a Miller array (with integer data) indicating the multiplicity of
    each unique reflection.  (If the set or array is already symmetry-unique,
    the multiplicity will be 1 for every reflection.)

    :returns: array object with flex.int data
    )r#   r   Zmultiplicityr+   r-   )r4   r%   r%   r&   multiplicitiess  s    zset.multiplicitiesc             C   s   t | |  |  S )N)r#   r   epsilonr+   )r4   r%   r%   r&   epsilons  s    zset.epsilonsc             C   s   t | |  |  S )N)r#   r7   rj   r+   )r4   r%   r%   r&   rj     s    zset.d_star_sqc             C   s    t | t|  |  dS )Ng      ?)r#   r   powr7   rj   r+   )r4   r%   r%   r&   d_star_cubed  s    zset.d_star_cubedc             C   s   t | |  |  S )zW
    Generate a double Miller array containing the resolution d of each
    index.
    )r#   r7   ri   r+   )r4   r%   r%   r&   
d_spacings  s    zset.d_spacingsc             C   s   t | |  |  S )N)r#   r7   rl   r+   )r4   r%   r%   r&   sin_theta_over_lambda_sq  s    zset.sin_theta_over_lambda_sqc             C   s   t | |  |  ||S )z[
    Generate a double Miller array containing the scattering angle of each
    index.
    )r#   r7   rm   r+   )r4   rr   rs   r%   r%   r&   rm     s    zset.two_thetac             C   s   t |  |  S )z;
    High-resolution limit.
    :returns: Python float
    )r   d_star_sq_as_dr7   Zmax_d_star_sqr+   )r4   r%   r%   r&   r/     s    z	set.d_minc             C   s   |   |  S )N)r7   min_max_d_star_sqr+   )r4   r%   r%   r&   r    s    zset.min_max_d_star_sqc       	      C   s   |rt dd |  D \}}|dk rt|  }|d}t|d| ||d d  }|  |\}}t	|t	| }}||fS t dd |  D S dS )z
    Low- and high-resolution limits.
    :returns: Python tuple of floats
    Modified 2020-10-02 to allow return of maximum defined instead of -1
        if F000 present
    c             S   s   g | ]}t |qS r%   )r   r  )ro   rj   r%   r%   r&   rq     s   z!set.d_max_min.<locals>.<listcomp>r   )r   r   r   Nr>   c             S   s   g | ]}t |qS r%   )r   r  )ro   rj   r%   r%   r&   rq     s   )
rt   r  r   r+   indexr   r   r7   r   r  )	r4   $d_max_is_highest_defined_if_infiniter   r/   Zindices_copyr  Znew_indicesZd_max_d_star_sqZd_min_d_star_sqr%   r%   r&   r     s    

zset.d_max_minc             C   s   t |  S )N)
index_spanr+   )r4   r%   r%   r&   r    s    zset.index_spanc             C   s   |   }| | fS )z!Return the range of h,k,l indices)r  minr\   )r4   spanr%   r%   r&   min_max_indices  s    zset.min_max_indicesc             C   s&   | j |}|dkrd}n|| }|S )ae  
    Returns the element `ary` coresponding to the `miller_index` if
    `miller_index exists, otherwise returns None.

    :param miller_index: Miller index as a 3-tuple
    :type miller_index: tuple
    :param ary: any array (e.g. self.data(), self.sigmas())
    :type ary: sequence (list, array, etc)
    :returns: type of contents of `ary`, or None
    N)r   first_index)r4   aryr   firstr{   r%   r%   r&   at_first_index  s
    zset.at_first_indexc             C   s   | j |S )aC  
    Returns the first index of the item  matching
    `miller_index`. If the `miller_index` is not found in `self`,
    then returns ``None``.

    :param miller_index: Miller index as a 3-tuple
    :type miller_index: tuple
    :returns: int, None -- index of first occurrence of
              `miller_index` or None
    )r   r	  )r4   r   r%   r%   r&   r	    s    zset.first_indexc       	      C   s   |   \}}tt|d |d }tt|d |d }tt|d |d }d|||gks`t|   dd \}}}d||  d||  d||  fS )zR
    Returns the effective resolution limits along the reciprocal space axes.
    r   r>   rT   N   g      ?)r  r\   r   r!   r7   r   )	r4   min_mimax_miZmax_hZmax_kZmax_lastbstcstr%   r%   r&   d_min_along_a_b_c_star  s    zset.d_min_along_a_b_c_star{Gz?c             C   s   d|    d|  S )NrT   r>   )r/   )r4   	tolerancer%   r%   r&   !minimum_wavelength_based_on_d_min  s    z%set.minimum_wavelength_based_on_d_minc             C   s   |   S )zSynonym for d_max_min().)r   )r4   r%   r%   r&   r     s    zset.resolution_range2   c	       	      C   s,   | j |  j|  ||||||||d	dS )a  
    Given an isotropic or anisotropic displacement or B-factor, alculate
    resolution-dependent scale factors corresponding to the indices.
    (Note that to simply apply one of the input parameters to an existing
    Miller array, you can call array.apply_debye_waller_factors)

    :param u_iso: Isotropic displacement (in Angstroms)
    :param b_iso: Isotropic B-factor (8*pi^2*u_iso^2)
    :param u_cart: Anisotropic displacement tensor
    :param b_cart: Anisotropic B-factor
    :param u_star: Anisotropic displacement tensor in fractional space
    :param u_cif: Anisotropic displacement tensor, dimensionless basis
    :returns: cctbx.miller.array object
    )	r<   u_isob_isou_cartb_cartu_cifu_starexp_arg_limittruncate_exp_arg)r   )r#   r7   debye_waller_factorsr+   )	r4   r  r  r  r  r  r  r  r  r%   r%   r&   r     s    zset.debye_waller_factorsc             C   s   | j dd\}}|  S )z#Return the number of Bijvoet pairs.F)#assert_is_unique_set_under_symmetry)r   r   r.   )r4   r   r   r%   r%   r&   n_bijvoet_pairs  s    zset.n_bijvoet_pairsc             C   s   t | |  ddS )zg
    Return a copy of the set using the same indices but with the anomalous flag
    set to false.
    F)r8   r+   r-   )r:   r+   )r4   r%   r%   r&   as_non_anomalous_set"  s    zset.as_non_anomalous_setc             C   s   t | |  ddS )zf
    Return a copy of the set using the same indices but with the anomalous flag
    set to true.
    T)r8   r+   r-   )r:   r+   )r4   r%   r%   r&   as_anomalous_set,  s    zset.as_anomalous_setc             C   s   ||g ddkst|   dkr,d}nH|dk	rRd|   |    |k}n"|dk	rh|  |k}n|  dk}t| |  |dS )z
    Set the anomalous flag automatically depending on whether the data
    contain Bijvoet pairs (optionally given minimum cutoffs).

    :returns: a copy of the set with (maybe) a new anomalous flag
    Nr   FrT   )r8   r+   r-   )r   r!   r+   r.   r"  r:   )r4   Zmin_n_bijvoet_pairsZmin_fraction_bijvoet_pairsr-   r%   r%   r&   auto_anomalous6  s    zset.auto_anomalousc             C   s    t j|   |  |  dS )zG
    Determine whether the indices in the set are symmetry-unique.
    )space_group_typer-   r<   )r)   r   r,   r   r-   r+   )r4   r%   r%   r&   r   M  s    
z set.is_unique_set_under_symmetryc             C   s    t j|   |  |  dS )N)r&  r-   r<   )r)   unique_under_symmetry_selectionr,   r   r-   r+   )r4   r%   r%   r&   r'  V  s    
z#set.unique_under_symmetry_selectionc             C   s*   |   }| |   kr | S | |S )N)r'  r.   r+   r   )r4   r   r%   r%   r&   unique_under_symmetry\  s     zset.unique_under_symmetryc             C   s   |    |  S )z
    Indicate whether the array is entirely contained within the reciprocal
    space asymmetric unit (ASU).  Warning: this calls map_to_asu internally,
    so it is better to simply call map_to_asu without checking in many cases.
    )
map_to_asur+   all_eq)r4   r%   r%   r&   	is_in_asua  s    zset.is_in_asuc             C   sD   |    }|  }|dkr d}t|   || t| ||  S )z
    Convert all indices to lie within the canonical asymmetric unit for the
    current space group (while preserving anomalous flag).  Required for many
    downstream steps.
    NT)r+   r   r-   r)  r,   r   r:   )r4   r   r-   r%   r%   r&   r)  j  s    
zset.map_to_asuư>c             C   s   |   dkst|   dkr6t| |   t dS |dk	rPt| |   |dS |dk}|rd|  }|}|dk	r||d| 9 }t| |   ||d}|r|	|
  |dt  k}|S dS )a]  
    Generate the complete set of Miller indices expected for the current
    symmetry, excepting systematic absences.

    :param d_min_tolerance: tolerance factor for d_min (avoid precision errors)
    :param d_min: High-resolution limit (default = d_min of current set)
    :param d_max: Low-resolution limit (default = d_max of current set)
    )FTr   )r8   r-   r+   N)r8   r-   	max_indexr>   )r8   r-   r/   r   )r-   r!   r+   r.   r:   r   r   rH   r/   r   r   r   fp_eps_double)r4   rK   r/   r   r-  Zd_min_was_noneZd_min_exactr{   r%   r%   r&   rL   z  s4    
  zset.complete_setr>   c             C   s  |dkst |rZ|  rZ|    }| |  |rD||  |j|||||ddS |s| j||d}t	| 
  td|
   d| S |  dk	st g }	xLt|   |   D ].\}
}|dkr|	| q|	||
 |  qW t|  |	dd	S )
a  
    Calculate the (fractional) completeness of the array relative to the
    theoretical complete set, either overall or in resolution bins.  By default
    the current low-resolution limit will be used.

    :param d_min_tolerance: tolerance factor for d_min (avoid precision errors)
    :param d_max: Low-resolution limit (default = d_max of current set)
    :param multiplier: Factor to multiply the result by (usually 1 or 100)
    :param as_non_anomalous_array: Report values for non-anomalous array
    r   F)r   rK   return_failr   
multiplieras_non_anomalous_array)rK   r   r>   g      ?Nz%5.3f)r(   r   r   )r!   r-   r1  merge_equivalentsr#   set_observation_typeuse_binning_ofr   rL   r  r+   r.   r\   r(   r   rF   rM   rE   r   )r4   r   rK   r/  r   r0  r1  mergedrL   r   Zn_givenr   r%   r%   r&   r     s2    

 zset.completenessc             C   s   t |   dS )NT)r   boolr+   r.   )r4   r%   r%   r&   all_selection  s    zset.all_selectionc             C   sD   |   dk	st|dkr |  }|r*| }|   |}t| ||S )a  
    Select a subset of reflections.

    :param selection: flex.bool or flex.size_t selection
    :param negate: select the inverse of the selection array
    :param anomalous_flag: anomalous flag for the new set
    :returns: a new set with a subset of indices
    N)r+   r!   r-   r   r:   )r4   r   negater-   r   r%   r%   r&   r     s    	 z
set.selectc             C   s   |  |    S )zl
    Select only acentric reflections.

    :returns: A Miller set or array (depending on object type).
    )r   r   r   )r4   r%   r%   r&   rI     s    zset.select_acentricc             C   s   |  |   S )zk
    Select only centric reflections.

    :returns: A Miller set or array (depending on object type).
    )r   r   r   )r4   r%   r%   r&   rJ     s    zset.select_centricc             C   s   | j |   | dS )N)r   r8  )r   r   r   )r4   r8  r%   r%   r&   remove_systematic_absences  s    
zset.remove_systematic_absencesc             C   sp   |   }|   }|ds"tt|}|dk	rL|dkrL||d| kM }|dk	rl|dkrl||d| kM }|S )ze
    Obtain the selection (flex.bool array) corresponding to the specified
    resolution range.
    r   Nr>   )r7  rj   r   all_ger!   r   sqrt)r4   r   r/   r{   rj   Zd_starr%   r%   r&   resolution_filter_selection  s    
  zset.resolution_filter_selectionr   c             C   s   | j | j||d|dS )a;  
    Select a subset within the indicated resolution range.
    Returns a new miller array (does not change existing array)

    :param d_max: Low-resolution cutoff
    :param d_min: High-resolution cutoff
    :param negate: Select outside this range instead
    :returns: set or array depending on object type
    )r   r/   )r   r8  )r   r<  )r4   r   r/   r8  r%   r%   r&   resolution_filter  s    
zset.resolution_filterTc             C   s8   |r|  |st|  | ks&tt|  | S )N)is_similar_symmetryr!   r-   match_indicesr+   )r4   r   assert_is_similar_symmetryr%   r%   r&   r?  	  s    zset.match_indicesc             C   s"   |j | |d }| |dS )z
    Match the indices in the current set and another set, and return a set
    (or array) containing only those reflections present in both.  Assumes that
    both sets are already in the asymmetric unit (ASU).
    )r   r@  r>   )r?  r   r   column)r4   r   r@  r   r%   r%   r&   
common_set  s    zset.common_setc             C   sF   |j | |d}|r| rt| }| |d||dgS )zn
    Like common_set(other), but returns a tuple containing matching copies of
    both sets (or arrays).
    )r   r@  r>   r   )r?  Zhave_singlesr!   r   r   rA  )r4   r   r@  assert_no_singlesr   r   r%   r%   r&   common_sets  s    zset.common_setsc             C   s   |  |j| |ddS )z
    Match the indices in the current set and another set, and return a set
    (or array) containing reflections which are present only in the current
    set.  Assumes that both sets are already in the asymmetric unit.
    )r   r@  r>   )r   r?  singles)r4   r   r@  r%   r%   r&   lone_set+  s    zset.lone_setc             C   s.   |j | |d}| |d||dgS )zq
    Like lone_set(other), but returns a tuple containing the reflections
    unique to each set (or array).
    )r   r@  r>   r   )r?  r   rE  )r4   r   r@  r   r%   r%   r&   	lone_sets5  s
    zset.lone_setsc             C   sl   |   dkst|  dk	s t|  dk	rP|  }t|  | |d}n| }t| |d}||fS )z
    Group Bijvoet mates (or Friedel mates) together, returning an object that
    allows enumeration over matching pairs and/or singletons.
    )NTN)r!  )r-   r!   r+   r,   r)  r   r   )r4   r!  r   r   r%   r%   r&   r   @  s    
zset.match_bijvoet_mates
resolutionc       	      C   s  |dkst |dkst |dkr>tj|  |  |ddS |dkr|   }t|  	 d| |   }t|  	 d| | 
  }||k }t|   d}|| d	 t|| | }tj||ddS tjt|  |  |ddS d
S )z
    Generate the selection array (flex.size_t object) to reorder the array
    by resolution or Miller index.

    :param by_value: sort type, must be "resolution" or "packed_indices"
    :param reverse: invert order
    :returns: flex.size_t object
    )rH  packed_indicesasu_indices)FTrH  T)r   reversestablerJ  Fr   g{Gz?N)r!   r   sort_permutationr7   rj   r+   r   r)  r,   r   r   r   doubler.   set_selected
iselectionr  pack	as_double)	r4   by_valuerK  rJ  Zasu_indices_anomr   Zfriedel_mate_flagsr   r   r%   r%   r&   rM  S  s(    	

zset.sort_permutationc             C   s   |  | j||dS )zs
    Reorder reflections by resolution or Miller index.

    :param by_value: 'resolution' or 'packed_indices'
    )rS  rK  )r   rM  )r4   rS  rK  r%   r%   r&   sortu  s    zset.sort皙?        @   cnsc             C   sN   |dkst |r|dkst |s4| j|||||dS | j||||||dS dS )a  
    Create an array of R-free flags for the current set, keeping anomalous
    pairs together.  Requires that the set already be unique under symmetry,
    and generally assumes that the set is in the ASU.

    :param fraction: fraction of reflections to flag for the test set
    :param max_free: limit on size of test set, overrides fraction
    :param lattice_symmetry_max_delta: limit on lattice symmetry calculation
    :param use_lattice_symmetry: given the current symmetry, determine the     highest possible lattice symmetry and generate flags for that symmetry,     then expand to the current (lower) symmetry if necessary.  This is almost     always a good idea.
    :param use_dataman_shells: generate flags in thin resolution shells to     avoid bias due to non-crystallographic symmetry.
    :param n_shells: number of resolution shells if use_dataman_shells=True
    :param format: convention of the resulting flags.  'cns' will return a     boolean array (True = free), 'ccp4' will return an integer array from     0 to X (0 = free, X dependent on fraction), 'shelx' will return an     integer array with values 1 (work) or -1 (free).

    :returns: a boolean or integer Miller array, depending on format.
    )rY  ccp4shelxr   )fractionmax_freeuse_dataman_shellsn_shellsformat)r\  r]  	max_deltar^  r_  r`  N)r!   generate_r_free_flags_basic)generate_r_free_flags_on_lattice_symmetry)r4   r\  r]  Zlattice_symmetry_max_deltaZuse_lattice_symmetryr^  r_  r`  r%   r%   r&   generate_r_free_flags~  s    zset.generate_r_free_flagsc             C   s   t j|  |  dS )z{Get crystal symmetry of the miller set

    :returns: a new crystal.symmetry object
    :rtype: cctbx.crystal.symmetry
    )r7   r,   )r	   r;   r7   r,   )r4   r%   r%   r&   r8     s    zset.crystal_symmetryc	             C   s  |    }	|	dkrtd|	}
|  rH|  d }|  |  }
|  sTt|dk	r|dkrl|dk sttd|dkst|dkst|dk	r|dk	stt	|
| |t
|
 }|dkst|dkst|r|rt|dkst|dkst|dkst|  }| |}tj| |d}tj| |dd	}| j|t|   dd
 }|  }| }|   }|   }d}|s|r|dkrtdtj|||d}ntj|||d}n`t }t|| d }x0t|D ]$}t|}t |}|!| qW tt"|d| }|  }|j#tj | $|dddd}|j|dd}|% }|jtj| |& dd}|  }|  r|' }||(  }|)|  }|j|   |* d}|)| }|  +|   st|S )a  
    Generate R-free flags by converting to the highest possible lattice
    symmetry (regardless of intensity symmetry), creating flags, and expanding
    back to the original symmetry.  This is a safeguard against reflections
    that are correlated due to twinning being split between the work and test
    sets.

    This method should usually not be called directly, but rather through
    set.generate_r_free_flags(...).
    r   z9An array of size zero is given for Free R flag generationr>   Ng      ?z?R-free flags fraction must be greater than 0 and less than 0.5.F)ra  )r7   r   Zassert_is_compatible_unit_cell)r8   r   rZ  zPCCP4 convention not available when generating R-free flags in resolution shells.)n_reflfraction_freer   )r`  T)r   rK  )r+   rK  )r   r   )r7   r   )r8   )r+   r   ),r+   r.   r   r-   r   r   r   r   r!   r  float!change_of_basis_op_to_niggli_cellchange_basisr   groupr7   r	   r;   r#   r   r   rN  r)  r2  average_bijvoet_matesr   assign_r_free_flags_by_shellsassign_random_r_free_flagssize_tr   r   random_doublerM  extendr   r   rj   r   r   generate_bijvoet_matesinverserB  r   r*  )r4   r\  r]  ra  Zreturn_integer_arrayZn_partitionsr^  r_  r`  Z
n_originalZ	n_non_anor   Zcb_op_to_niggliZtmp_maZlattice_groupZ
lattice_xsZ	tmp_flagsZn_non_ano_lat_symrg   r{   Zn_timesiitmpr+   r%   r%   r&   rc    s    










z-set.generate_r_free_flags_on_lattice_symmetryc             C   s  |dkr|dk st d|r,|dk r,t d|dk	rD|dkrDt d|  r|  d }|d	}|d
}|d	}	|d
}
|  |  }~n|  st	| 
  }|dk	rt||td| }|r|dkrt dtj|||d}ntj|||d}|  s| 
 }nH| 
 |}|| 
 |	 || 
 |
 | |ks^t	|jtj|  |dddd}|  s| j|dS ~|dkrd}t| 
  d}n<|dkrd}t| 
  d}nd}t| 
  d}| }||	  }|d| }||| ||||ks>t	||| ||d|| ksht	~~~||	|||  ~	||
||d  ~
| j|dS )z
    Generate R-free flags, without taking lattice symmetry into account (not
    recommended).  Should not normally be called directly - use
    generate_r_free_flags(...) instead.
    r   g      ?z?R-free flags fraction must be greater than 0 and less than 0.5.   zOYou must use at least 5 resolution shells when assigning R-free flags this way.NzQThe maximum number of free reflections must either be None, or a positive number.r>   +rX   rZ  zPCCP4 convention not available when generating R-free flags in resolution shells.)re  rf  r   )re  rf  r`  T)r   rK  )r+   rK  )r   r[  r   FrT   )r   r-   r   pairs_hemisphere_selectionrE  r   r.   r   r   r!   r+   r  r\   r   rl  rm  r   rp  r   rM  r7   rj   r#   r   r6  rO  r   )r4   r\  r]  r^  r_  r`  r   Zsel_ppZsel_pmZsel_spZsel_smrg   r{   r+   Ztest_flag_valueZresult_fullZi_ppZi_pp_spZr_ppr%   r%   r&   rb  +  s    









zset.generate_r_free_flags_basicc             C   sP   t j|  dd }|r"|d9 }n|dtj 9 }| j|  j|  ||ddS )N)r.   g      ?ih  rT   )r<   phasesrs   )r   )	r   ro  r.   mathpir#   r   Znearest_valid_phasesr+   )r4   rs   random_phasesr%   r%   r&   0random_phases_compatible_with_phase_restrictions  s     
z4set.random_phases_compatible_with_phase_restrictionsc             C   s8   t |trt|}tj| tj| ||	| 
 dS )a&  Get a transformation of the miller set with a new basis specified by cb_op

    :param cb_op: object describing the desired transformation of the basis
    :type cb_op: string or sgtbx.change_of_basis_operator

    :returns: a new miller set with the new basis
    :rtype: cctbx.miller.set
    )r8   r+   )r   r^   r   change_of_basis_opr:   r   r	   r;   ri  applyr+   )r4   cb_opr%   r%   r&   ri    s
    	
 
zset.change_basisc             C   sL   |   d k	st|  d k	s t|  d k	s0tt|  |  |  |dS )N)r   r-   r+   build_iselection)r,   r!   r+   r-   expand_to_p1_iselectionr   )r4   r  r%   r%   r&   r    s    zset.expand_to_p1_iselectionc             C   s6   | j |d}t|  |j|  d}|r2||jfS |S )zGet a transformation of the miller set to spacegroup P1

    :returns: a new set of parameters (symmetry, miller indices, anomalous_flag) in spacegroup P1
    :rtype: set(cctbx.crystal.symmetry, cctbx.miller.indices, boolean)
    )r  )r8   r+   r-   )r  r:   cell_equivalent_p1r+   r-   rP  )r4   return_iselectionproxyr{   r%   r%   r&   r     s    
zset.expand_to_p1c             C   s&   |   dksttj| tj| dS )NF)r8   )r-   r!   r:   r   r	   r;   patterson_symmetry)r4   r%   r%   r&   r    s    zset.patterson_symmetryUUUUUU?ru  c             C   s<   |dkr|dkr|   }tj|  |||||  |||d	S )z
    Calculate real-space grid for FFT given array crystal symmetry, d_min, and
    desired resolution-dependent spacing.  The actual grid dimensions will be
    adjusted to suit the needs of the FFT algorithm.
    N)	r7   r/   resolution_factorstepsymmetry_flagsr,   mandatory_factors	max_primeassert_shannon_sampling)r/   r
   crystal_griddingr7   r,   )r4   r  r/   	grid_stepr  r  r  r  r%   r%   r&   r    s     zset.crystal_griddingc             C   s>   t |   ||}|  }| j||||    dS )N)r+   r   )	asu_map_extZasymmetric_mapr   r   r+   r   structure_factorsr7   volume)r4   Zasu_map_datan_realZasu_mr+   r%   r%   r&   structure_factors_from_asu_map  s    z"set.structure_factors_from_asu_mapc       
      C   s  |  dkr | dkr | s$tt|tjr8| }t|tjsTt|tj	sTt|dks`tt|tjrt
| }| s|rt| | kstt|t| | }q|s| }n|s| }t
| }||}|r|   t|   }||9 }|dkr0|  }|rVtjj|  ||   |dd}ntjj||   |dd}|! }	t"| |	dS )	a  
    Run FFT on a real-space map to calculate structure factors corresponding to
    the current set of Miller indices.

    :param map: flex.double map with 3D flex.grid accessor
    :param in_place_fft: perform the FFT in place instead of creating a copy of
      the map first
    :param use_scale: perform volume-scaling using current unit cell
    :param anomalous_flag: determines anomalous_flag for output array
    :param use_sg: use space-group symmetry
    :returns: array with same Miller indices and complex_double data
    r   r  )FTNT)r   r-   r<   complex_mapconjugate_flag)r-   r<   r  r  )r6   r   )#focus_size_1dnd
is_0_basedr!   r   r   r   rR  rN  complex_doubler   real_to_complex_3dfocus	is_paddedr  r
   r   gridZm_real	set_focusr   complex_to_complex_3dforwardr7   r  r   r   productr-   r  from_mapr   r+   r   r#   )
r4   mapZin_place_fft	use_scaler-   use_sgfftr   r  r   r%   r%   r&   structure_factors_from_map  sJ    $ "




zset.structure_factors_from_mapc
          
   C   sL   ddl m}
 |dkr&|
jj|| |dS |
jj| |||||||	d|| |dS )a  
    Calculate structure factors for an :py:class:`cctbx.xray.structure` object
    corresponding to the current set of Miller indices.  Can use either FFT
    or direct summation.

    :param xray_structure: :py:class:`cctbx.xray.structure` object
    :param algorithm: switch method to calculate structure factors - can be
      'direct' or 'fft'
    :returns: array with same Miller indices and complex_double data
    r   )xrayZdirect)xray_structurer6   cos_sin_table)r6   r  grid_resolution_factorquality_factoru_baseb_basewing_cutoffexp_table_one_over_step_size)r  r6   	algorithm)cctbxr  r  Zfrom_scatterers_directZfrom_scatterers)r4   r  r  r  r  r  r  r  r  r  r  r%   r%   r&   !structure_factors_from_scatterers  s$    z%set.structure_factors_from_scatterersc       	   	   C   s   ddl m} t }t }x4| D ](\}}||j|	  || q$W t
j|||j|j|  |  |  dj}t| |S )z A miller.array whose data N(h) are the normalisations to convert
    between E's and F's:
    E(h) = F(h) / N(h)
    The argument wilson_plot shall feature attributes
    - wilson_intensity_scale_factor
    - wilson_b
    r   )eltbx)Zform_factorsr   wilson_intensity_scale_factorwilson_br+   r7   r   )r  r  r   rN  Zshared_gaussian_form_factorsitemsrE   Zxray_scatteringwk1995Zfetchr)   Zamplitude_normalisationr  r  r+   r7   r   normalisationsr#   )	r4   asu_contentswilson_plotr  r   Z	gaussiansZchemical_typeZ
multiplicyr   r%   r%   r&   amplitude_normalisations1  s     
zset.amplitude_normalisationsc
       
      C   s(   | j || j||||||||	d dS )N)r  r  r  r  r  r  r  r  )f_obs_factorf_calc)f_obs_minus_f_calcr  r  )
r4   r  r  Zstructure_factor_algorithmr  r  r  r  r  r  r%   r%   r&   !f_obs_minus_xray_structure_f_calcK  s    z%set.f_obs_minus_xray_structure_f_calcc             C   s  |s|dks|dkst |s0|dks0|dks0t |r|dkr@d}|dkrLd}tt|  | d }||krtt|  | d }n|rtt|  | d }|dkst |  dk	st |   dks|dkst | jt|  ||  ||d |  S )z`
    Create internal resolution binner object; required for many other methods
    to work.
    r         g      ?N)r5   )	r!   r   r]   r+   r7   r.   r   r5   r(   )r4   r   r/   auto_binningr   r   Z	n_per_binr%   r%   r&   r   _  s$      zset.setup_binnerr   -C6?   c                s  |dkst ||   ks0|d |   krFt|   dgS |    }dt| }t	|  d  |  |d  }|   }|  fdd}	|	 }
t
|
|kr t
 d   |d  |	 }
g }x|t|
D ]p\}}|t
|
d k r.||
|d   }}|||g q|t
|
d kr|
|d  |
|  }}|||g qW g }xt|D ]\}}|\}}|dkr||| k}|||kM }n@|t
|d kr||k}|||| kM }n||k}|||kM }|| qtW |t
|d  }|t
|d  }|d|dd k rX|d	t
|d  }|||B  |}g }xdt|D ]X\}}|d|k rt
|d dkr|t
|d  |B |t
|d < n
|| qfW |}|S )
z
    Create resolution bins on a logarithmic scale.  See Urzhumtsev et al.
    (2009) Acta Crystallogr D Biol Crystallogr. 65:1283-91.
    r>   rT   Tg      ?r   c                 s   t dt  g} }x8|t krRt dt | }| | |7 }qW tt |}t dt | }| | | S )Nr>   )ry  r;  expr   r\   rE   r  )r9   Zlnss_minri   )lnsss0s1r  r%   r&   
get_limits  s    

z#set.log_binning.<locals>.get_limitsrV   N)r!   r+   r.   r   r6  rT  r   r   pow2logr]   r   rE   r   )r4   Z&n_reflections_in_lowest_resolution_binepsZmax_number_of_binsZmin_reflections_in_binZd_spacings_sortedsss2r   r  r9   r   r   ri   d1d2Z
selectionspr   r/   r   r   spZnew_selectionsZnew_selsir%   )r  r  r  r  r&   log_binningx  sd    

""zset.log_binningc             C   s   |s|d k	st |s |d k	s t |r8|dks8|d ks8t |rj|   }t|}t|}~|d krjd}|dksvt t||f\}}| jt| 	 | 
 |||dS )Nr   gMbp?g        )r5   )r!   r   r   r   r\   r  sortedr   r5   r7   r+   )r4   r  r   r/   d_star_sq_stepr   r%   r%   r&   setup_binner_d_star_sq_step  s$    

zset.setup_binner_d_star_sq_step     h㈵>c             C   s$  | j dd\}}|dk	r$t||}	n|}	|dk	r<t||}
n|}
|	|k sP|
|krp|  j|	|
d}| }d}n|  }|}ttt|| ||}t }d|	|	  }d|
|
  }|| | }|	|||   x(t
d|D ]}|||  }|	| qW |	|||   | jt|  |dS )	zT
    Set up bins of equal width in d_star_sq by target for mean number per bin.
    T)r  N)r   r/   g        g      ?r>   )r5   )r   r  r\   r   r=  r.   r   r   rN  rE   r   r   r5   r7   )r4   r   Zmin_binsZmax_binsr   r/   d_toleranceZ
d_max_dataZ
d_min_dataZ
d_max_workZ
d_min_workZworking_dataZ
n_ref_workZ
this_d_tolr   r9   Zd_star_sq_minZd_star_sq_maxr  rB   Z
this_limitr%   r%   r&   setup_binner_d_star_sq_bin_size  s4    

z#set.setup_binner_d_star_sq_bin_size绽|=c             C   s~  |dkst |dkst t|ts0t|ts0t |d k	rD|dksDt |d k	rX|dksXt |dksdt |dk spt |   }|t|}|dd  |d d  }||k }|d7 }|	dd ||}|dkr||d|d  k}|dkr||d|d  k }|
 dkst |rRtdt|
 t| }	|rNt||	n|	}||
 kstt d||
 f |
 t| }t }
|
|d  |dkr|
d|d  d|   n|
td|d d|   |
 d }xBtd|D ]4}t|| }|
|| d|   ||krP qW |dkrR|
d|d  d|   n|
|d d|   | jt|  |
dS )	Nr   g      ?r>   r   g      ?rT   z7n_bins (%i) must be <= number of unique d-spacings (%i))r5   )r!   r   r   rj   r   r   r   rM  rP  insertr.   r\   r   rg  r  rN  reserverE   r   r   r5   r7   )r4   r   r/   r   r   r  rj   deltaZiselZn_bins_calcr9   mrB   r   r%   r%   r&   setup_binner_counting_sorted   sV    



 
z set.setup_binner_counting_sortedc             C   s   | j S )zU
    Return a reference to the current resolution binner (or None if undefined).
    )r   )r4   r%   r%   r&   r(   7  s    z
set.binnerc             C   s   t || | _| jS )z|
    Use the resolution binning of the specified binner object (does not need
    to be from an identically sized set).
    )r(   r   )r4   r5   r%   r%   r&   r   =  s    zset.use_binningc             C   s   | j | dS )zp
    Use the resolution binning of the specified set (does not need to be an
    identical set of indices).
    )r5   )r   r(   )r4   r   r%   r%   r&   r4  E  s    zset.use_binning_ofc             C   s$   |   |  st|j| _| jS )zQ
    Use the exact binner of another set, which must have identical indices.
    )r+   r*  r!   r   )r4   r   r%   r%   r&   use_binner_ofL  s    zset.use_binner_ofc             C   s
   d | _ d S )N)r   )r4   r%   r%   r&   clear_binnerT  s    zset.clear_binnerc             C   sD   |r|  |st|  | ks&tt| | j| |  dS )zu
    Combine two Miller sets.  Both must have the same anomalous flag, and
    similar symmetry is also assumed.
    )r8   r+   r-   )r>  r!   r-   r:   r   concatenater+   )r4   r   r@  r%   r%   r&   r  W  s    zset.concatenatec             C   s   |d k	r$|d kst dddg|}|d k	rT|d kr<|d ks@t t|  ||d}n$d ||gksdt t|  |||d}| |S )Nr   r   r   )r+   
slice_axisslice_index)r+   r  slice_start	slice_end)r!   r  Zsimple_slicer+   Zmulti_slicer   )r4   axisZ
axis_indexr  r  r  r   r%   r%   r&   r    d  s     
z	set.slicec             C   s&   t |dkst|  |k}| |S )zA
    Remove all reflections with the specified Miller index.
    r  )r]   r!   r+   r   )r4   hklseler%   r%   r&   delete_index|  s    zset.delete_indexc             C   s@   t |   d}x | D ]}||  |kM }qW | |S )z]
    Delete multiple reflections, as specified by the Miller indices of
    another set.
    T)r   r6  r+   r.   r   )r4   r   r  r  r%   r%   r&   delete_indices  s    zset.delete_indicesc             C   sF   |   r| S |    }|   }|||  t| |ddS )zk
    If the array is not already anomalous, expand the miller indices to generate
    anomalous pairs.
    T)r8   r+   r-   )r-   r   r   r+   r   rp  r   r:   )r4   r   r+   r%   r%   r&   generate_bivoet_mates  s     zset.generate_bivoet_mates)N)NN)Nr?   )NF)Nr?   )r   N)F)F)F)r  )NNNNNNr  F)NN)r,  NNN)Fr,  NNr>   N)FN)F)NN)r   r   r   )T)T)TF)T)T)T)rH  F)rH  F)rU  rV  rW  TFrX  rY  )rU  rV  rW  FNFrX  rY  )rU  rV  FrX  rY  )F)T)F)r  NNNNru  T)FFNF)NFr  NNNNN)NFNNNNN)r   r   Fr   r   )r   r  r  r  )TNNN)r  r  r  NNr  )r   r   NNr  )T)NNNNN)`r   r   r   __doc__r*   r   r+   r-   r.   r   r   r   r   r#   r"   r   r   r   r   r   r   r   r   r   rj   r   r   r   rm   r/   r  r   r  r  r  r	  r  r  r   r   r"  r#  r$  r%  r   r'  r(  r+  r)  rL   r   r7  r   rI   rJ   r9  r<  r=  r?  rB  rD  rF  rG  r   rM  rT  rd  r8   rc  rb  r|  ri  r  r   r  r  r  r  r  r  r  r   r  r  r  r  r(   r   r4  r  r  r  r    r  r  r  r%   r%   r%   r&   r:   }  sJ  




 
4




       


 
		 
#  
&





 





"

      
)       
l    
Q
	


      
 
5       
      
   
 
G   
     
$    
2
    
r:   c             C   s~   |dk	r@||g ddkstt| t|   || |}n:t| t|  |   || |}|dk	rz|j|d}|S )a  
  Given crystal symmetry, anomalous flag, and resolution limits, create a
  complete set object.

  :param crystal_symmetry: cctbx.crystal.symmetry object
  :param anomalous_flag: Boolean, indicates whether to generate anomalous indices
  :param d_min: High-resolution limit (optional if max_index is specified)
  :param d_max: Low-resolution limit (optional)
  :param max_index: highest-resolution Miller index
  :returns: a set object
  NrT   )r   )	r   r!   r:   Zindex_generatorr,   r   Zto_arrayr7   r=  )r8   r-   r/   r   r-  r{   r%   r%   r&   rH     s(    

 rH   c             C   sF   t | dkstt }x| D ]}||  qW | d j| dS )Nr   )r+   )r]   r!   Zunion_of_indices_registryupdater+   r   as_array)Zmiller_setsZuoimsr%   r%   r&   union_of_sets  s
    
r  c            	   @   sV   e Zd ZdZdddZdd Zeeeeeeeeef	dd	Zd
d Zdd Z	dd Z
dS )
array_infozf
  Container for metadata associated with a Miller array, including labels
  read from a data file.
  NFc
       
      C   s   t | t  d S )N)r   locals)
r4   sourcesource_typehistoryr   r5  systematic_absences_eliminatedcrystal_symmetry_from_filetype_hints_from_filerr   r%   r%   r&   r*     s    
zarray_info.__init__c             C   s&   d | _ | j| t| ds"d | _d S )Nrr   )r  __dict__r  hasattrrr   )r4   stater%   r%   r&   __setstate__  s    
zarray_info.__setstate__c
       
      C   s   |t kr| j}|t kr| j}|t kr*| j}|t kr8| j}|t krF| j}|t krT| j}|t krb| j}|t krp| j}|	t kr~| j	}	t
|||||||||	d	S )zw
    Create a modified copy of the array_info object, keeping all attributes
    that are not explicitly modified.
    )	r  r  r  r   r5  r  r  r  rr   )r   r  r  r  r   r5  r  r  r  rr   r  )
r4   r  r  r  r   r5  r  r  r  rr   r%   r%   r&   r     s8         zarray_info.customized_copyc             C   s>   g }| j d k	r|| j  | jr*|d | jr:|d |S )Nr5  r  )r   rp  r5  rE   r  )r4   part_2r%   r%   r&   as_string_part_2  s    


zarray_info.as_string_part_2c             C   s"   |   }t|dkrd|S dS )z
    A combined representation of the data labels extracted from the input file.
    This is generally how downstream programs will identify and select Miller
    arrays.
    r   ,N)r  r]   rb   )r4   r  r%   r%   r&   label_string  s     
zarray_info.label_stringc             C   sx   g }| j d k	r |t| j  n| jd k	r:|t| j |  }t|dkr^|d| t|dkrndS d|S )Nr   r  None:)r  rE   r^   r  r  r]   rb   )r4   r{   r  r%   r%   r&   __str__  s    

zarray_info.__str__)	NNNNFFNNN)r   r   r   r  r*   r  r   r   r  r  r  r%   r%   r%   r&   r    s.           


r  c             C   s@   | d krt d S y| jjdt| f  S  tk
r:   dS X d S )Nz	, size=%dZUnknown)r^   	__class__r   r]   	Exception)r#   r%   r%   r&   raw_array_summary'  s     r  c            
   @   s  e Zd ZdZdd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dd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d0d1 Zd2d3 Zd4d5 Zd6d7 Zeeeeeeeeedf
d8d9Zdd;d<Z eeeeefd=d>Z!d?d@ Z"dAdB Z#dCdD Z$dEdF Z%dGdH Z&ddIdJZ'dKdL Z(ddNdOZ)ddPdQZ*ddTdUZ+ddXdYZ,dZd[ Z-dd]d^Z.dd`daZ/ddcddZ0ddedfZ1ddgdhZ2ddidjZ3ddkdlZ4ddmdnZ5ddodpZ6ddrdsZ7ddtduZ8ddwdxZ9ddzd{Z:dd}d~Z;dd Z<dddZ=dddZ>dddZ?dd Z@dddZAdd ZBdddZCdd ZDdd ZEdddZFdddZGdd ZHdd ZIdddZJdd ZKdddZLdddZMdddZNdddZOdddZPdddZQdddZRdddZSdddZTdddZUdddZVdddZWdddZXdd ZYdddZZdddZ[dddĄZ\dddƄZ]dddȄZ^dddʄZ_ddd̄Z`dddτZadddфZbdddӄZcdddՄZddddׄZedddلZfdddۄZgdddބZhdddZidd Zjdd ZkdddZldddZmdddZndddZodddZpdddZqdd Zrdd Zsdd ZtdddZudd Zvdd ZwdddZxdؐddZydd Zzdd Z{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d Zdېdd Zdܐd!d"Zdݐd$d%Zdސd'd(Zd)d* Zdߐd,d-Zdd0d1Zdd2d3Zdd5d6Zdd7d8Zdd:d;Zdd<d=Zdd>d?Zdd@dAZddBdCZdg ddfdDdEZddFdGZddKdLZddMdNZdOdP ZddRdSZddTdUZddVdWZddXdYZddZd[Zdd\d]ZeeZd^d_ Zd`da ZddddeZddfdgZdhdi ZddldmZddodpZdqdr ZddsdtZdudv Zdwdx ZddydzZdd{d|Zdd}d~Zdd Zdd Zdd Zdd ZdddZdddZejdfddZdddZdddZdddZdS (  r#   z
  Extension of the set class with addition of data and (optional) sigmas
  flex arrays, plus an optional array_info object and an optional flag for
  the observation type (amplitude, intensity, or reconstructed amplitude).
  Nc             C   s(   t | | || _|| _d | _d | _d S )N)r:   r   _data_sigmas_info_observation_type)r4   r6   r   r   r%   r%   r&   r*   4  s
    zarray.__init__c             C   s0   t | | |j| _|j| _|j| _|j| _d S )N)r:   r   r  r  r  r  )r4   r   r%   r%   r&   r   ;  s
    zarray._copy_constructorc             C   s
   || _ | S )N)r  )r4   infor%   r%   r&   set_infoB  s    zarray.set_infoc             C   s@   ddl m} t|tr| }|d ks6t||js6t|| _| S )Nr   )observation_types)
cctbx.xrayr  r   r#   observation_typeanyr!   r  )r4   r  r  r%   r%   r&   r3  H  s    
zarray.set_observation_typec             C   s   ddl m} | | S )z1
    Flag the array as X-ray amplitudes (F).
    r   )r  )r  r  r3  	amplitude)r4   r  r%   r%   r&   #set_observation_type_xray_amplitudeP  s    z)array.set_observation_type_xray_amplitudec             C   s   ddl m} | | S )z2
    Flag the array as X-ray intensities (I).
    r   )r  )r  r  r3  	intensity)r4   r  r%   r%   r&   #set_observation_type_xray_intensityW  s    z)array.set_observation_type_xray_intensityc             C   s   | j S )N)r  )r4   r%   r%   r&   r   ^  s    z
array.datac             C   s   | j S )N)r  )r4   r%   r%   r&   r   a  s    zarray.sigmasc             C   s*   |d k	r |  |    ks t|| _d S )N)r.   r+   r!   r  )r4   r   r%   r%   r&   
set_sigmasd  s    zarray.set_sigmasc             c   s\   |   d k	r6xJt|  |  |   D ]
}|V  q&W n"x t|  |  D ]
}|V  qJW d S )N)r   r   r+   r   )r4   itemr%   r%   r&   __iter__i  s
    zarray.__iter__c             C   s   | j S )zB
    Return the associated info object, or None if undefined.
    )r  )r4   r%   r%   r&   r  q  s    z
array.infor?   c             C   sT   t j| ||d |  d k	rPt|  trP|  j}|d k	rPt|d|  |d | S )N)r   r   zWavelength: %.4f)r}   )r:   r   r  r   r  rr   rA   )r4   r   r   rr   r%   r%   r&   r   w  s    
z array.show_comprehensive_summaryc             C   s   | j S )z
    Return the (experimental) data type, if defined.  See the module
    cctbx.xray.observation_types for details.

    :returns: an object from cctbx.xray.observation_types
    )r  )r4   r%   r%   r&   r    s    zarray.observation_typec             C   sn   |   d k	st|  d k	s t|   |    ks<t|  d k	rd|   |    ksdtt| S )N)r+   r!   r   r.   r   r:   )r4   r%   r%   r&   r.     s    z
array.sizec             C   s   t |  tjS )N)r   r   r   
std_string)r4   r%   r%   r&   is_string_array  s    zarray.is_string_arrayc             C   s   t |  tjS )N)r   r   r   r6  )r4   r%   r%   r&   is_bool_array  s    zarray.is_bool_arrayc             C   s0   t |  tjp.t |  tjp.t |  tjS )N)r   r   r   r   longrn  )r4   r%   r%   r&   is_integer_array  s    zarray.is_integer_arrayc             C   s    t |  tjpt |  tjS )N)r   r   r   rg  rN  )r4   r%   r%   r&   r     s    zarray.is_real_arrayc             C   s   t |  tjS )N)r   r   r   r  )r4   r%   r%   r&   is_complex_array  s    zarray.is_complex_arrayc             C   s   t |  tjS )N)r   r   r   hendrickson_lattman)r4   r%   r%   r&   is_hendrickson_lattman_array  s    z"array.is_hendrickson_lattman_arrayc             C   s   ddl m} t|  |jS )Nr   )r  )r  r  r   r  r  )r4   r  r%   r%   r&   r     s    zarray.is_xray_amplitude_arrayc             C   s   ddl m} t|  |jS )Nr   )r  )r  r  r   r  Zreconstructed_amplitude)r4   r  r%   r%   r&   %is_xray_reconstructed_amplitude_array  s    z+array.is_xray_reconstructed_amplitude_arrayc             C   s   ddl m} t|  |jS )Nr   )r  )r  r  r   r  r  )r4   r  r%   r%   r&   r     s    zarray.is_xray_intensity_arrayc             C   s   |   p|  S )N)r   r   )r4   r%   r%   r&   is_xray_data_array  s    zarray.is_xray_data_arrayc             C   s&   t | |  |  d|  | S )zI
    Create a new array object using references to internal objects.
    )r6   r   r   )r#   r   r   r  r  r3  )r4   r%   r%   r&   r     s    
z
array.copyc             C   s\   d}d}|   dk	r |    }|  dk	r8|   }tt| ||d|  | S )zG
    Clone the array, making copies of all internal array objects.
    N)r6   r   r   )r   r   r   r#   r:   r  r  r3  )r4   ri   r   r%   r%   r&   r     s      
zarray.deep_copyc             C   s|   |t kr| }|t kr|  }|t kr,|  }|
t kr<|  }
|	t krL|  }	tj||||||d}t|||d|		|
S )N)r8   r+   r-   r7   r,   )r6   r   r   )
r   r   r   r  r  r:   r   r#   r3  r  )r4   r6   r   r   r8   r+   r-   r7   r,   r  r  r%   r%   r&   r     s$         zarray.customized_copyTc             C   s   |   |  gd dkrV|  j| |dj|  | |   |  dS |  j| |dj|  | dS d S )Nr   )r   r@  )r   r   )r   )r   r   r:   r  r#   r   )r4   r   r@  r%   r%   r&   r    s    zarray.concatenatec             C   s   t j| |||||dS )zA
    Return the basic cctbx.miller.set object for the array.
    )r8   r+   r-   r7   r,   )r:   r   )r4   r8   r+   r-   r7   r,   r%   r%   r&   r:     s    	z	array.setc             C   s   t j| ddS )z4
    Create a copy of the array without sigmas.
    N)r   )r#   r   )r4   r%   r%   r&   discard_sigmas	  s    zarray.discard_sigmasc             C   s$   |   sttj| t|  dS )N)r   )r"  r!   r#   r   r   conjr   )r4   r%   r%   r&   	conjugate	  s    zarray.conjugatec             C   s   |   }| }| }|jdd}| sH| }| }|jdd}| }| sv|j|	 |
 dd|}|	 dk}|ds|| }| }|dk	r| dk}||
 dkM }||}| r|
 dk}||}||S )	z|
    A series of conversions that are required for many downstream tests, such as
    refinement, map calculation, etc.
    T)r  )r5  N)r+   r   r   )r   r   r   Fr   )r   r  eliminate_sys_absentr   r   r2  r#   r)  sigmas_are_sensibler+   r   r3  r*  r   r   r   r  )r4   r{   r  r5  r   r   r   Zselection_positiver%   r%   r&   
regularize	  s4    


zarray.regularizec             C   s   | j |   dS )zz
    Create a copy of the array with the data converted to a flex.double type.
    Will fail for incompatible arrays.
    )r   )r#   r   rR  )r4   r%   r%   r&   rR  /	  s    zarray.as_doublec             C   s*   t t| |t|  |t|  |dS )N)r6   r   r   )r#   r:   r"   r'   r   r   )r4   r$   r%   r%   r&   r"   6	  s    
zarray.__getitem__c             C   s   |d krt j}t|d| jj  |  |d t|d |  |d t|d t|  |d t|d t| 	 |d t
j| ||d | S )NzMiller %s info:)r}   zObservation type:zType of data:zType of sigmas:)r   r   )r~   r   rA   r	  r   r  r  r  r   r   r:   r   )r4   r   r   r%   r%   r&   r   <	  s     zarray.show_summaryc             C   s   t |  tjst|   }t|}t|}dt| 	   d }d| t
| |  }| jtj|| || ddS )Ng      ?g      @rT   )ab)r   )r   r   r   r  r!   rx  sincosr  r   r  r   r#  )r4   Zk_blurZb_blurrx  Z
sin_phasesZ
cos_phasesr  tr%   r%   r&   make_up_hl_coeffsF	  s    

zarray.make_up_hl_coeffsrX  c             C   s   |  st|   st|  d k	s(t|  | ks<tt||  }| }|}| }t| |  |  }| t	|  }tj
|ddd | }||}||}||}	||}| }
|  }t|
|||	||dS )NT)rK  )r+   fo_sqfc_sqdelta_f_sq_over_sigmafc_over_fc_maxr   )r   r!   r   r.   r  as_amplitude_arrayr   r   r   r\   rM  r   r+   r   r   )r4   	f_calc_sqn_reflectionsZfo2fc2fcZ
delta_f_sqr6  permr5  r+   r   r%   r%   r&   disagreeable_reflectionsP	  s.    



zarray.disagreeable_reflectionsc          	   C   s   |d krt j}| j||d}td|d xnt|j D ]\}td|j|  d|d td|j | |j	 | |j
| |j| |j| f |d q8W |S )N)r9  zR  h   k   l       Fo^2      Fc^2   |Fo^2-Fc^2|/sig(F^2)   Fc/max(Fc)  d spacing(A))r}   z%3i %3i %3irU   )endr}   z1 %9.2f %9.2f        %9.2f         %9.2f     %9.2f)r~   r   r=  rA   r   r3  r.   r+   r   r4  r5  r6  r   )r4   r8  r9  r   r{   r   r%   r%   r&   show_disagreeable_reflectionsi	  s      z#array.show_disagreeable_reflections{Gz?      @c             C   s   t | |||dS )N)miller_array#unit_cell_relative_length_tolerance"unit_cell_absolute_angle_toleranceworking_point_group)6crystal_symmetry_is_compatible_with_symmetry_from_file)r4   rC  rD  rE  r%   r%   r&   rF  u	  s
    z<array.crystal_symmetry_is_compatible_with_symmetry_from_file      ?ư>c             C   sb   d }|   d k	r^|    dkr^d}|   |kd}|    }t|t| }||kr^d}|S )Nr   TF)r   r.   r   rg  )r4   Zcritical_ratior   r{   Z	suspectedallratior%   r%   r&   r+  	  s    zarray.sigmas_are_sensiblec             C   s&   |   d kr| S | |   dkS d S )Nr   )r   r   )r4   r%   r%   r&   enforce_positive_sigmas	  s    zarray.enforce_positive_sigmas      c             C   s   |   st|  dk	st|  s(t| |  dk} |  |   }| ||k} t|  |   d|   |    }t|  | d }d||  |  d|  |  |     }td| }| j||d	| 
 }|S )a  
    Takes in an intensity array (including negatives) and spits out amplitudes.
    The basic assumption is that
    P(Itrue) \propto exp(-(Itrue-Iobs)**2/(2*s))
    where Itrue>=0 (positivity constraint on error free amplitudes).
    For amplitudes, this results in
    P(Ftrue) \propto 2 Ftrue exp( -(Ftrue**2-Iobs)**2/(2s) )
    A Gaussian approximation is fitted to the Mode of this distribution.
    An analytical solution exists and is implemented below.
    This method does not require any Wilson statistics assumptions.
    Nr   g       @g      ?g      @)r   r   )r   r!   r   r+  r   r   r   r;  r   r3  r7  )r4   Zi_sig_levelZi_sigidetZf_saddleZs_saddler{   r%   r%   r&   enforce_positive_amplitudes	  s    *z!array.enforce_positive_amplitudesxtal_3_7c             C   s   ddl m} |  dks$|  s$t|j|jd}||}|dkrptdt	| d d
dd	 | D  |  dkrt| ||  j}n$||  |  |}t| |j|j}|  r|  |S )
z
    Given an intensity/F^2 array (or undefined observation type), return the
    equivalent amplitudes.  Note that negative intensities will be discarded;
    for French-Wilson treatment, call the separate array.french_wilson()
    method.
    r   )r  N)rO  ZcrystalszUnknown f_sq_as_f algorithm=%s
z  Possible choices are: z, c             S   s   g | ]}t |qS r%   )r   )ro   r   r%   r%   r&   rq   	  s    z#array.f_sq_as_f.<locals>.<listcomp>)r  r  r  r   r!   Zarray_f_sq_as_f_xtal_3_7Zarray_f_sq_as_f_crystalsgetRuntimeErrorr   rb   keysr   r#   r   r   Zsigma_fr  )r4   r  r  r  
converters	converterr{   rr%   r%   r&   	f_sq_as_f	  s    

*zarray.f_sq_as_fsimplec       	   	   C   s  |dkst ddlm} |  dks0|  s0t |  dkrTt| ||  j	}n|dkr||  |  }t| |j	|j
}ntt }t }xTt|  |  D ]>\}}||d  |dtd| ttdt||  qW t| ||d}|  r|  |S )	zP
    Convert amplitudes (and associated sigmas, if present) to intensities.
    )rW  Zshelxlr   )r  NrW  rT   g{Gz?)r6   r   r   )r!   r  r  r  r   r   r#   Zarray_f_as_f_sqr   f_sqZ
sigma_f_sqr   rN  r   rE   r\   r   r  )	r4   r  r  r{   rU  rX  Zs_sqr   r   r%   r%   r&   	f_as_f_sq	  s"    ,
zarray.f_as_f_sqc             C   sL   |   r(t| t|  |  d S |  s4t| 	 rH| j
|dS | S )z
    Convert the array to simple amplitudes if not already in that format.
    Only valid for complex (i.e. F,PHI), intensity, or amplitude arrays.
    )r6   r   r   )r  )r"  r#   r   r   r   r   r  r   r!   r   rV  )r4   r  r%   r%   r&   r7  	  s    zarray.as_amplitude_arrayc             C   s<   |   r|  j|dS |  s$t|  s8| j|dS | S )z
    Convert the array to intensities if not already in that format.  Only valid
    for complex (F,PHI), amplitude, or intensity arrays.
    )r  )r"  r7  rY  r   r!   r   )r4   r  r%   r%   r&   as_intensity_array	  s    zarray.as_intensity_arrayc       
      C   s   |   s|  st|    dks,tddlm} |   rr|  }| j	dd}|j
|dd}|j|dd}nF|dk	s~t|rd}nd	}||   || }	t| |  |	 }|S )
as  
    Adjust a complex array (map coefficients) or phase array
     corresponding to a shift of all coordinates by
     new_xyz_frac = old_xyz_frac + shift_frac.

    If a phase array, must specify whether it is in degrees.
    Only makes sense in P1

    F'=exp( i 2 pi h.(x+shift_frac)) -> F' = F exp ( i 2 pi h.shift_frac)
    phase_shift = 2 * pi * h . shift_frac
    )r   r>   r   )r   F)rs   )phase_sourcers   Ng     v@gn!@)r"  r   r!   r   r   numberr   r   
amplitudesrx  translational_shiftphase_transferr+   r   dotr#   r   )
r4   Z
shift_fracrs   r   r]  Z
phases_radZnew_phases_radr{   cZphase_shiftr%   r%   r&   r^  	  s"    zarray.translational_shiftc             C   s   |    }|   }|  s(|  rDt|   |  || n>|dkrft|   |  | nt|   |  ||| t	t
| ||  ||  | S )z
    Convert all indices to lie within the canonical asymmetric unit for the
    current space group (while preserving anomalous flag).  Required for many
    downstream steps.
    N)r+   r   r   r"  r$  r)  r,   r   r-   r#   r:   r   r3  )r4   rs   r   ri   r%   r%   r&   r)  '
  s$    




zarray.map_to_asuc             C   s   |r|  |st|   |  ks.t|  | ksBtt| |   }|  || stt| 	 }| 
 }|d k	r||}|d k	r||}t|||d| S )N)r6   r   r   )r>  r!   r+   r.   r-   r?  permutationr   r*  r   r   r#   r3  )r4   r   r@  r  ri   r   r%   r%   r&   	adopt_setA
  s     
 
zarray.adopt_setc             C   sV  |    |   kst|  d k	rP|   |   ksDt|d k	sPt|j| |d }t||   jr| | kst|	 }n|   |  |}|
|d|   |d |  d krd }nlt||  jr| | kst|	 }n|  |  |}|
|d|  |d |j||dS )N)r   r@  r   r>   )r   r   )r   r.   r+   r!   r   r?  r   r   r	  r   rO  rA  r   r#   )r4   r   Zdata_substituteZsigmas_substituter@  r   r   r   r%   r%   r&   matching_setO
  s0    

zarray.matching_setFc       
      C   s   |  |\}}|r,dt|   d }t| t|  }}d}|rtjjt	|||d}dt|   d }|j
t| |j  }n(t|| }	|	dkrt|| |	 }|j| | dS )Ng      ?g      @r>   )xyzr   )r   )rD  r   r  r   r   r   scitbxry  gaussian_fit_1d_analyticalr;  r-  r  r.  sumr   )
r4   r   Zresolution_dependentr   or  scale_factorrU  Zss_otherdenr%   r%   r&   r   p
  s     zarray.scalec             C   s   | | }}|r|j |d}|rdt| tjs2t||\}}|j|d}||\}}	|	|}|
|}
| 	|
 }| 	|
 }d }| d k	r| 	|
 }| j|||dS )N)r   )r[  )r   r+   r   )r   r   r   r   r  r!   rD  r_  rG  r  rF  r+   r   r   )r4   r   r   Zreplace_phasesr   rk  Zs_cZc_oZs_lZc_lZolZd_newZi_newZ
sigmas_newr%   r%   r&   complete_with
  s     
 

zarray.complete_withr>   c             C   s  |   |  kst|  d ks$t| j|d\}}| j|d\}}|}	|rtt| t|  }
|
dkrtt| t|  |
 }	| | |	  }|	| |  |	| |	 |  |
 }|	|
  |	|
  t|  ||   d}|j|dS )N)r   r   )r8   r+   r-   )r   )r-   r!   r   rD  rG  r   rj  r   r   rp  r+   r:   r8   r#   )r4   r   r   Zscale_for_lonesscale_for_matchesZf1_cZf2_cZf1_lZf2_lscale_k1rm  result_dataZresult_indicesr  r%   r%   r&   combine
  s(    "&zarray.combiner   c             C   s   | j |||d}t|  | }|  }|  }	|	d k	rB|	 }	|  }
|
d k	rZ|
 }
|d}| }|dkr~| }nL|| 	|}|	d k	r|	
|	 | | |
d k	r|

|
 | | | j||	|
dS )N)rK   r/   r   r>   r   )r+   r   r   )rL   r?  r+   r   r   r   rE  r.   r  r   resizer   )r4   rK   r/   r   Znew_data_valueZnew_sigmas_valuecsr   r   ri   r   r  rg   r%   r%   r&   complete_array
  s(      

  zarray.complete_arrayrH  c             C   s   |dkst |dkr&tj| ||d}np|dkrFtj|  | dd}nP|dkrltjt|  | dd}n*t|trtd| ntj|| dd}|S )	aH  
    Generate the selection array (flex.size_t object) to reorder the array
    by resolution, Miller index, data values, or absolute data values.

    :param by_value: sort type, must be "resolution", "packed_indices", "data",
                     or "abs"
    :param reverse: invert order
    :returns: flex.size_t object
    )FT)rH  rI  rJ  )rS  rK  r   T)r   rK  rL  r   zUnknown: by_value=%s)	r!   r:   rM  r   r   r   r   r^   
ValueError)r4   rS  rK  r{   r%   r%   r&   rM  
  s    

zarray.sort_permutationc             C   s4   |   }|  rt|   }tt| ||  S )N)r   r"  r   r   r#   r:   r  r   )r4   r   r%   r%   r&   r  
  s    zarray.patterson_symmetryc       	      C   s  |   dk	st|  dk	s t|  dk	s0t|  dk	s@td}d}ttd|  jj	d}|dk	r|dksvt| 
 dkst||  |  |  |  d}|j}n|dk	r|dkst| 
 dkstt|  tjstt|  |  |  |  |d}|j}nJ|dks t|  }|  |j}| 
 dk	rV| 
 |j}|j}t|  |j|  dj||d| }|r|dk	st||fS |S )z-
    Generate the equivalent P1 dataset.
    N)r  r#  )r   r-   r+   r   )FT)r   r-   r+   r   rs   )r8   r+   r-   )r   r   )r,   r!   r+   r-   r   Zexpand_to_p1_complexZ expand_to_p1_hendrickson_lattmanrP  r	  r   r   r   r   r   rN  Zexpand_to_p1_phasesr  r   rP  r:   r  r#   r3  )	r4   Z	phase_degr  Z	p1_sigmasrP  Zexpand_typep1Zp1_datar{   r%   r%   r&   r   
  sZ    
zarray.expand_to_p1c             C   s.  t |trt|}|dks$|dkrJ|  s0tt||  |  |d}n| 	 rjt
||  |  d}n`|  s|  s|  rt||  |   d}n(|  rt||  |  d}ntdd }|  d k	rt |  tjst|   }tttj| ||j|  d|j|d|  S )	NFT)r  
indices_indata_inrs   )r  rx  ry  )r+   r   z#Unsupported miller.array data type.)r8   r+   r-   )r6   r   r   )r   r^   r   r}  r   r!   Zchange_basis_phases_doubler+   r   r"  Zchange_basis_complex_doubler  r!  r   r~  r   r$  Z change_basis_hendrickson_lattmanrQ  r   r   rN  r#   r:   r	   r;   ri  r-   r3  r  )r4   r  rs   r{   Zresult_sigmasr%   r%   r&   ri    sJ    
 


zarray.change_basisc             C   s   |   st| j| ||d\}}| | ks8t| |  }}|t| }t|}t	t
|d}dtjd  t|| S )z The factor phi_{sym} quantifying whether complex structure factors
    are invariant under the given symmetry operator, as used in Superflip.
    Ref: J. Appl. Cryst. (2008). 41, 975-984
    )r@  rT   r  )r"  r!   rD  ri  r.   r   r   r(  r   r   argry  rz  mean_weighted)r4   opr@  r   Zop_fZcc_sfweightsr  r%   r%   r&   symmetry_agreement_factor@  s    
zarray.symmetry_agreement_factorc             C   s   |  st|  | s"t|  | ks6t|   rZt| ||   |  dS t| ||   t|  dj	|dS d S )N)r6   r   )r[  )
r"  r!   r+   r*  r-   r#   r   r   r   r_  )r4   r  r  r%   r%   r&   r  R  s    zarray.f_obs_minus_f_calc绽|=c             C   s<  |   dk	stt|dr"|  }t|   tjsFt|   tjsFtt|tjsnt|tjsnt|tjsntt|tjr|dkrt }n
t|d}|| 	 | 
 |d}t|   tjr|   }nt|   }| 	 dk	stt|tjrt| t| 	 | 
 ||||  dS t| t| 	 | 
 ||||  dS )a2  Combines phases of phase_source with self's data if real (keeping
    the sign of self's data) or with self's amplitudes if complex.

    Centric reflections are forced to be compatible with the phase restrictions.

    phase_source can be a miller.array or a plain flex array.

    epsilon is only used when phase_source is a complex array. If both the
    real and the imaginary part of phase_source[i] < epsilon the phase is
    assumed to be 0.

    deg is only used if phase_source is an array of doubles.
    deg=True indicates that the phases are given in degrees,
    deg=False indicates phases are given in radians.

    phase_integrator_n_steps is only used if phase_source is an
    array of Hendrickson-Lattman coefficients. The centroid
    phases are determined on the fly using the given step size.
    Nr   )n_steps)r   r<    hendrickson_lattman_coefficients)r6   r   r   )r   r!   r  r   r   r  rN  r#  phase_integratorr   r+   r   r#   r_  r   )r4   r[  r   rs   Zphase_integrator_n_steps
integratorr   r%   r%   r&   r_  `  sN    


zarray.phase_transferc             C   s&   dt j t|    }| |S )NrT   )ry  rz  r   ro  r   r.   r_  )r4   r{  r%   r%   r&   randomize_phases  s    zarray.randomize_phasesc             C   sd   |   st|d ks |d ks t|d krB|d kr8t }n
t|d}t| ||  |  |  ddS )N)r  )r   r<   r  )r6   r   )r$  r!   r  r#   r   r+   r   )r4   r  r  r%   r%   r&   phase_integrals  s    
zarray.phase_integralsc             C   s   |   d k	stt|tr>t| |  dks6t|  }t|   }t|tjsht|tj	shtt|tjrt|}n|}t
jj||d}t|   }t|}|dkstt|| }|| d tj S )Nr   )phi1phi2   )r   r!   r   r#   r   orderr+   rz  r  rN  rh  ry  phase_errorr   rj  rz  )r4   r[  rw  p2er   Zsum_wZsum_wer%   r%   r&   mean_weighted_phase_error  s    

zarray.mean_weighted_phase_errorc             C   s   |   d k	stt|tr>t| |  dks6t|  }t|   }t|tjsht|tj	shtt|tjrt|}n|}t
tjj||d}|d tj S )Nr   )r  r  r  )r   r!   r   r#   r   r  r+   rz  r  rN  meanrh  ry  r  rz  )r4   r[  rw  r  r  r%   r%   r&   mean_phase_error  s    
zarray.mean_phase_errorc             C   sh   |   st|dkr(t|   d}ddl}|dkrD|dd}tj	| 
 ||||d}| j|dS )z*
    Add random error to reflections.
    NTr   i@B )r   r   amplitude_errorphase_error_degrandom_seed)r   )r"  r!   r   r6  r+   r.   randomrandintr)   randomize_amplitude_and_phaser   r   )r4   r  r  r   r  r  new_datar%   r%   r&   r    s      z#array.randomize_amplitude_and_phasec             C   sx   |   dk	st| }|r | }| \}}|d}||  }d}| dk	rb|| }tt	||dd||S )zm
    Returns an array object with DANO (i.e. F(+) - F(-)) as data, and
    optionally SIGDANO as sigmas.
    Nrv  F)r-   )
r   r!   rK  r   Zmiller_indices_in_hemisphereZminusr   additive_sigmasr#   r:   )r4   rK  	tmp_arrayr   r   r   ri   r   r%   r%   r&   anomalous_differences  s    
zarray.anomalous_differencesc             C   sJ   |dkst |  d k	st |  \}}d|}|j| |ddS )N)rv  rX   z+-F)r   r-   )r!   r   r   r  r   r   rA  )r4   Zplus_or_minusr   r   i_columnr%   r%   r&   hemisphere_acentrics  s    
zarray.hemisphere_acentricsc                s4   |   d k	st|  \ t fdddD S )Nc                s$   g | ]} j  |d dqS )F)r   r-   )r   r   rA  )ro   r  )r   r   r%   r&   rq     s   z/array.hemispheres_acentrics.<locals>.<listcomp>)r   r>   )r   r!   r   rt   )r4   r%   )r   r   r&   hemispheres_acentrics  s
    zarray.hemispheres_acentricsc             C   s   |   r|  st|s|  }|r4|j|||d}|  }|ddkrRdS || }|	 }	| 
 }
t|
	 |	 dS |  dk	stg }xT|   D ]D}|  |}| |}|  |\}}||j|||d qW t|  |ddS )	z
    Return the percent of acentric reflections with both h,k,l and -h,-k,-l
    observed (only meaningful for amplitude and intensity arrays).  By default
    this is calculated relative to the complete set.
    )r   r/   rK   Fr   g      ?N)r   r/   relative_to_complete_setz%5.3f)r(   r   r   )r-   r   r!   rk  rL   r   r   r   r   r.   r  r  r(   rD   r   ra   rE   r   r   )r4   r   rK   r   r/   r  r5  r   Zmerged_acentricZ
n_acentricZ
anom_diffsresultsrB   r   Z	array_selZ	d_max_binZ	d_min_binr%   r%   r&   r     s.    
zarray.anomalous_completenessc             C   s   |   s| S |  }|  dk	rf| }|   }|d}|dkrT| j| d}|  d}|  dk	r|  r|r|	 \}}|
  }	| | }
|
dkr|	d |
 |k r|   }| | } | S )z
    Convert anomalous array into nonanomalous if the number of Bijvoet pairs is
    too small compared to the number of lone Bijvoet mates.
    NTr   )r   g      ?)r-   r   r,   r   r   r   r   r   r   r   r   r.   r   r1  r2  r#   r3  )r4   	thresholdr   r   r   r   r   r   r   r   Zn_lone_matesr5  r%   r%   r&   6convert_to_non_anomalous_if_ratio_pairs_lone_less_than&  s(     
z<array.convert_to_non_anomalous_if_ratio_pairs_lone_less_thanc       
      C   s,  |r|   dk	st|s| |  dk}|  r:| }| \}}|  |  ksbt|  dkrvdS t	t
| |  }|dkstt	t
| t
|  }|dksttd| | S g }x6|    D ]&}|   |}	|| |	  qW t|   |ddS )a  Get the anomalous signal according to this formula:

    .. math::
       \sqrt{\dfrac{<||F(+)|-|F(-)||^2>}{\frac{1}{2} (<|F(+)|>^2 + <|F(-)|>^2)}}

    :param use_binning: If 'True' the anomalous signal will be calculated for     each bin of the data set individually
    :type use_binning: boolean
    :returns: the anomalous signal
    :rtype: float or cctbx.miller.binned_data
    Nr   rT   z%7.4f)r(   r   r   )r(   r!   r   r   r   rV  r  r.   r   r  r  ry  r;  rD   r   rE   r   r   )
r4   r   obsZf_plusZf_minusZmean_sq_diffZmean_sum_sqr  rB   r   r%   r%   r&   r   ?  s(     zarray.anomalous_signalc       	      C   s   |   st|  st|  }| s6td d d |S | |  }t	|}|
|}t }|| }|d k	rt||k }|
|}|
|}t||}| rt| | | |S td d d |S )N)r   r!   r-   r  r.   r   r   r   r   rM  r   r   normal_distribution	quantilesr   linear_regressionis_well_definedr   y_intercept)	r4   r   ZdIrf  r<  distributionre  r   fitr%   r%   r&   anomalous_probability_plot_  s$    



z array.anomalous_probability_plotc             C   sF  ||g ddkst|  r>tdd}||  |  |  }|r|   }t	
td| }|| d}t	
td| }||d}|| }|s|rt	|S | j|d}|S nz|  dk	stg }	xR|   D ]B}
|  |
}||}d}| dkrt	|}|	| qW t|  |	d	d
S ndS dS )aT  Get phase entropy as measured in terms of an base-360 entropy
    (base-2 for centrics).

    An entropy of 0, indicates that the phase uncertainity is as low as possible
    An entropy of 1 however, indicates that the uncertainty is maximal:
    all phases are equally likely!

    :param return_binned_data: if 'True' you receive a binned object rather     then a raw array
    :type return_binned_data: boolean
    :param exponentiate: whether or not to exponentiate the entropy. This will     return a phase uncertainty in degrees (or the 'alphabet size')
    :type exponentiate: boolean
    TrT   ih  )r  g       @r   )r   Nz%7.4f)r(   r   r   )r   r!   r$  phase_entropyZrelative_entropyr   r+   r   r   r   r  ry  r  rO  r  r#   r(   rD   r   r   r.   rE   r   )r4   ZexponentiateZreturn_binned_dataZreturn_meanr  r{   r   ZcenZacenZbinned_resultsrB   r   Zsel_datar  r%   r%   r&   r  w  s6    




zarray.phase_entropyc             C   s  |   st|r |  dk	s t|  dk	s0tt|}|s| |  dk}|  r`| }| 	 dkrt|S |
 \}}| 	 | 	 kstt| |  }t| |  | |   }t|dk }	||	d}|| }
| t| dk d}| | }| t| dk d}| | }|
|k||k@ ||k@ d}|
	 dkr||
	  S |S g }x>|   D ].}|  |}|| |j||d qW t|  |ddS )zFraction of reflections for which
    (:math:`\dfrac{|\Delta I|}{\sigma_{dI}}` > cutoff and
    :math:`min(\dfrac{I_{+}}{\sigma_{+}},\dfrac{I_{-}}{\sigma_{-}})` > cutoff
    Nr   r>   T)cutoffr/  z%7.4f)r(   r   r   )r-   r!   r(   r   rg  r   r   r   rY  r.   r  r   fabsr;  r6  rP  rO  r   rD   r   rE   measurabilityr   )r4   r   r  r/  r  i_plusi_minustopbottomzerosrJ  i_plus_sigmai_minus_sigmameasr  rB   r   r%   r%   r&   r    s>     &""zarray.measurabilityr  c             C   s  |   st| |  dk}|dkr8|  r8| }n|dkrP|  rP| }| \}}| 	 | 	 ksxt| |  d }t
| |  }|r|  d k	stt
| |  }	t
| |  | |   }
t
|
dk }|
|d}
|	|
 }| t
| dk d}
| |
 }| t
| dk d}
| |
 }||k||k@ ||k@ }||}||}|	 |	 kst|dk}||}||}|| S )Nr   r  r  rT   r>   )r-   r!   r   r   r   rV  r   rY  r  r.   r   r  r   r;  r6  rP  rO  )r4   Zobs_typeZmeasurable_onlyr  r  r  r  i_meand_anor  r  r  rJ  r  r  r  Znon_zero_seler%   r%   r&   bijvoet_ratios  s@    




zarray.bijvoet_ratiosc             C   s   |r|   dk	st|s\|   dkr,dS t|  d }|dkrJdS t|  | S g }x6|    D ]&}|   	|}|
| |  qnW t|   |ddS )z<data^2>/(<data>)^2Nr   rT   z%7.4f)r(   r   r   )r(   r!   r+   r.   r   r  r   mean_sqrD   r   rE   r   second_momentr   )r4   r   Zmean_data_sqr{   rB   r   r%   r%   r&   r    s      zarray.second_momentc             C   s   |r|   dk	std}|  r4|  }||  n| }|sn|  dkrPdS t|	 }|dkrjdS |S g }x6|  
 D ]&}|  |}|||  qW t|  |ddS )z<F^2>Nr   z%7.4f)r(   r   r   )r(   r!   r   rY  r4  r+   r.   r   r  r   rD   r   rE   r   r  r   )r4   r   r  Z	mean_datar{   rB   r   r%   r%   r&   r    s$      zarray.wilson_plotc             C   s   |r| j dk	st|s|   dkr*|S d}|  rR|  rF|  }|  rR| }|dk	r||	 dk}|  dkr|S t
| |	  }|S dS g }x:|    D ]*}|   |}|| |j|d qW t|   |ddS )z<I/sigma_I>Nr   )r/  z%7.4f)r(   r   r   )r(   r!   r+   r.   r   r   rY  r   r   r   r   r  r   rD   r   rE   i_over_sig_ir   )r4   r   r/  r  Zi_sig_ir{   rB   r   r%   r%   r&   r    s0      zarray.i_over_sig_ic             C   s   |r| j dk	st|s|   dkr*|S d}|  rR|  rF|  }|  rR| }|dk	r|t	|
 | 
   }|S |S g }x:|    D ]*}|   |}|| |j|d qW t|   |ddS )z <I/epsilon> Nr   )r/  z%7.4f)r(   r   r   )r(   r!   r+   r.   r   r   rY  r   r   r  r   r   rR  rD   r   rE   r   $mean_of_intensity_divided_by_epsilonr   )r4   r   r/  r  weighted_meanr{   rB   r   r%   r%   r&   r  3  s.     
z*array.mean_of_intensity_divided_by_epsilonc             C   s   |r| j dk	st|sL|   dkr*|S t|  |     }|S g }x:|   	 D ]*}|   
|}|| |j|d q^W t|   |ddS )z <sigma^2/epsilon> Nr   )r/  z%7.4f)r(   r   r   )r(   r!   r   r.   r   r  r   r   rR  rD   r   rE   r   (mean_of_squared_sigma_divided_by_epsilonr   )r4   r   r/  r  r{   rB   r   r%   r%   r&   r  O  s     
z.array.mean_of_squared_sigma_divided_by_epsilonc             C   s0   |   r| }n|  }|r$||  |j|dS )z7<I^2>/(<I>)^2 (2.0 for untwinned, 1.5 for twinned data))r   )r   rY  r  r  )r4   r   r-  r%   r%   r&   second_moment_of_intensitiesd  s    
z"array.second_moment_of_intensitiesc             C   s   |   s| }n|  }|r$||  |j|d}|dkr<dS |sHd| S g }x8|jD ].}|dksh|dkrt|d qT|d|  qTW t| |ddS )z;(<F>)^2/<F^2> (0.785 for untwinned, 0.885 for twinned data))r   Nr>   r   z%7.4f)r(   r   r   )r   rV  r  r  r   rE   r   r(   )r4   r   r-  r  r{   Zsmr%   r%   r&   wilson_ration  s     
   zarray.wilson_ratio
   usedc             C   s  |   st|dkstt|d |d |d k	r>| j|d n|  d k	sNtg }g }d }xt|  d|  D ]}|  |}	|  |	}
|
	d}|

 | }|| || |  |}|d kr&tdtt|  
 }d| }t|d	 d	t| |d
 |d d|d d| }t|d	 ||| || dd| td||   |d qrW |  	d}|  
 | }t|d	 dt| d || || dd| td||   |d ||fS )N)r  rI  z.Number of work/free reflections by resolution:)r}   )r   Zrange_TrV   z%%%dsrU   workfreez %freez%%%ddz%5.1f%%g      Y@r>   Zoverall)r  r!   rA   r   r(   getattrr   r   r   r   r.   rE   r|   r\   r]   r^   r+   )r4   r   Zbinner_ranger   r   Zn_worksZn_freesr   rB   r   flagsZn_freeZn_workr   widthr%   r%   r&   show_r_free_flags_info  s>    



$ zarray.show_r_free_flags_infoc             C   s   |   sttdd}tdd}|  }| }d}x<t|D ]0\}}|rB|d7 }||d  |||  qBW t	||dS )Nr>   r   )Zreflection_countsZfree_fractions)
r  r!   r   rn  rN  r   r.   r   rE   r   )r4   rcZffri   rg   ra  r   r   r%   r%   r&   r_free_flags_accumulation  s    zarray.r_free_flags_accumulationc             C   s  |r|   dk	st|  dks4|  s4|  s4t| dksT| sT| sTt|  |   kspt|s^|   dkrdS |r| | }}n| j|dd\}}t	
| }t	
| }|tkrt	|| }|dkr|t	|| | 9 }n|dk	r||9 }|r@dt	t	
||  t	||  S t	t	
|| t	| S g }	xD|    D ]4}
|   |
}|	| ||||| qpW t|   |	ddS )a  Get the R1 factor according to this formula

    .. math::
       R1 = \dfrac{\sum{||F| - k|F'||}}{\sum{|F|}}

    where F is self.data() and F' is other.data() and
    k is the factor to put F' on the same scale as F

    :param other: array object with the same observation type
    :param scale_factor: optional scale factor to be applied to 'other'; if
      Auto, will be determined automatically
    :param assume_index_matching: skips calling self.common_sets(other)
    :param use_binning: divide by resolution shells
    :param emulate_sftools: copies behavior of SFTOOLS in CCP4: instead of
      the denominator being sum(self.data()), it will be 0.5*sum(self.data()+
      other.data())
    :returns: a Python float (if use_binning=False), or a binned_data object
    Nr   T)r   rC  rT   z%7.4f)r(   r   r   )r(   r!   r  r"  r   r+   r.   r   rD  r   r   r   rj  rD   r   rE   r   	r1_factorr   )r4   r   rl  Zassume_index_matchingr   Zemulate_sftoolsrk  ra  rm  r  rB   r   r%   r%   r&   r    s:     


&zarray.r1_factorc             C   s   |   dk	st|dkr |  }|r*| }|   |}d}|  dk	rV|  |}d}|  dk	rt|  |}tt| ||||| S )a  
    Select a sub-array.

    :param selection: flex.bool or flex.size_t selection
    :param negate: select the inverse of the selection array
    :param anomalous_flag: anomalous flag for the new set
    :returns: a new array with a subset of indices and data/sigmas
    N)	r+   r!   r-   r   r   r   r#   r:   r3  )r4   r   r8  r-   r   ri   r   r%   r%   r&   r     s    	   zarray.selectc          
   C   s   |r4|  }t|   d| t|   |}nt|  |}y| j|d|dS  tk
r } z"dt	|kr~tdnt|W d d }~X Y nX d S )NTr   )r8  z<CCTBX_ASSERT(miller_indices_[1].size() == size_processed(1))z\cctbx.miller.array.select_indices(): This method can only be used reliably on a merged array)
r   r)  r   r   r?  r+   r   Zpair_selectionrQ  r^   )r4   r+   Zmap_indices_to_asur8  Zmatched_indicesr  r%   r%   r&   select_indices  s    
zarray.select_indicesc             C   sF   |   dk	st|  dk	s tt|   |  | k}| ||S )z
    Return a copy of the array filtered to remove reflections whose value is
    less than cutoff_factor*sigma (or the reverse, if negate=True).
    N)r   r!   r   r   r   r   )r4   cutoff_factorr8  r  r%   r%   r&   sigma_filter  s    zarray.sigma_filterc             C   sd   d }|   }|d k	r`| dkr`t|dkr4d}n,|d}|sJ|sJt|r`t|  | }|S )Nr   g        )r   r.   r   r  all_ner!   r   )r4   Zreturn_none_if_zero_sigmasr{   r   Zsigmas_all_not_equal_zeror%   r%   r&   min_f_over_sigma  s    
zarray.min_f_over_sigmac             C   s   ||g ddkst|  dk	s&td}|dk	r^tt|  }|dkrV|  S || }|  | }|  dk	r|  | }| j||d	| 
 | S )a2  
    Apply a scale factor to the data (and optionally sigmas).

    :param target_max: target maximum value for the scaled data - the scale
                       factor will be determined automatically
    :param factor: explicit scale factor
    :returns: custumozed copy with scaled data and sigmas
    Nr>   r   )r   r   )r   r!   r   r   r\   r   r   r   r   r  r  r3  )r4   Z
target_maxfactorr   Zcurrent_maxri   r%   r%   r&   apply_scaling$  s    	  
zarray.apply_scalingc       
      C   s*  |d kr|   }|   |  s*t| |s8t| j|d ||  t|    d}x| 	 
 D ]}| 	 |}| |}||}d}tt| t|  }	|	dkrtt| t|  |	 }||| qpW |dkd| kst|j| | dS )N)r   r   g      ?r   T)r   )r+   r.   r*  r!   r>  r   r4  r   rN  r(   r@   r   r   rj  r   r   rO  r   r#   )
r4   r   r   r   rB   r   f1f2Zscale_rm  r%   r%   r&   
multiscale:  s$    


"&zarray.multiscaler  c
          
   C   sT   | j ||||||||	d }
|  |
 }|  }|dk	rF|rF||
 }| j||dS )ai  
    Given an isotropic or anisotropic displacement or B-factor, apply
    resolution-dependent scale factors to the data (and optionally sigmas).

    :param u_iso: Isotropic displacement (in Angstroms)
    :param b_iso: Isotropic B-factor (8*pi^2*u_iso^2)
    :param u_cart: Anisotropic displacement tensor
    :param b_cart: Anisotropic B-factor
    :param u_star: Anisotropic displacement tensor in fractional space
    :param u_cif: Anisotropic displacement tensor, dimensionless basis
    :param apply_to_sigmas: Also scale sigma values (if present)
    :returns: cctbx.miller.array object with scaled data
    )r  r  r  r  r  r  r  r  N)r   r   )r   r   r   r   )r4   r  r  r  r  r  r  Zapply_to_sigmasr  r  Zdwsri   r   r%   r%   r&   apply_debye_waller_factorsN  s    z array.apply_debye_waller_factorsc       	      C   s  |dks|dkst |s|   dkr,d S |sb|sb|sFt|  S t|  |    S |svt|  }nt	|  |    }|rt
|S |S |  d k	st g }x>|   D ].}|  |}|| |j|||d qW t|  |dS )NFr   )use_multiplicitiessquaredrms)r(   r   )r!   r   r.   r   r  r{  r   rR  r  mean_sq_weightedry  r;  r(   rD   r   rE   r   r   )	r4   r   r  r  r  r{   r   rB   r   r%   r%   r&   r  p  s6      
z
array.meanc             C   s   | j ||ddS )NT)r   r  r  )r  )r4   r   r  r%   r%   r&   r    s    zarray.mean_sqc             C   sn   | j |||d}|s |  | S |   }x8|   D ](}|j| d k	r:|j|  || 9  < q:W |S d S )N)r   r  r  )r  r.   r(   countsr@   r   )r4   r   r  r  r  r  r   r%   r%   r&   rj    s    z	array.sumc             C   s   | j ||ddS )NT)r   r  r  )rj  )r4   r   r  r%   r%   r&   sum_sq  s    zarray.sum_sqc             C   s   | j ||ddS )NT)r   r  r  )r  )r4   r   r  r%   r%   r&   r    s    z	array.rmsc       	      C   s~   | j ||d}t|  }|s.||| k}nD|  }x:|   D ]*}||  | |||j|  kB M }qDW | ||S )N)r   r  )	r  r   r   r   r7  r(   r@   r   r   )	r4   r  r   r  r8  r  Zabs_datakeeprB   r%   r%   r&   
rms_filter  s    zarray.rms_filterr   c          
   C   s   |s$t |  |  |  |  }nvt }xl|   D ]\}|  	|}|
ddkrf|d q:|t |  |  |  ||  | q:W |S )NTr   )statistical_meanr   r-   r+   r   r   rN  r(   r@   r   r   rE   r   )r4   r   r{   rB   r   r%   r%   r&   r    s    zarray.statistical_meanc       
   	   C   s   |   d k	st|   |   ks,td}g }xp|    D ]`}|   |}|  |}||}|r|| | }t	||}|
||t	d|  f qBW dtd|  }	t|   ||	dS )Nr   r>   z%%%dd %%6.4fz%d)r(   r   r   )r(   r!   r   r.   r+   rD   r   r   r   r\   rE   r]   r   )
r4   Zdata_value_to_countZcount_not_equalZmax_nr  rB   r   Zdata_selrg   r   r%   r%   r&   count_and_fraction_in_bins  s    
 
 z array.count_and_fraction_in_binsc             C   s   |   d ks|  st| jdd}|   }xP|   D ]@}|  |}|	 dkr>|
||  |||d    q>W t| |S )NT)r   r   r>   )r  r   r!   r  r   r   r(   r@   rN   r.   rO  r   r#   )r4   Zs_meanrq  rB   r   r%   r%   r&   remove_patterson_origin_peak  s    "z"array.remove_patterson_origin_peakc             C   s>   |   d ks|  stt| |  t|     dS )N)r6   r   )	r  r   r!   r#   r   r   r;  r   rR  )r4   r%   r%   r&   quasi_normalized_as_normalized  s    z$array.quasi_normalized_as_normalized   c             C   s   | }|   r|  }n|  s"t|   }|dk	rB|| }|j|d t	| 
 d}x|  D ]p}| |}| |}|
 dkrqp||}	|t|	 }
|
t|
d |

  d  }|||}qpW | j|dS )z
    Compute E-values: E = (F/eps**0.5) / rms of (F/eps**0.5)
    This is 'Karle' approach, that is not using overall B from Wilson plot.
    N)r   r   rT   g      ?)r   )r   rV  r   r!   r   r   rR  r   r   rN  r.   r(   r@   r   r   r;  rj  rO  r#   )r4   r   eps_facf_obsr  ErB   Zbin_selfor  Zfo_epsZE_binr%   r%   r&   	normalize  s&    
 
zarray.normalizec             C   s   | j ||d }|   }|d }g }xhd|fd| fgD ]R\}}|ddkrVq>||}	||}
||t|
|
 t|
d  f q>W |S )zH
    Compute <E**4>/<E**2>**2 for centric and acentric reflections.
    )r   r  rT   ZcentricZacentricTr   )r  r   r   r   r   rE   r   r  )r4   r   r  r  Zcentrics_selectione_sqr{   r   r   Ze_Ze_sq_r%   r%   r&   second_moments_centric_acentric  s     

*z%array.second_moments_centric_acentricc       
      C   s  |   dk	st|    dks$t|  ds6t|  dksN|  sNt|    }t	
 }xp|    D ]`}|   |}t	|  |}| dkr||}|| }|t	| qt|d qtW |   ||}	|	dstt| t	|	S )a   A miller.array whose data N(h) are the normalisations to convert
    between locally normalised E's and F's:
    E(h) = F(h) / N(h)

    self features the F's, which are then binned with the current binner
    and N(h) is the average of F's in the bin h belongs to.
    Nr   )r(   r!   rS   r   r:  r  r   r   rR  r   rN  r@   r   r  r   r.   rE   r  interpolateall_gtr#   r;  )
r4   d_star_powerr   mean_f_sq_over_epsilonrB   r   sel_f_sqsel_epsilonssel_f_sq_over_epsilonmean_f_sq_over_epsilon_interpr%   r%   r&   amplitude_quasi_normalisations!  s$    
z$array.amplitude_quasi_normalisationsc       
      C   s   |   dk	st|    dks$t|  ds6t|  dksN|  sNt|    }t	
 }xj|    D ]Z}|   |}|  |}| dkr||}|| }|t	| qt|d qtW |   ||}	t| |	S )a   A miller.array whose data N(h) are the normalisations to convert
      between locally normalised E^2's and I's:
      E^2(h) = I(h) / N(h)

      Intensities are binned with the current binner
      and N(h) is the average of I's in the bin h belongs to.
      Nr   )r(   r!   rS   r   r:  r  r   r   rR  r   rN  r@   r   r   r.   rE   r  r  r#   )
r4   r  r   r  rB   r   r  r  r  r  r%   r%   r&   intensity_quasi_normalisations=  s"    
z$array.intensity_quasi_normalisationsc             C   s$   |  |}|  |  }t| |S )N)r  r   r#   )r4   r  r  qr%   r%   r&   !quasi_normalize_structure_factors\  s    
z'array.quasi_normalize_structure_factorsc       
      C   sr  |    |   kst|    |   ks8t|  sDt| sPt|d k	r| sdt|    |   kst| j|  dj|d }t	| }|| }|d k	r||  }|d krt
t|  t|   }n2t
| |  t|   t|   }t
t| t|  }t|| }	|	dksbt| j||	 dS )N)r   )r[  r   )r+   r.   r!   r   r"  r#   r   r_  r   r(  rj  r   ry  r;  )
r4   r[  r  Zfomr  r  ZcoeffZf3f4rm  r%   r%   r&   !phased_translation_function_coeffa  s*    $ "z'array.phased_translation_function_coeffc             C   sh   |    }| jr$|d | j  }|d | j  }| jrN|d | j  }|d| j   }|d S )zx
    Emit a string for debugging of the labels, type of data
    and sigmas array present within this miller_array.
    
z	
size: %d)r8   __repr__r  r  r  r  r.   )r4   Zmstrr%   r%   r&   r  y  s    zarray.__repr__c             C   s   t | t|  |  S )z
    Return a copy of the array with data replaced by absolute values, i.e.
    complex arrays will be converted to amplitudes.  Enables abs(array).
    )r#   r   r   r   r   )r4   r%   r%   r&   __abs__  s    zarray.__abs__c             C   s(   t |  tjstt| t|  S )N)r   r   r   r  r!   r#   norm)r4   r%   r%   r&   r    s    z
array.normc             C   s   t | t|  |S )N)r#   r   rz  r   )r4   rs   r%   r%   r&   rz    s    z	array.argc             C   s,   t |  tjst|  dks$tt| S )z?
    For a complex array, return array of absolute values.
    N)r   r   r   r  r!   r   r   )r4   r%   r%   r&   r]    s    zarray.amplitudesc             C   s,   t |  tjst|  d ks$t|  S )N)r   r   r   r  r!   r   r  )r4   r%   r%   r&   intensities  s    zarray.intensitiesc             C   s.   t |  tjst|  dks$t| |S )zV
    For a complex array, return the array of its phases (in radians by default).
    N)r   r   r   r  r!   r   rz  )r4   rs   r%   r%   r&   rx    s    zarray.phasesgaussianc             C   s   t | |||dS )z
    Given a non-unique array, merge the symmetry-related reflections (keeping
    anomalous flag).

    :returns: a merge_equivalents object, from which the merged array may     be extracted by calling the array() method.
    )incompatible_flags_replacementuse_internal_variance)r2  )r4   r  r  r   r%   r%   r&   r2    s    
zarray.merge_equivalentsc             C   s    t |  |  |  d| S )z
    Return a copy of the array with identical contents (keeping original
    flex arrays) but with the anomalous flag set to false.
    )r6   r   r   )r#   r#  r   r   r3  )r4   r%   r%   r&   r1    s    zarray.as_non_anomalous_arrayc             C   s    t |  |  |  d| S )z
    Return a copy of the array with identical contents (keeping original
    flex arrays) but with the anomalous flag set to true.
    )r6   r   r   )r#   r$  r   r   r3  )r4   r%   r%   r&   as_anomalous_array  s    zarray.as_anomalous_arrayc             C   sH   |   s|  r4|     j| d  S |    S dS )zg
    Given an anomalous array, merge the anomalous pairs and return the
    non-anomalous average.
    )r8   N)r"  r$  r   r1  r2  r#   r   )r4   r%   r%   r&   rk    s    zarray.average_bijvoet_matesc             C   sd  | j |d }|d}|dkr&| S |dk	r|r8d}nd}t|  tjs\t|  tjrpt|  }d}nd}d}t|d	||t	|d
 |f  |d | j
| d}	|dk	r`|dk	rVt|d |d t|
|}
t|d|
  |d || krVt|
| }t|d|  |d |dkrV||
d krVt|d|
|   |d t|d |	S )zf
    Remove all reflections which should be systematically absent in the current
    space group.
    )r   Tr   Nz	integral r?   r  .z$Removing %d %ssystematic absence%s%sr>   )r}   )r   z  Average absolute value of:z    Absences: %.6gz      Others: %.6gg#B;z       Ratio: %.6g)r   r   r   r   r   rN  r  r   rA   r   r   r  r.   )r4   r   r  r   r   rg   r  Zdata_absra  r{   Zmean_absencesZmean_othersr%   r%   r&   r*    s>    
  


zarray.eliminate_sys_absentc             C   s   | j | j|d dS )N)r   )r   )r   r   r   )r4   r   r%   r%   r&   select_sys_absent  s    zarray.select_sys_absentc             C   s   |   dk	st|  dk	s tt|t| krBt| |  | S |  dk	sRt| dk	sbtt|   |  }|d}||  | }d}|  dk	r| dk	r|	|  | }tt
| |||S )zOverload the '+' operator.Nr   )r+   r!   r   r   r#   r?  Zpaired_miller_indicesZplusr   r  r:   )r4   r   matchr   ri   r   r%   r%   r&   __add__  s    
zarray.__add__c             C   sL   |   d k	st|  d k	s t|  }||9 }|  }|d k	rH||9 }| S )N)r+   r!   r   r   )r4   r   r   r   r%   r%   r&   __imul__  s     zarray.__imul__c             C   sL   t |tr8|  | s t| j|  |  dS |  }||9 }|S )N)r   )r   r#   r+   r*  r!   r   r   r   )r4   r   r{   r%   r%   r&   __mul__!  s    
zarray.__mul__c             C   sL   |   d k	st|  d k	s t|  }|| }|  }|d k	rH|| }| S )N)r+   r!   r   r   )r4   r   r   r   r%   r%   r&   __itruediv__)  s     zarray.__itruediv__c             C   s   |   }|| }|S )z/ This requires from __future__ import division )r   )r4   r   r{   r%   r%   r&   __truediv__2  s    zarray.__truediv__c             C   s,   |  |g}t| dks t| d S )zAExtract the value of the array for the specified reflection h,k,lr>   r   )r  r]   r   r!   )r4   r  Z	hkl_arrayr%   r%   r&   value_at_index8  s    zarray.value_at_indexc             C   s   |  | j|S )a,  
    Returns the value of data of the first index matching
    `miller_index`. If the `miller_index` is not found in `self`,
    then returns ``None``.

    :param miller_index: Miller index as a 3-tuple
    :type miller_index: tuple
    :returns: int, float, complex, None -- data value or None
    )r  r  )r4   r   r%   r%   r&   data_at_first_index>  s    
zarray.data_at_first_indexc             C   s   | j dk	st| | j |S )a0  
    Returns the value of sigmas of the first index matching
    `miller_index`. If the `miller_index` is not found in `self`,
    then returns ``None``.

    :param miller_index: Miller index as a 3-tuple
    :type miller_index: tuple
    :returns: int, float, complex, None -- sigmas value or None
    N)r  r!   r  )r4   r   r%   r%   r&   sigma_at_first_indexJ  s    
zarray.sigma_at_first_indexc             C   s   |   r| S |    }|   }|||  d}d}|  dk	r|   }|  rx|t	|| n.| 
 r|||	  n||| |  dk	r|   }||| tt| |dd||dS )zp
    If the array is not already anomalous, expand to generate anomalous pairs
    (without changing data).
    NT)r8   r+   r-   )r6   r   r   )r-   r   r   r+   r   rp  r   r"  r   r(  r$  r   r#   r:   )r4   r   r+   r   r   r%   r%   r&   rq  W  s0     zarray.generate_bijvoet_matesc       	      C   s&  |r|  |st|  st| s*t|r>|  dk	s>t| }| r\| s\| }n| st| rt| }|j||d\}}|st|	 |	 S |
|  g }xf|   D ]V}| |}t|	 ||	 |}| s|d q||  qW t| |ddS )a  
    Calculate correlation coefficient between two arrays (either globally or
    binned).

    :param other: another array of real numbers
    :param use_binning: calculate CC in resolution bins (default = calculate
                         a single global value)
    :param assert_is_similar_symmetry: check that arrays have compatible
                                       crystal symmetry
    :returns: a Python float (if use_binning=False), or a binned_data object
    N)r   r@  z%6.3f)r(   r   r   )r>  r!   r   r(   r-   rq  rD  r   linear_correlationr   r4  rD   r   r   r  rE   coefficientr   )	r4   r   r   r@  lhsr   rB   r   correlationr%   r%   r&   r  u  s2    


 zarray.correlationc             C   s"  |dkrt j}|   |   ks*t|  r~|dk	r~xt|  |  D ]*\}}t|t	| |t
j||d|d qNW n|  dkrxt|  |  D ]\}}t|t	| ||d qW n\|   |   kstx>t|  |  |  D ]"\}}}t|t	| |||d qW | S )z"Listing of Miller indices and dataN)rs   )r}   )r~   r   r   r.   r+   r!   r"  r   rA   r^   r   Zabs_argr   )r4   r   r   rs   r   ri   r   r%   r%   r&   
show_array  s     ($zarray.show_array  c             C   s  | | }}|  |  s t|  }| }| }t|}||}||}||}tj	||||d}	|		 }
|	
 }|	 }d}| | }|dk rt|d }ddlm} |j||
|dd\}}
t|}|
 | krdS t|||||
|d	S )
z1
    Compute Fourier Shell Correlation (FSC)
    )r  r  r   r  r  r  r   )	smoothingrT   )re  rf  half_windowdegreeN)ri   d_invfsc)r+   r*  r!   r   r   r   rM  r   r
   r  ri   r  r.   r   rh  r  Zsavitzky_golay_filterr   )r4   r   	bin_widthr  r  dsr  r  r   rU  r  ri   r  r  rJ  r  r%   r%   r&   r    s0    





z	array.fscM?c             C   s\  |dkr4|dk	st | j||d}|s@tdddS n|dks@t d}x*t|j D ]}|j| |k rT|}P qTW d}d}|dk	rB|j| }|dk	rB|d }	|	dk rd}	|d }
|
t|jkrt|jd }
d}|d	kr|j|	 |k|j|
 |k gdd
k}|s|rB|j|	|
 }|j|	|
 }ddl	m
} |j||d
ddj\}}}|| }|d
 d| |  }|d	k|d	kg}|dd
krB| t| d
|  }| t| d
|  }|| d	k rdt|| }nh|dkrB|dkrBd| d|  }}t|| }t|| }||k r(|}n|}t|| dkrBd}|dkrP|}t||dS )zf
    Compute Fourier Shell Correlation (FSC) and derive resolution based on
    specified cutoff.
    N)r   r  )r  r/   ru  r   r  r>   Tg        rT   )curve_fitting)Zx_obsZy_obsr  Znumber_of_cyclesrV   g      ?g      ?)r!   r  r   r   r.   ri   r]   r   r  scitbx.mathr  Zunivariate_polynomial_fitparamsry  r;  r\   r   )r4   r   Z	fsc_curver  Z
fsc_cutoffZi_midr   r/   Zd_midZi_minZi_maxZon_slopere  rf  r  ra  r.  r-  rM  Zwell_definedx1x2r  r  Zdiff1Zdiff2r%   r%   r&   d_min_from_fsc  sh     




  
 zarray.d_min_from_fscc             C   sz   t |  }t | }|   }|  }tt |t | }|dkrvt || t ||  | S d S )Nr   )	r   r   r   rx  ry  r;  r  rj  r0  )r4   r   r  r  rw  r  r  r%   r%   r&   map_correlation  s     zarray.map_correlation      ?c	             C   s   t |  tjst||gddks*t| }	||gd dkrN| j||d}	|	j||tj	|d}
|rn|

  |rz|
  |
j|dS )NT)r   r>   r   )r/   r   )r  r  r  r  )wrapping)r   r   r   r  r!   r   r=  fft_mapr
   Zuse_space_group_symmetryapply_sigma_scalingapply_volume_scalingas_map_manager)r4   r  r  r  r/   r   r%  r&  r#  mcZfft_map_r%   r%   r&   r'    s    	  zarray.as_map_managerUUUUUU?ru  c
       
   
   C   s<   |dk	rt || |	dS t | j|||||||d| |	dS dS )aa  
    Calculate the FFT for the array, assuming the data are complex doubles.

    :param resolution_factor: when multiplied times the resolution limit, gives
                              the approximate grid spacing of the map.
    :param d_min: High-resolution cutoff
    :param crystal_gridding: optional gridding to use (overrides automatic
                             gridding)
    :param symmetry_flags: specifies how the grid should be constructed to
                           handle symmetry
    :param f_000: Optional F(0,0,0) value (scalar added to entire map)
    :returns: an fft_map object
    N)r  fourier_coefficientsf_000)r/   r  r  r  r  r  r  )r$  r  )
r4   r  r/   r  r  r  r  r  r  r+  r%   r%   r&   r$  (  s     zarray.fft_mapc             C   sx   |   st| }|    dkr,| }| s<| }tj	|
 | |d}|dk	rd|| S ||    S dS )z
    Calculates the exact map value at the specified fractional coordinate
    using direct Fourier summation.  Relatively slow but avoids interpolation
    errors.
    r>   )r<   r   	site_fracN)r"  r!   r,   r   r\  r   r-   rq  r
   direct_summation_at_pointr+   r   r7   r  )r4   r,  sigmaZ
map_coeffsrj  r%   r%   r&   r-  P  s    zarray.direct_summation_at_pointr   c             C   s<  t |  tjst|  }|| }| j|d g }xl|  	 D ]\}|  
|}|  j|ddd}| j|d}| \}	}
t| }||	|
|g qDW t }t }xbt|  | D ]H\}}x>|D ]6}||d kr||d kr||d  || P qW qW t| |dd}t||}| j|d	S )
N)r   F)rB   ru   rx   )r   r>   r   rT   )r-   )r   )r   r   r   rN  r!   rL   rF  r   r(   r@   r   r|   r   r   r  rE   r   r   r   r+   r:   r#   rn  )r4   r   rt  lsr{   rB   r   r   Zsselr   r/   Z	data_meanZ	data_loner+   ri   r   rU  Zlmslar%   r%   r&   complete_with_bin_averagee  s0    
 



zarray.complete_with_bin_averagec             C   sb   |   st| j|d}|  | }tj|||d | }|d k	rP| j|d}|j|ddddS )N)r  )r   
mean_scalen_iterations)r/   TF)r  r  r-   r  )	r"  r!   r$  r&  real_map_unpaddedr
   Zhoppe_gassman_modificationrL   r  )r4   r2  r3  r  r/   r$  map_datarB  r%   r%   r&   hoppe_gassmann_modification  s     z!array.hoppe_gassmann_modification      @c             C   s   |   st| j|d}|  | }| }~t| }	t	| }
|	|
kr`|
 }}n,t
j|td| d}|j|||d\}}t
j||||d}|d kr|  }|j|d|  dd}|d kr| }dd	d
}|||d}|d kr|}|S )N)r  i  )r   )r  vol_cutoff_plus_percentvol_cutoff_minus_percent)r5  r  cutoffpcutoffmT)r  r  r-   r    c             S   s  |   |    kst| |\}}td|   }|j|d || dt|	    d }t
 }t
 }x|  D ]}| |}	t||	  }
t||	  }t|
| }t|| }|dks|dkrd S |||  |t||	 qW | dkrptjjt||d}dt|	    d }|jt| |j  }n|d }|j|  | dS )	Ni  )r   g      ?g      @r   r>   )re  rf  )r   )r   r.   r!   rD  r  r   r4  r   r  r   rN  r(   r@   r   r   r   rj  rE   r  rh  ry  ri  r;  r-  r  r.  r   )r  r  r   Zf1_Zf2_r  r   Zss_binrB   r   Zsel_f1Zsel_f2rg   ri   rU  Zk_isotropicr%   r%   r&   r     s0    
 z+array.double_step_filtration.<locals>.scale)r  r  )r<  )r"  r!   r$  r%  r4  r  r   r  as_1dr\   r
   	histogramr.   Zget_percentile_cutoffsZdenmod_simplerL   r  r-   )r4   rL   r8  r9  r  Zscale_tor$  r5  r  Z	value_minZ	value_maxr:  r;  histsfr   r{   r%   r%   r&   double_step_filtration  sD    
  
 zarray.double_step_filtrationc          
   C   s   |   }t||d}| j|||||||	|
d}|  |t| | }|j|	 | d}t| j
|||||||	d|d }|S )N)rL   radius)r  r/   r  r  r  r  r  r+  )r   )r/   r  r  r  r  r  r  )r  r*  )rL   get_sphere_reciprocalr$  r&  r  r   r  r4  r#   r   r  )r4   rB  Zmean_solvent_densityr  r/   r  r  r  r  r  r+  rL   sphere_reciprocalr  tempfourier_coeffr%   r%   r&   local_standard_deviation_map  s6    
z"array.local_standard_deviation_mapc          
   C   s  |    |   st|  }t||d}|d krB|  }| j|||||||	|
d}|  |j|||||||	|
d}|  |	 }|
  j}|| }|	 }|
  j}|| }|| }||}|j| | d}t| j|||||||	d|d }|S )N)rL   rB  )r  r/   r  r  r  r  r  r+  )r   )r/   r  r  r  r  r  r  )r  r*  )r8   r7   is_similar_tor!   rL   rC  r/   r$  r%  r4  r=  min_max_meanr  r  r#   r   r  r&  )r4   r   rB  r  r/   r  r  r  r  r  r+  rL   rD  r  Z	other_fftr5  Zmap_data_meanZother_map_dataZother_map_data_meanZoverlap_map_datarE  rF  r%   r%   r&   local_overlap_map  s^    


zarray.local_overlap_mapc
          	   C   s,   |   }
t|
j||||||d|
|||	dS )z.
    Calculate an unphased Patterson map.
    )r  r/   r  r  r  r  )r  f_pattr+  
sharpeningorigin_peak_removal)r  patterson_mapr  )r4   r  r/   r  r  r  r  r+  rL  rM  rK  r%   r%   r&   rN  ?  s    zarray.patterson_mapc             C   s$   ddl m} |j| ||||d dS )z8
    Write reflections to a SHELX-format .hkl file.
    r   )hklf)rB  file_objectnormalise_if_format_overflowfull_dynamic_rangescale_rangeN)Ziotbx.shelxrO  Z!miller_array_export_as_shelx_hklf)r4   rP  rQ  rR  rS  rO  r%   r%   r&   export_as_shelx_hklfY  s    zarray.export_as_shelx_hklfc             C   s$   ddl m} || |||||d dS )z1
    Write reflections to a CNS-format file.
    r   )export_as_cns_hkl)rP  r   r  array_namesr_free_flagsN)Ziotbx.cns.miller_arrayrU  )r4   rP  r   r  rV  rW  implementationr%   r%   r&   rU  i  s    	zarray.export_as_cns_hklc             C   s$   ddl m} || |||||d dS )a  
    Write data in unmerged scalepack format.

    :param file_object: filehandle-like object
    :param file_name: output file to write
    :param batch_numbers: integer array indicating the batch (image) numbers
                          corresponding to the indices (optional)
    :param spindle_flags: integer array indicating the position of the
                          reflections on the detector (optional)
    r   )writer)Zi_obsrP  r   batch_numbersspindle_flags%scale_intensities_for_scalepack_mergeN)Z'iotbx.scalepack.no_merge_original_indexrY  )r4   rP  r   rZ  r[  r\  rY  r%   r%   r&   export_as_scalepack_unmergedz  s    z"array.export_as_scalepack_unmergedr	   projectdatasetc
          
   C   s`   |dkr.|   r*|   jr*|   jd }nd}| j||||||||	d}
|
 }|j|d dS )zU
     Simple version of write_mtz for a single array, typically map coefficients
    Nr   F)column_root_labelcolumn_typeslabel_decoratortitlecrystal_nameproject_namedataset_namerr   )r   )r  r   as_mtz_dataset
mtz_objectwrite)r4   r   ra  rb  rc  rd  re  rf  rg  rr   Zmtz_datasetri  r%   r%   r&   	write_mtz  s    zarray.write_mtzc	             C   sP   ddl }	|dkr&|  }
|
dk	r&|
j}|dkr2d}|	jj| ||||||||d	S )z
    Generate an iotbx.mtz.dataset object for the array, which can be extended
    with additional arrays and eventually written to an MTZ file.
    r   Ng      ?)ra  rb  rc  rd  re  rf  rg  rr   )Z	iotbx.mtzr  rr   mtzZmiller_array_as_mtz_dataset)r4   ra  rb  rc  rd  re  rf  rg  rr   iotbxr  r%   r%   r&   rh    s     zarray.as_mtz_datasetc             C   s   dd l }|j| |jS )Nr   )	iotbx.cifcifmiller_arrays_as_cif_block	cif_block)r4   
array_typerm  r%   r%   r&   as_cif_block  s    zarray.as_cif_blockglobalc             C   sB   |d krt j}dd l}|jj }| j|d||< t||d d S )Nr   )rr  )r}   )r~   r   rn  ro  modelrs  rA   )r4   rr  r   Z	data_namerm  ro  r%   r%   r&   as_cif_simple  s     zarray.as_cif_simplec             C   s$   ddl }|jj| |||||d dS )z$
    Write phases to .phs file.
    r   N)r4   r   scale_amplitudesrx  
phases_degfigures_of_merit)Ziotbx.phasesrx  Zmiller_array_as_phases_phs)r4   r   rw  rx  rx  ry  rm  r%   r%   r&   as_phases_phs  s    	zarray.as_phases_phsc             C   sB   |dkr4ddl m} |  }|jdd |||}t| ||S )z Overriden version of set.amplitude_normalisation which computes
    the Wilson parameters from the array data if wilson_plot is None. Nr   )
statisticsrX  )r   )r  r{  r7  r   r  r:   r  )r4   r  r  r{  r  r%   r%   r&   r    s    zarray.amplitude_normalisationsc             C   s   t | ||S )N)normalised_amplitudes)r4   r  r  r%   r%   r&   r|    s    zarray.normalised_amplitudesc             C   s  |   dkrdS |r$|  dk	s$t|r4|dks4t|dk	rT| |    ksTt| s`t| |    ksxt|s`|    dkrdS |   }|  r|   }nt|  }|dk	r|dk st|t	|   | k}|
|}|
|}|dk	r|
|}|dkr:t|| tt| S t|| | t|t|  S g }xZ|   D ]J}	|  |	}d}
|dk	r|
|}
|| 
||
||
 qrW t|  |ddS )a&  
    The analytical expression for the least squares scale factor.

    K = sum(w * yo * yc) / sum(w * yc^2)

    If the optional cutoff_factor argument is provided, only the reflections
    whose magnitudes are greater than cutoff_factor * max(yo) will be included
    in the calculation.
    Nr   r>   z%7.4f)r(   r   r   )r   r(   r!   r.   r"  r   r  r   r   r\   r   rj  r  rD   r   rE   rl  r   )r4   r  r}  r  r   r  calcr   r  rB   Zweights_selr%   r%   r&   rl    sH       







 zarray.scale_factorc             C   sD   ddl }ddl m} |jj||||jdj}|dk	r<|| S |S dS )zg
    Class method for building an array from a CIF file (or filehandle).
    Depends on iotbx.cif.
    r   N)builders)rP  	file_pathdata_block_namedata_structure_builder)rn  r~  ro  cctbx_data_structures_from_cifmiller_array_buildermiller_arrays)clsrP  r  r  rm  r~  arraysr%   r%   r&   from_cif0  s    zarray.from_cifc             C   s`   |   st|   }|  |  |}d| | t|d | }|d7 }t	|d}|S )a  
    Extinction parameter x, where Fc is multiplied by:
      k[1 + 0.001 x Fc^2 wavelength^3 / sin(2theta)]^(-1/4)

    See SHELX-97 manual, page 7-7 for more information.

    Note: The scale factor, k, is not applied nor calculated by
          this function. The scale factor should be calculated
          and applied ***AFTER*** the application of the extinction
          corrections.
    gMbP?r  r>   g      п)
r"  r!   rZ  r   r7   Zsin_two_thetar+   ry  r   r   )r4   re  rr   r:  Zsin_2_theta
correctionr%   r%   r&   shelxl_extinction_correctionA  s    z"array.shelxl_extinction_correctionc             C   s    |  ||}| j|  | dS )N)r   )r  r   r   )r4   re  rr   r  r%   r%   r&   "apply_shelxl_extinction_correctionU  s    z(array.apply_shelxl_extinction_correction皙?皙?c             C   s  |  |   st| r.t| }n|  }|   }t|dk rXdS t	|}t
|| }|dkr|dS ||| 9 }tt|t|}	|	dkrdS |d|	 9 }|d|	 9 }d| d|  }
|
 | }d|
 }|}||
| | k ||| | kB }|r|||fS |S )z      Preconditions (not checked explicitly):
        self is amplitude array,
        f_calc is complex array or amplitude array.
    r   Nr>   )r+   r*  r!   r"  r   r   r   r   r  r  rj  r\   )r4   r  Z
offset_lowZoffset_highZalso_return_x_and_yre  rf  Zsum_xxZsum_xyr   Zm_lowZb_lowZm_highZb_highr{   r%   r%   r&   "f_obs_f_calc_fan_outlier_selectionY  s4    



z(array.f_obs_f_calc_fan_outlier_selectionc             C   s  |   d ks |  s |  s t|  s,t|  d k	s<tddlm} d}|d k	rX|}|d k	r| | 	  ksxt|d kst
|dkrt|rt|| 	 |  |  ||}tt| |j	|  d|j|jd| |_n"|| 	 |  |  |}| |_||_||_|S )Nr   )observationsr%   )r8   r+   r-   )r6   r   r   )r  r   r   r!   r   r   r  r  r.   r+   r]   r   r#   r:   r-   r3  r3  Zref_twin_fractionsZref_twin_components)r4   Zscale_indicesZtwin_fractionsZtwin_componentsr  Ztw_cmpsr{   r%   r%   r&   as_xray_observations  s8    
zarray.as_xray_observationsc             K   s4   |   stddlm} t|}| |d< |jf |S )z
    Perform French-Wilson treatment of X-ray intensities to estimate the "true"
    intensities, replacing very weak and/or negative values, and takes the
    square root to obtain amplitudes.

    :returns: an array of all-positive X-ray amplitudes
    r   )french_wilsonrB  )r   r!   r  r  dictZfrench_wilson_scale)r4   kwdsr  r%   r%   r&   r    s
    zarray.french_wilsonr   r   r   r   r   r>   c             C   st  ddl }|   }|j|}| }t|tt|t|  }t	
||}	t|}t }
x|  D ]}t|| }t|t| }t	
||}||}||	 }d}|dkr
|dkst|| }tdt| dk rd}dt	j t	| }|
| qvW x:tddD ],}|
|k}d|d |  |kr$P q$W |rf| j|d	S | j| d	S )
z
    Remove reflections corresponding to a cone shape in reciprocal space with
    the apex at the origin.  Used to simulate incomplete data due to poor
    alignment of the crystal with the goniometer axis.
    r   Ng      ?gMbP?r  r>   g      Y@T)r   )r   r7   fractionalization_matrixr   sqr	transposer   rN  r   ry  r;  r`  r+   r!   r   rz  acosrE   r   r   r.   r   )r4   Zfraction_percentZvertexaxis_point_1axis_point_2r8  rh  fmr  axis_lengthZopening_anglespointZpoint_minus_vertexZpoint_minus_vertex_length	numeratordenominatorZopening_angle_deg_for_pointrJ  Zoar   r%   r%   r&   remove_cone  s>    


   zarray.remove_coner  c             C   s*  |   d krd S | jdd}d\}}}xt| | |  |  D ]\}}}}	|  |}
|d dkr|d dkr|| |kr|d kr|	|d f}|d dkr|d dkr|| |kr|d kr|	|d f}|d dkr|d dkr|| |kr|d kr|	|d f}|||gd dkrLP qLW |||gd dksh|d |d |d gddkr | 	 \}}dd }||d |d }||d |d }||d |d }| 
 \}}}|d ks|d dkr||f}|d ks|d dkr ||f}|d ks|d dkr ||f}|||fS )	NT)rK  )NNNr>   r   rT   c             S   s4   t | |kr| S t | |k r |S t | |kr0|S d S )N)r   )r-  r.  r%   r%   r&   helper  s       zBarray.ellipsoidal_resolutions_and_indices_by_sigma.<locals>.helper)r   rT  r   r+   r   r   r7   r   r   r  r  )r4   sigma_cutoffr  h_cutk_cutl_cutr   r   r   ri   r   r  r  r  ZhmZkmZlmZdhZdkdlr%   r%   r&   ,ellipsoidal_resolutions_and_indices_by_sigma  s<     
,,4 "   z2array.ellipsoidal_resolutions_and_indices_by_sigmac          	   C   s  |   d krd S | jdd}g g g   }}}xt| | |  |  D ]\}}}}|| }	|d dkr|d dkr|||d |	f |d dkr|d dkr|||d |	f |d dkrP|d dkrP|||d |	f qPW td td xtt	t
|t	t
|t
|D ]}
d}yd	||
  }W n tk
rP   |}Y nX yd	||
  }W n2 tk
r   t
| dkr|}n|}Y nX yd	||
  }W n tk
r   d
}Y nX t||| qW d S )NT)rK  r>   r   rT   z0a*                      b*                    c*zAd         h   F/sigma   d        k  F/sigma   d        l  F/sigmaz                     z%7.3f %4d %8.3fr?   )r   rT  r   r+   r   r   rE   rA   r   r\   r]   r
  strip)r4   r  r   r   r   r   r   r   ri   Zdata_over_sigmar   Zblancr  r  r  r%   r%   r&   *show_mean_data_over_sigma_along_a_b_c_star  s@        &  
  
  
z0array.show_mean_data_over_sigma_along_a_b_c_starc             C   s  | j |d\}}}|   }t|d |d  }t|d |d  }t|d |d  }|||gd dkrv|  S t|  	 d}	| 
 }
|  }xlt|  D ]\\}}|  |}t|d | d |d | d  |d | d  }|dkrd|	|< qW | j|	dS )N)r  r>   r   rT   FT)r   )r  r7   r   r   r   r   r   r6  r+   r.   r   r   r   r   ry  r;  r   )r4   r  r  r  r  r   ZehmZekmelmr   r   r   r   r   r   rU  r%   r%   r&   ellipsoidal_truncation_by_sigma  s"     6 z%array.ellipsoidal_truncation_by_sigmac             C   s   |    }t| d }||k||k@ }| }t| }||}||| |  |}	d}
| 	 dk	r| 	 |}
| j
|	|
dS )z
    Randomly shuffle reflections within a given resolution range.  Used for
    control refinements to validate the information content of a dataset.
    TN)r   r   )r   r   r   r6  r.   rP  random_permutationr   rO  r   r   )r4   r   r/   r   Zall_iselZrange_selectionZ
range_iselr<  Zrange_isel_permutedr   r   r%   r%   r&   permute_d_range!  s    
zarray.permute_d_rangec             C   sT   |   sdS |   }| |}| }|ddkr@|  S | |}|  S )z
    Determine whether the array contains unmerged experimental observations
    or not.  In some files only the centric reflections will appear to be
    unmerged, so we specifically check the acentrics (if present).
    FTr   )r   r   r   r   r   r   )r4   r   ZcentricsZacentric_flagsZ	acentricsr%   r%   r&   is_unmerged_intensity_array3  s     


z!array.is_unmerged_intensity_arrayc       
      C   s   |   st|s8| j|d }|d}t|||dS |  dk	sHtg }xX|   D ]H}|  |}| 	|}	|	
 dkr|d qZ||	j||d qZW t|  |ddS )a  
    Calculate the correlation between two randomly assigned pools of unmerged
    data ("CC 1/2").  If desired the mean over multiple trials can be taken.
    See Karplus PA & Diederichs K (2012) Science 336:1030-3 for motivation.
    This method assumes that the reflections still have the original indices
    and maps them to the ASU first; the underlying compute_cc_one_half
    function skips this method.
    )r-   rI  )n_trialsreturn_n_reflNr   z%6.3f)r(   r   r   )r   r!   r   r)  rT  compute_cc_one_halfr(   rD   r   r   r.   rE   cc_one_halfr   )
r4   r   r  r-   r  r  r   rB   r   	bin_arrayr%   r%   r&   r  D  s"    


zarray.cc_one_halfc             C   s>  |   st|s| jt|  dd}|jdd}| |	 
 dk}| dkr`d}nJt| }t|
 }| }	dt| }
|	d|
  |	d|
   }|r|| fS |S |  dk	stg }xX|   D ]H}|  |}| |}| dkr|d q||j|d	 qW t|  |d
dS )u  
    Calculation of CC1/2 by the 'sigma-tau' method, avoiding the random
    assignment into half-datasets of the above method.
    See Assmann et al., J. Appl. Cryst. (2016). 49, 1021–1028.

    var_y is the variange of the average intensities across the unique
    reflections of a resolution shell.
    var_e is the average variance of the observations contributing to the
    merged intensities
    r>   )r   T)r   r   rT   g      ?N)r  z%6.3f)r(   r   r   )r   r!   r   r   rN  r.   r2  r#   r   redundanciesr   r  r   mean_and_varianceunweighted_sample_variancer  r(   rD   r   rE   cc_one_half_sigma_taur   )r4   r   r  Zintensities_copyZmerging_internalr5  r  Zinternal_variancesZmavZvar_yZvar_er   rB   r   r  r%   r%   r&   r  a  s6    
zarray.cc_one_half_sigma_tauc             C   sj  |   st| jdd }|d}|st| | | dd}t	| |jdd}|
 sbtt||jd}| }t||jd}	|	 }
| |
 st|r||	fS |r|j|
dd | fS |j|
dd S |  d	k	st|j| d
 g }xV|  D ]F}| |}||}| dkrD|d	 n||  qW t| |ddS )z
    Calculate the correlation of the anomalous differences of two randomly
    assigned half-datasets (starting from unmerged data).
    T)r-   rI  F)unmerged_indicesunmerged_dataunmerged_sigmasZweighted)r8   r+   r-   )r6   r   )r   r   N)r   r   z%6.3f)r(   r   r   )r   r!   r   r)  rT  split_unmergedr+   r   r   r:   r   r#   data_1r  data_2r*  r  r  r.   r(   r4  rD   r   r   rE   "half_dataset_anomalous_correlationr   )r4   r   Zreturn_n_pairsZreturn_split_datasetsr  split_datasetsZbase_setZarray1Zdano1Zarray2Zdano2r   rB   r   r  r%   r%   r&   r    sL    



z(array.half_dataset_anomalous_correlationc             O   s   | j ||S )z>
    Alias for array.half_dataset_anomalous_correlation()
    )r  )r4   argsr  r%   r%   r&   cc_anom  s    zarray.cc_anomc             C   s   |   st| jdd }| s0|  }| }| j	|d}t
t
| }t
t
| }|dks|t|| S )aI  Calculate R_anom, which measures the agreement between Friedel mates.
    Unlike CC_anom and various other R-factors (such as R_pim, which it is
    usually compared to), this requires merged data.

    .. math::
      R_{anom} = \dfrac{\sum_{hkl}{|I_{hkl} - I_{-h,-k,-l}|}}{\sum_{hkl}{\left \langle I_{hkl} \right \rangle}}
    T)r-   )r   r   )r   r!   r   r)  r   r2  r#   r  rk  rB  r   rj  r   r   )r4   r  r  r  r  r  r%   r%   r&   r_anom  s    zarray.r_anomc             C   s   |dk	rd|  krdks"n t |dk	s.t |  }| rF| }| sRt tj|ddd}|  dkrzt	dt
|}|| }|j|d	d
\}}d| |  ||   }|d }	|j||	d }
|  r|
 S |
S )a  
    Apply a twin law to the data, returning an array of the same original type.

    :params twin_law: a valid twin law expressed as h,k,l operations
    :params alpha: predicted twin fraction (0 to 0.5)
    :returns: a new array with synthetically twinned data
    Ng        g      ?   i   )r_dent_denr>   z>The determinant of the provided twin law is not equal to unityF)r   r@  g      ?g      Y@)r   r   )r!   r)  r   rY  r   r   rt_mxrU  determinantr   r}  ri  rD  r   r   r  rV  )r4   twin_lawalphar  r  	new_arrayxaxbr  
new_sigmasZtwinnedr%   r%   r&   	twin_data  s*    "
zarray.twin_datac             C   s~  |dk	rd|  krdks"n t |dk	s.t |  }| rF| }| sRt tj|ddd}|  dkrzt	dt
|}|| }|j|d	d
\}}| | kst | }| }| }| }	d| | ||  dd|   }
d}tdd|  d| |  dd|   }|dk	rR|tt|d||	  d  }|j|
|dj| d}|  rz| S |S )a  
    Detwin data using a known twin fraction, returning an array with the same
    original data type.

    :params twin_law: a valid twin law expressed as h,k,l operations
    :params alpha: predicted twin fraction (0 to 0.5)
    :returns: a new array with detwinned data
    Ng        g      ?r  i   )r  r  r>   z>The determinant of the provided twin law is not equal to unityF)r   r@  g      ?g       @rT   )r   r   )r   )r!   r)  r   rY  r   r   r  rU  r  r   r}  ri  rD  r.   r   r   ry  r;  r   r   r   rB  rV  )r4   r  r  r  r  r  Zi_old1Zi_old2Zs_old1Zs_old2r  r  Ztmp_multZ	detwinnedr%   r%   r&   detwin_data  s<    	"
 *
"
zarray.detwin_datac          
   C   s  |dkrt j}| }td|d |dkr0| }n||dkrB| }nj|dkrT| }nX|dkrf| }nFyt|}W n6 t	k
r } zt
d|t|f W dd}~X Y nX |   rtd	|d td
| |d ntd|d td| |  f |d |   }td||d |dk r^|dkr^td|d td|d td|d |r|j| d}t|  |}	|	 }
||
}||	}tdt| |d t| dkrtdt| |d |}|j|d}td|d tj j!|d|d ||fS )a-  
    Encapsulates a variety of reindexing operations, including handling for a
    variety of corner cases.

    :param change_of_basis: Python str for change-of-basis operator
    :param eliminate_invalid_indices: remove reflections with non-integral
      indices
    :returns: new Miller array
    NzChange of basis:)r}   to_reference_settingZto_primitive_settingZto_niggli_cellZto_inverse_handzAThe change-of-basis operator '%s' is invalid (original error: %s)z<  Change of basis operator in both h,k,l and x,y,z notation:z   z-  Change of basis operator in x,y,z notation:z    %s [Inverse: %s]z  Determinant:r   z@  **************************************************************z@  W A R N I N G: This change of basis operator changes the hand!)r<   z"  Mean value for kept reflections:z%  Mean value for invalid reflections:)r  z)  Crystal symmetry after change of basis:z    )r   r   )"r~   r   rA   Z'change_of_basis_op_to_reference_settingZ'change_of_basis_op_to_primitive_settingrh  Z"change_of_basis_op_to_inverse_handr   r}  rv  r   r^   Zc_invr1  is_zeroZas_hklZas_xyzrr  ra  rU  r  Z%apply_results_in_non_integral_indicesr+   r   r6  r.   r   r  r   r]   ri  r	   r;   r   )r4   change_of_basiseliminate_invalid_indicesr   rB  r  r  ri   r   Ztossr  Z
keep_arrayZ
toss_arrayZprocessed_arrayr%   r%   r&   apply_change_of_basis   s\    



"


zarray.apply_change_of_basisMbP?c             C   s  |dkrt j}||gddks$t| }| }	|	 }
td|d |	j|dd | }| }	td|d |	j|dd |dkrt	
|}| }| |
 k r|rtd|d | }n
td	 |	 }|  }d
|  krdk rVn n^| rVt	d}||}| d | d krVtd|d ||}| }	|	 }| |s|}| |}td| |d tdt|  |d tdt|  |d | }| }t|| | }||krtdd|d   t tj||d}|j|d}|j dd|d\}}|rD|! sD|" # }|rf|$ }|% }|j&|d}td|d |j|dd |S )a  
    Encapsulates all operations required to convert the original data to a
    different symmetry (e.g. as suggested by Xtriage).  This includes
    reindexing and adjusting the unit cell parameters if necessary, and
    expansion to P1 (for moving to lower symmetry) or merging equivalents.

    :param space_group_symbol: Python str for space group symbol (any format)
    :param space_group_info: Pre-defined sgtbx.space_group_info object
    :param volume_warning_threshold: Cutoff for relative change in unit cell
      volume beyond which a warning is issued.
    :param expand_to_p1_if_necessary: When moving to lower symmetry, expand the
      data to P1 first.
    :param remove_systematic_absences: eliminate reflections that are
      systematically absent in the new symmetry.
    :param merge_non_unique: merge reflections that are no longer symmetry-
      unique under the new symmetry.
    :param log: filehandle-like object
    :returns: Miller array in the new symmetry
    Nr>   zCurrent symmetry:)r}   z  )r   r   zNiggli cell symmetry:z1Changing to lower symmetry, expanding to P1 firstzIThis operation will result in incomplete data without symmetry expansion!      za,-b,-cr   zReindexing with a,-b,-cz5Coercing unit cell into parameters compatible with %sz  Old cell: %sz  New cell: %sz3This operation will change the unit cell volume by zmore than %.1f%%.r   )r7   r,   )r8   r  T)r  r  r   )r   zNew Miller array:)'r~   r   r   r!   r8   r   rA   r   Zniggli_cellr   r,   rj  Zn_smxr   warningswarnr7   r   r\  Zis_reference_settingr}  ri  r   Zis_compatible_unit_cellZaverage_unit_cellr^   r  r   UserWarningr	   r;   r   r  r   r2  r#   r   r9  rF  )r4   r   r,   Zvolume_warning_thresholdZexpand_to_p1_if_necessaryr9  Zmerge_non_uniquer  rB  symmZspace_group_oldZspace_group_newr7   r\  r  Zunit_cell_newZunit_cell_oldZvolume_startZ
volume_newZvolume_change_fractionZsymm_newZma_oldr/  r%   r%   r&   change_symmetry^  sx    


$



zarray.change_symmetryc             C   s   t | j||dS )a  
    For each possible space group sharing the same basic intensity symmetry,
    show a list of possible systematically absent reflections and corresponding
    I/sigmaI.  Note that if the data have already been processed in a specific
    space group rather than the basic point group, for example P212121 instead
    of P222, all systematically absent reflections are likely to have been
    removed already.

    :returns: a systematic_absences_info object
    )r   r   )systematic_absences_infor   )r4   r   r   r%   r%   r&   %show_all_possible_systematic_absences  s    z+array.show_all_possible_systematic_absences      @c             C   s:   ddl }|jdstdddlm} |j| |||dS )z
    Detect translational pseudosymmetry and twinning, using methods in
    Xtriage.  Returns a mmtbx.scaling.twin_analyses.twin_law_interpretation
    object.  (Requires mmtbx to be configured to be functional.)
    r   Nmmtbxz)mmtbx is required for this functionality.)twin_analyses)r4   r/   completeness_as_non_anomalousr  )libtbx.load_envenv
has_moduleImportErrorZmmtbx.scalingr  analyze_intensity_statistics)r4   r/   r  r  r   r  r%   r%   r&   r    s    z"array.analyze_intensity_statisticsc             C   s   | j |d S )z
    Convenience method for identifying twinned data.  Note that this is
    hugely inefficient if any other Xtriage analyses are planned, since it
    discards the other results.  Requires mmtbx.
    )r/   )r  has_twinning)r4   r/   r%   r%   r&   r    s    zarray.has_twinningc             C   sZ  |r t |  d t dks td }d }|s8t||d}x|D ]}t| |d}|r|| \}	}
| j|	 |	 d}| j|
 |
 d}||}nd}|d kr|| }n|j	|d|d}|jt
| t|d	}|d kr|}q>|j	|dd
}q>W | dk }| |d |j| d|   d	}|| \}}
| j| | d}|S )Nr   y      ?      ?)r   r   )r   )r+   r   r>   F)r   ro  )r   )r   gư>)r   r   r!   r   r   rD  r   r+   r!  rr  r   rN  r.   r   rO  )r4   r   r   r   Zaverage_with_ccZ	sum_arrayZsum_n_arrayr   Zoffset_arrayZoffset_array_matchingZself_matchingZ
self_arrayweightZcount_arrayr   Zsum_array_matchingr  r%   r%   r&   average_neighbors  sF    


zarray.average_neighbors)NN)Nr?   )T)Nr?   )rX  )rX  N)r@  rA  N)rG  rH  )rL  )rO  rH  )rW  )rO  )rW  )N)N)T)NT)F)FF)Tr>   r>   )rH  NNr   r   )rH  F)NF)N)T)r  FN)NN)NN)F)FrH  NNT)F)N)FFF)FrA  N)r  TrA  )F)F)FN)FN)FN)F)F)r  r  Nr?   )NFFF)FN)FF)F)F)NN)N)	NNNNNNTr  F)FFFF)FF)FFF)FF)FF)FFF)r   )F)r  N)r  N)r>   )r>   )r>   )N)F)F)r  NT)FNr?   )F)FT)Nr?   N)r  )NNr  r  )r"  NNNNTFT)	r)  NNNNNru  TN)N)r   )r"  N)Nr7  r7  r"  N)	r   r)  NNNNru  TN)r)  NNNNru  TN)	r)  NNNru  TNFF)NFFN)NNNNF)	NNNNNr	   r^  r_  N)NNNr	   r^  r_  N)Nrt  )TNNN)N)N)NNF)NNN)r  r  F)NNN)r  r  r  F)r  )r  )Fr>   FF)FF)FFF)TN)NNr  TTTN)r  NN)r  )r>   FNN)r   r   r   r  r*   r   r  r3  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,  rR  r"   r   r2  r=  r?  rF  r+  rK  rN  rV  rY  r7  rZ  r^  r)  rc  rd  r   rn  rr  ru  rM  r  r   ri  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  r  r  rj  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rz  r]  r  rx  r2  r1  r  rk  r*  r  r  r  r  r  r	  r
  r  r  rq  r  r  r  r   r!  r'  r$  r-  r1  r6  rA  rG  rJ  rN  rT  rU  r]  rk  rh  rs  rv  rz  r  r|  rl  r  classmethodr  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#   .  sx  	 

  )      	4' ?		   0( $  
   " 2
                

$		  % :                    <        !       >                             
    .  #   ( +-/ <      V  r#   c               @   s   e Zd ZdddZdd ZdS )	rF  {Gz?      @Nc             C   s   || _ d| _d| _| }|d ks,|jd kr0d S |j }|d k	rh| }|d k	rh|j|||dshd| _|j }|d k	r|d kr| }	|	d k	r|	 }|d k	r| }
|
|krd| _d S )NT)r   Zrelative_length_toleranceZabsolute_angle_toleranceF)	rB  unit_cell_is_compatiblespace_group_is_compatibler  r  r7   rH  r   build_derived_point_group)r4   rB  rC  rD  rE  r  Zucfr   ZsgfZsgZpoint_group_from_filer%   r%   r&   r*     s2     

z?crystal_symmetry_is_compatible_with_symmetry_from_file.__init__c             C   s   | j }g }d|t| f g}| js\|d |dt| j  dt|  g | js|d |dt| j	  dt|	  g t
|dkrt
|d	krd
g}dd|d |d f d g| S d S )Nz  %s: %sz	unit cellz  Unit cell from file: z    Working unit cell: zspace groupz  Space group from file: z    Working space group: r   rT   zcrystal symmetryr  z$Working %s is not compatible with %sz from reflection file:)rB  r^   r  r  rE   rp  r  r7   r  r,   r]   rb   )r4   Zdata_descriptionmawhatmsgr%   r%   r&   format_error_message7  s,    

 zKcrystal_symmetry_is_compatible_with_symmetry_from_file.format_error_message)r  r  N)r   r   r   r*   r  r%   r%   r%   r&   rF    s     
rF  c               @   s2   e Zd ZdZdddZdd Zdd Zd	d
 ZdS )r|  z! E-values and related statistics Nc             C   s   |  st|||}| |  }tt| | d |d	 | _
t|}tt|d | _|dkd| _d S )N)r8   r+   )r6   r   r>   rV   T)r   r!   r  r   r#   r:   r8   r+   r%  r  _arrayr   r  rj  r   _sum_e_sq_minus_1r   _n_e_greater_than_2)r4   rB  r  r  r  r  r  r%   r%   r&   r*   R  s    
znormalised_amplitudes.__init__c             C   s   | j S )N)r  )r4   r%   r%   r&   r#   `  s    znormalised_amplitudes.arrayc             C   s   | j | j  S )N)r  r  r.   )r4   r%   r%   r&   mean_e_sq_minus_1c  s    z'normalised_amplitudes.mean_e_sq_minus_1c             C   s   d| j  | j  S )Ng      Y@)r  r  r.   )r4   r%   r%   r&   percent_e_sq_gt_2f  s    z'normalised_amplitudes.percent_e_sq_gt_2)N)r   r   r   r  r*   r#   r  r  r%   r%   r%   r&   r|  O  s
   
r|  c               @   st   e Zd 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dZdS )!r2  a  
  Wrapper for merging redundant observations to obtain a symmetry-unique
  array.  This also calculates some useful statistics resulting from the
  merging operation.  Normally this would not be instantiated directly, but
  instead obtained by calling array.merge_equivalents(...).
  r  NTc          
   C   s  |dkst d| _d| _d}d | _ | _ | _| _d| _d| _|	 j
j}tjtjtjtjd|d}|dk	r:| }|jdd}	yN|dkr|| |	|	 |	|d}
n|| |	|	 |	}
W nD tk
r } z$dt|krtt|d	  W dd}~X Y nX d}~t|
d
r|
j| _nt|	 tjrTt|}|jdd}	| dk	r|dkrtj| |	|	 |	| |	|d}
nH|dkrt | |	|	 |	| |	}
|
j!| _ntd|
j}n$t"| |	|	 |	}
d}~|
j#| _|
j$| _|
j%| _|
j&| _|
j'| _|
j(| _njt|	 tj)r| }|jdd}	t*| |	|	 |	}
~n tdt+|	 t+| f t,t||
j|- d|
j	|d.|| _/|
j0| _1dS )z
    :param miller_array: a non-unique array of experimental data
    :param algorithm: merging method (options are "gaussian" or "shelx")
    )r  r[  N)r6  r   r  r#  rI  )rS  )r6  r   )r  z%merge_equivalents_exact: incompatiblez! (mismatch between Friedel mates)n_incompatible_flagsr  )r   r[  z*Programming error (should be unreachable).zOcctbx.miller.merge_equivalents: unsupported array type:
  data: %s
  sigmas: %s)r8   r+   r-   )r6   r   r   )2r!   	_r_linear	_r_square_r_int_r_merge_r_meas_r_pim_inconsistent_equivalentsr  r   r	  r   r)   Zmerge_equivalents_exact_boolZmerge_equivalents_exact_intZmerge_equivalents_complexZmerge_equivalents_hlrP  r)  rM  r+   r   rQ  r^   r   r  r   r   rN  r:   r   Zmerge_equivalents_obsZmerge_equivalents_shelxinconsistent_equivalentsZmerge_equivalents_realr_linearr_squarer_intr_merger_measr_pimr  Zmerge_equivalents_stringreprr#   r-   r3  r  r  _redundancies)r4   rB  r  r  r   r   Zdata_type_strZ
merge_typeZ	asu_arrayr<  Z	merge_extr  Zasu_setr%   r%   r&   r*   q  s    









zmerge_equivalents.__init__c             C   s   | j S )z)
    Return the merged Miller array.
    )r  )r4   r%   r%   r&   r#     s    zmerge_equivalents.arrayc             C   s   | j j| jdS )zq
    Return an array representing the redundancy or multiplicity of each
    reflection in the merged array.
    )r   )r  r#   r
  )r4   r%   r%   r&   r    s    zmerge_equivalents.redundanciesc             C   s   | j dkrdS | jj| j dS )z7R-linear = sum(abs(data - mean(data))) / sum(abs(data))N)r   )r  r  r#   )r4   r%   r%   r&   r    s    
 zmerge_equivalents.r_linearc             C   s   | j dkrdS | jj| j dS )z5R-square = sum((data - mean(data))**2) / sum(data**2)N)r   )r  r  r#   )r4   r%   r%   r&   r    s    
 zmerge_equivalents.r_squarec             C   s   | j S )N)r  )r4   r%   r%   r&   r    s    zmerge_equivalents.r_intc             C   s   | j S )z
    Standard (but flawed) metric of dataset internal consistency.

    .. math::
       R_{merge} = \dfrac{\sum_{hkl}{\sum_{i}{|I_{i}(hkl) - \left \langle I_{i}(hkl) \right \rangle|}}}{\sum_{hkl}{\sum_{i}{I_{i}(hkl)}}}
    )r  )r4   r%   r%   r&   r    s    zmerge_equivalents.r_mergec             C   s   | j S )ao  
    Alternate metric of dataset internal consistency.  Explained in detail in
    Diederichs K & Karplus PA (1997) Nature Structural Biology 4:269-275.

    .. math::
       R_{meas} = \dfrac{\sum_{hkl}{ {\left \{ N(hkl) / [N(hkl) - 1] \right \} }^{1/2} \times \sum_{i}{|I_{i}(hkl) - \left \langle I_{i}(hkl) \right \rangle|}}}{\sum_{hkl}{\sum_{i}{I_{i}(hkl)}}}
    )r  )r4   r%   r%   r&   r    s    zmerge_equivalents.r_measc             C   s   | j S )aX  
    Alternate metric of dataset internal consistency or quality.  Explained in
    detail in Weiss MS (2001) J Appl Cryst 34:130-135.

    .. math::
       R_{meas} = \dfrac{\sum_{hkl}{ {\left \{ 1 / [N(hkl) - 1] \right \} }^{1/2} \times \sum_{i}{|I_{i}(hkl) - \left \langle I_{i}(hkl) \right \rangle|}}}{\sum_{hkl}{\sum_{i}{I_{i}(hkl)}}}
    )r   )r4   r%   r%   r&   r    s    zmerge_equivalents.r_pimc             C   s   | j d kr| j S dS )Nr   )r  )r4   r%   r%   r&   r    s    
z*merge_equivalents.inconsistent_equivalentsc             C   s$   t |   t |    S )N)r   rj  r#   r   r   )r4   r%   r%   r&   r_sigma  s    zmerge_equivalents.r_sigmar  r?   c             C   s  |d krt j}|   }|j|d |jdd}|   dk}|  }|d k	rr||}|	| |jdd}| 
 }	|	d k	r|	|}	|		| |	jdd}
ddddg}|d kr|d n
|d	 |	d kr|d n
|d
 |g}dd |d D }xN|j D ]>}|jj|ddg}|j|}|  | }| dkrd|ddg n(|dt|  |dt|  |j| d kr|d n|d|j|   |d ks|j| d kr|d n|d|j|   |	d ks|
j| d kr|d n|d|
j|   || dd t||D }qW |d k	rrt|| jj |d |	d k	rt|| j
j |d |d k	s|	d k	rt|d |d tt|dd d }dt|d |g|dd    }ddd|d d d   g}x2||	gD ]&}|d kr0|d n
|d qW t||t|   |d dt| }x*|D ]"}t||t|   |d qnW d S )N)r   T)r   r>   r?   ZMinZMaxZMeanzR-linearzR-squarec             S   s   g | ]}t |qS r%   )r]   )ro   fieldr%   r%   r&   rq   %  s    z2merge_equivalents.show_summary.<locals>.<listcomp>r   F)rB   rx   z%dz%.3fz%.4fc             S   s   g | ]\}}t |t|qS r%   )r\   r]   )ro   Zmax_lenr  r%   r%   r&   rq   <  s   )r}   z/In these sums single measurements are excluded.rV   z%%%ds  %%%ds  %%%ds  %%%dsZ
RedundancyrU   r  rT   zMean  z(%%%ds  %%%ds  %%%ds  %%%ds  %%%ds  %%%ds)r~   r   r  rR  r   r  r   r  r   r4  r  rE   r(   rD   r|   r   r.   rp  r   r  r\   r   rA   r  rj  r   rt   rstrip)r4   r   r   r   r  Zred_meanr   r  Zr_l_meanr  Zr_s_meanfieldslinesZmax_lengthsrB   r   rU  rg   r   r%   r%   r&   r     s~     



 
 




 
zmerge_equivalents.show_summary)r  NT)r  Nr?   )r   r   r   r  r*   r#   r  r  r  r  r  r  r  r  r  r   r%   r%   r%   r&   r2  j  s     
]	

r2  c               @   s   e Zd ZdZd"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dZddddgfddZd'd d!ZdS )(r$  aN  
  Container for an FFT from reciprocal space (complex double) into real space.
  Normally this is obtained by calling array.fft_map(...), not instantiated
  directly outside this module.  If the input array is anomalous, the
  resulting map will be a flex.complex_double (with grid accessor), otherwise
  it will be a flex.double.
  Nc          	   C   s2  t j| | | dkst| |  s4t| |  ksHtt|	 t
js\t| | _|  st|  }| }nt|  }| }t jj|  |  | |	 |  t
|dd}|d k	r| d dkstt|| d< d| _|  s|| | _n|| | _d S )N)FTT)r   r-   r<   r  r  Zmap_gridr  r   y                F)r
   r  r   r-   r!   r7   rH  r   r   r   r   r  r   r   r  r  	n_complexr  rg   r  Zto_mapr+   r  r  complex_real_map_accessedbackward	_real_map_complex_map)r4   r  r*  r+  rfftr  Zcfftr  r%   r%   r&   r*   X  s4    


zfft_map.__init__c             C   s   | j S )N)r   )r4   r%   r%   r&   r-   v  s    zfft_map.anomalous_flagTc             C   s:   |   s*| j s|rt|r$d| _| jS t| jS dS )zn
    Extract the real component of the FFT'd map.

    :returns: a flex.double object with grid accessor.
    TN)r-   r  r  r!   r  r   realr  )r4   direct_accessr%   r%   r&   real_mapy  s    zfft_map.real_mapc             C   s0   | j |d}ddlm} |||  | |dS )zQ
     Create a map_manager object from real_map_unpadded version of this map
    )in_placer   )map_manager)r5  unit_cell_crystal_symmetryZunit_cell_gridr#  )r4  Ziotbx.map_managerr  r8   rI  )r4   r  r#  r5  r  r%   r%   r&   r'    s    zfft_map.as_map_managerc             C   sT   |r| j rt| jdd}| s&|S |r:tj|d |S t|t|	 S dS )z
    Extract the real component of the FFT'd map, removing any padding required
    for the FFT grid.

    :returns: a flex.double object with grid accessor.
    F)r  )r  N)
r  r!   r  r  r
   Zunpad_in_placer   r   r  r  )r4   r  r{   r%   r%   r&   r4    s    
 zfft_map.real_map_unpaddedc             C   s   |   st| jS )N)r-   r!   r  )r4   r%   r%   r&   r    s    zfft_map.complex_mapc             C   s   t | jddS )NF)r  )r
   r{  r  )r4   r%   r%   r&   r{    s    zfft_map.statisticsc             C   s*   |   s|  j|9  _n|  j|9  _| S )N)r-   r  r  )r4   r   r%   r%   r&   r    s    zfft_map.apply_scalingc             C   s   | j dt|    dS )Nr>   )r   )r  r   r   r  r  )r4   r%   r%   r&   apply_fourier_scaling  s    zfft_map.apply_fourier_scalingc             C   s   | j d|    dS )z/
    Volume-scale the map values in place.
    r>   )r   )r  r7   r  )r4   r%   r%   r&   r&    s    zfft_map.apply_volume_scalingc             C   s@   |   }| dkr| S d|  }|  r4t|}| j|dS )z.
    Sigma-scale the map values in place.
    r   r>   )r   )r{  r.  r-   r  r  )r4   r{  r   r%   r%   r&   r%    s    zfft_map.apply_sigma_scalingc             C   s   |   j|| jdd|dS )NF)r  )r   r  verify_symmetry)Ztagspeak_searchr  )r4   r   r  r%   r%   r&   r    s    
zfft_map.peak_searchz,Values outside boundaries are wrapped insidezfft_map from Phenixc          
   C   s   ddl m} | jdd}|dkr$d}|dkrRt|  }|dkrRtdd |D }t|d	ksbt|j||  | 	 |||t
|d
 dS )zD
    Write the real component of the map to a CCP4-format file.
    r   )mrcfileF)r  N)r   r   r   c             S   s   g | ]}|d  qS )r>   r%   )ro   rg   r%   r%   r&   rq     s    z'fft_map.as_ccp4_map.<locals>.<listcomp>r  )r   r7   r   gridding_firstgridding_lastr5  r   )rm  r   r  rt   r  r]   r!   Zwrite_ccp4_mapr7   r   r   r  )r4   r   r!  r"  r   r   r5  r%   r%   r&   as_ccp4_map  s     	zfft_map.as_ccp4_mapc             C   sn   ddl m} | jdd}|dkr$d}|dkrRt|  }|dkrRtdd |D }|j||  |||d	 dS )
zD
    Write the real component of the map to a DSN6-format file.
    r   )dsn6F)r  N)r   r   r   c             S   s   g | ]}|d  qS )r>   r%   )ro   rg   r%   r%   r&   rq     s    z'fft_map.as_dsn6_map.<locals>.<listcomp>)r   r7   r!  r"  r5  )rm  r$  r  rt   r  Zwrite_dsn6_mapr7   )r4   r   r!  r"  r$  r5  r%   r%   r&   as_dsn6_map  s    zfft_map.as_dsn6_map)N)T)TT)T)NT)NN)r   r   r   r  r*   r-   r  r'  r4  r  r{  r  r  r&  r%  r  r#  r%  r%   r%   r%   r&   r$  P  s&   




 r$  c             C   sP   t |   }d| tj | }dt ||t |   t |d }|S )NrV   r  )	r   r;  r   r   ry  rz  r/  r0  r   )rL   rB  rk   r   rD  r%   r%   r&   rC    s    (rC  c             C   s   |  st|r$|jdd | }| }|rD|jdd | }t|| t	| 
 d d}|d k	rx|| }t| ||S )NT)r  r>   )r   )Zis_patterson_symmetryr!   r   r  rY  r  r#   r   r   r  r.   r$  )r  rK  r+  rL  rM  Zi_pattr%   r%   r&   rN    s    "rN  c       
      C   s   |d k	r|d kst |d k	r(|d ks(t |d kr8| }dd |D }t| ||d}|d k	rh|j|d}|st|d k	r| }	|	d |j|	d}|d kr|S |j|d|dd	S d S )
Nc             S   s   g | ]}|d  d qS )r>   rT   r%   )ro   r   r%   r%   r&   rq     s    z1structure_factor_box_from_map.<locals>.<listcomp>)r8   r-   r-  )r/   )r   r   r   )r+   TF)r  r  r-   r  )r!   r  rH   r=  r+   rE   r   r  )
r8   r  r  r-   Zinclude_000r+  r/   r-  rL   r+   r%   r%   r&   structure_factor_box_from_map  s0      
 r&  c             C   s   g }|  |  dk} xvt|D ]j}d}|dkr@tt d }d }}t|  |  |  |d}|j}|j	}t
|| }	||	 q W t|| }
|r|
| fS |
S )z
  Implementation of array.cc_one_half, assuming that the reflections are
  already in the ASU.  Because the implementation uses random numbers, the
  function has the option to calculate the mean over multiple trials.
  r   r>   i'  N)r  r  r  seed)r   r   r   r   r  r  r+   r   r  r  r   r  r  rE   rj  r.   )Zunmergedr  r  Zcc_allre  r'  r  r  r  ccr  r%   r%   r&   r  2  s(    r  c               @   s*   e Zd ZdZdddZejdfddZdS )	r  a  
  Container for information about possible systematically absent reflections in
  the array, trying both the current space group and all intensity-equivalent
  groups (i.e. all possible screw axis combinations).  This object would
  normally be instantiated directly from a Miller array, but is self-contained
  to enable saving as part of Xtriage results.

  :param obs: X-ray intensity (preferred) or amplitude array
  Nc             C   s  || _ d| _| d k	st|d}| r<| }d| _| sHt| s\|	 
 }| rl| }| | _| jd k	st| j }| j  }|j| d }g | _d| _d| _x|D ]}||  }||  }t|}	|	| jkr
|	| _t|dkrRt|| jkr2t|| _||}
| j| |
f qt|dkrv| j| df q| j| d f qW d S )NFrI  T)r,   r   )was_filteredinput_amplitudesr   r!   rT  r   rY  r   r   r2  r#   r-   rk  r,   Z&reflection_intensity_equivalent_groupsrj  r  r   r  rL   "space_group_symbols_and_selectionsn_possible_maxZn_found_maxr   r+   rP  r]   r   rE   )r4   r  r)  Z
all_groupsZpoint_groupZcomplete_selrj  Z
absent_selZall_possibleZ
n_possibleabsencesr%   r%   r&   r*   Y  sF    





z!systematic_absences_info.__init__r?   c             C   s0  | j dkrtd|d | S | jr,td|d x| jD ]\}}d}t|t| jkrVd}|dkrxt|d||f  |d q4|d	krt|d
||f  |d q4t|d||f  |d xtt| D ]d\}}| | }|	 | }	d| }
|	dkrt|d|
  |d qt|d|
||	 f  |d qW q4W | S )z
    For each possible space group, show a list of possible systematically
    absent reflections and corresponding I/sigmaI.
    r   zCNo systematic absences possible in any intensity-equivalent groups.)r}   a  Please note that the input data were amplitudes, which means that weaker
reflections may have been modified by French-Wilson treatment or discarded
altogether, and the original intensities will not be recovered.  For best
results, use intensities as input.
r?   z (input space group)Fz%%s%s: no systematic absences possibleNz%s%s: no absences foundz%s%s:z(%4d, %4d, %4d)z  %s: i/sigi = undefinedz  %s: i/sigi = %6.1f)
r,  rA   r*  r+  r^   r,   r   r+   r   r   )r4   r   r   Z
group_infor-  Z
group_noteZi_hklr  r  r.  Zindices_fmtr%   r%   r&   r     s4    


zsystematic_absences_info.show)N)r   r   r   r  r*   r~   r   r   r%   r%   r%   r&   r  O  s   	
'r  )r>   F)N)NNN)NN)NFF)NNFFNN)r>   F)S
__future__r   r   r   Zcctbx.sgtbxr  boost_adaptbx.boost.pythonboostpythonbp	six.movesr   r   
import_extr)   r  r   r	   r
   r   r   r   r   cctbx.array_familyr   rh  r   r  r   libtbx.math_utilsr   r   r   Zscitbx.python_utils.miscr   r   libtbx.str_utilsr   libtbx.utilsr   r   r   r   r   Zlibtbx.table_utils	itertoolsr   r  r  ry  timer~   collectionsr   r   !floating_point_epsilon_double_getr.  Zgenerate_r_free_params_strr'   r(   r   objectr   r   r   r   r;   r:   rH   r  r  r  r#   rF  r|  r2  r  r$  rC  rN  r&  r  r  r%   r%   r%   r&   <module>   s   


 z,

            / 
!^                            7 g .
  
  

