ó
É™xTc           @   sj  d  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 m Z d d l m Z 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 m Z d d l  m! Z! m" Z" d d l m# Z# d d l$ Z d d l% Z d d l& m' Z' d d l( Z( d d l) Z) d d l* Z* d e j+ Z, d „  Z- e. d ƒ \ Z/ Z0 Z1 Z2 d d d g Z3 d e4 f d „  ƒ  YZ5 d e4 f d „  ƒ  YZ6 d e4 f d „  ƒ  YZ7 d e
 j8 f d  „  ƒ  YZ9 d! e4 f d" „  ƒ  YZ: d# e4 f d$ „  ƒ  YZ; d% „  Z< d& e e= e> e> d' „ Z? d( „  Z@ d S()   s{  
Examines a structure for metal ions. Can iterate over all atoms, examining
their density and chemical environment to determine if they are correctly
identified, or if there are better candidate ions that they can be replaced
with.

See mmtbx.ions.build to actually modify the structure, the code in this module
handles ion identification, but only prints out messages to a log.
iÿÿÿÿ(   t   division(   t   find_coordination_geometry(   t   environment(   t   halides(   t   utils(   t
   validationN(   t   common_residue_names_water(   t   sasakit   henke(   t   crystalt   adptbx(   t   flex(   t   col(   t   make_sub_headert   format_valuet   framed_output(   t
   group_argst   adopt_init_argst   Auto(   t   null_outt   Sorry(   t   easy_mp(   t   sqrtsA  
require_valence = False
  .type = bool
  .help = Toggles the use of valence calculations
  .short_caption = Require good bond valence
ambiguous_valence_cutoff = 0.5
  .type = float
  .help = "Cutoff to uniquely select one of many metals by comparing its observed and expected valence"
d_min_strict_valence = 1.5
  .type = float
  .short_caption = Resolution limit for strict valence rules
anom_map_type = *residual simple llg
  .type = choice
  .help = Type of anomalous difference map to use.  Default is a residual     map, showing only unmodeled scattering.
find_anomalous_substructure = Auto
  .type = bool
use_phaser = True
  .type = bool
  .help = Toggles the use of Phaser for calculation of f-prime values.
  .short_caption = Use Phaser to calculate f-double-prime
aggressive = False
  .type = bool
  .help = Toggles more permissive settings for flagging waters as heavier     elements.  Not recommended for automated use.
map_sampling_radius = 2.0
  .type = float
  .input_size = 80
  .short_caption = Sampling radius
water
  .short_caption = Water filtering
  .style = box auto_align
{
  min_2fofc_level = 1.8
    .type = float
    .input_size = 80
    .help = Minimum water 2mFo-DFc map value.  Waters below this cutoff will       not be analyzed further.
    .short_caption = Min. allowed 2mFo-DFc map value
  max_fofc_level = 3.0
    .type = float
    .input_size = 80
    .help = Maximum water mFo-DFc map value
    .short_caption = Max. expected mFo-DFc map value
  max_anom_level = 3.0
    .type = float
    .input_size = 80
    .help = Maximum water anomalous map value
    .short_caption = Max. expected anomalous map value
  max_occ = 1.0
    .type = float
    .input_size = 80
    .help = Maximum water occupancy
    .short_caption = Max. expected occupancy
  min_b_iso = 1.0
    .type = float
    .input_size = 80
    .help = Minimum water isotropic B-factor
    .short_caption = Min. expected B-factor
  fp_max = 1.0
    .type = float
  fpp_max = 0
    .type = float
  max_stddev_b_iso = 5
    .type = float
    .input_size = 80
    .short_caption = Max. standard deviations below mean B-iso
  min_frac_b_iso = 0.2
    .type = float
    .input_size = 80
    .short_caption = Min. fraction of mean B-iso
  min_frac_calpha_b_iso = 0.75
    .type = float
  max_frac_calpha_2fofc = 1.2
    .type = float
  min_2fofc_coordinating = 0.9
    .type = float
    .help = Minimum 2mFo-DFc for waters involved in coordination shells.
}
phaser
  .short_caption = Phaser options
  .caption = These parameters control the identification of anomalous     scatterers using Phaser substructure completion.
  .style = box auto_align
{
  llgc_ncycles = None
    .type = int
    .short_caption = Number of cycles
  distance_cutoff = 1.5
    .type = float
    .input_size = 80
    .short_caption = Min. required separation from other atoms
  distance_cutoff_same_site = 0.7
    .type = float
    .input_size = 80
    .short_caption = Max. separation from mapped atom
  fpp_ratio_min = 0.2
    .type = float
    .input_size = 80
    .help = Minimum ratio of refined/theoretical f-double-prime.
    .short_caption = Min. f-double-prime ratio
  fpp_ratio_max = 1.1
    .type = float
    .input_size = 80
    .help = Maximum ratio of refined/theoretical f-double-prime.
    .short_caption = Max. f-double-prime ratio
}
chloride
  .short_caption = Chloride ions
  .style = box auto_align
{
  %s
}
c           C   s   t  j j t d t ƒS(   Nt   process_includes(   t   libtbxt   philt   parset   ion_identification_phil_strt   True(    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   ion_master_phil–   s    i   t   MGt   CAt   MNt   managerc           B   sp  e  Z d  Z d! d! d! d e d! d „ Z d „  Z d „  Z d! d! e d „ Z	 d „  Z
 d „  Z d „  Z e j d	 „ Z d
 „  Z d d e e d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d d d „ Z d! e d „ Z d „  Z d „  Z d e d „ Z e e e e j d „ Z d „  Z  e j e e d „ Z! e j e d „ Z" e j e d! d  „ Z# RS("   s[   
  Wrapper object for extracting local environment and adding or modifying
  scatterers.
  i   c
         C   s£  |	 d  k r t ƒ  }	 n  | |  _ i  |  _ | |  _ | |  _ | |  _ d  |  _ t |  _	 d  |  _
 d  |  _ d  |  _ t | d d  ƒ |  _ i  |  _ i  |  _ d  |  _ | d  k	 rÆ | j ƒ  j ƒ  |  _ n  |  j d | d | d | d |	 ƒ |  j ƒ  t }
 | d  k	 r| j }
 n  |
 t k r=| j ƒ  j ƒ  o7| d  k	 }
 n  |
 rŸ| d  k rbt d d ƒ ‚ n% | j ƒ  j ƒ  s‡t d d ƒ ‚ n  | j rƒt j j d	 ƒ rƒ|	 d
 IJt j ƒ  } t d | d | d | d | d |	 d | j j ƒ } t j ƒ  } |	 d | | IJ| d  k r"|	 d IJqœ| j  ƒ  |  _ t! |  j ƒ d k rS|	 d IJqœ|	 d t! |  j ƒ IJ|  j" d |	 d t# ƒ qŸt# |  _	 |  j$ d |	 ƒ n  d  S(   Nt   use_svmt   pdb_hierarchyt   xray_structuret   connectivityt   logs   Wavelength required when s!   find_anomalous_substructure=True.s   Anomalous data required when t   phasers+     Running Phaser substructure completion...t   fmodelt
   wavelengtht   verboset   n_cycless       time: %.1fss/     ERROR: Phaser substructure completion failed!i    s      No anomalous scatterers found!s     %d anomalous scatterers found(%   t   NoneR   R(   t   atoms_to_propst   paramsR)   t   nproct   phaser_substructuret   Falset   flag_refine_substructuret   fpp_from_phaser_ax_sitest   site_fpt   site_fdpt   getattrR"   t   _map_valuest   _map_gaussian_fitst   anomalous_flagt   f_obst   update_structuret   update_mapst   find_anomalous_substructureR   R   t
   use_phaserR   t   envt
   has_modulet   timet   find_anomalous_scatterersR'   t   llgc_ncyclest   atomst   lent   analyze_substructureR   t   refine_anomalous_substructure(   t   selfR(   R#   R$   R.   R)   R%   R/   R*   R&   t   refine_substructuret   t1t   phaser_resultt   t2(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   __init__£   sv    
 														

	c         C   sQ   |  j  j ƒ  } d j d j g  t D] } d | ^ q" ƒ ƒ } | j | ƒ j ƒ  S(   sx   
    Fetchs the selection for all waters in the model.

    Returns
    -------
    scitbx.array_family.flex.size_t
    s!   ({}) and element O and altloc ' 's    or s   resname (   R#   t   atom_selection_cachet   formatt   joint   WATER_RES_NAMESt	   selectiont
   iselection(   RH   t	   sel_cachet   it   sel_str(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   water_selectionï   s    )c   	      C   s  d d l  m } |  j j ƒ  } | j d | d |  j d |  j d t d t d t d	 | ƒ } | j j	 ƒ  } t
 j | j ƒ  t ƒ |  _ t
 j | j ƒ  d
 ƒ |  _ t
 j | j ƒ  d
 ƒ |  _ xY | D]Q } xH | j D]= } | | } t |  j | <| j |  j | <| j |  j | <qÒ WqÂ Wd S(   s  
    Run simple "substructure completion" implemented using CCTBX tools (the
    command-line equivalent is mmtbx.refine_anomalous_substructure).  A faster
    alternative to Phaser, but not clear how effective this is at the moment.

    Parameters
    ----------
    log : file
    iÿÿÿÿ(   t   anomalous_scatterer_groupsR(   R#   R)   t   reset_water_u_isoR*   t   use_all_anomaloust   outi    N(   t   mmtbx.refinementRX   R(   t	   deep_copyRG   R#   R)   R   R$   t
   scatterersR   t   boolt   sizeR1   t   use_fdpt   doubleR4   R5   RS   t   fpt   fdp(	   RH   R&   RX   t
   fmodel_tmpt   anom_groupsR^   t   groupt   i_seqt   sc(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRG   ü   s(    
				
c         C   sè  | |  _  | |  _ |  j r4 |  j j | d t ƒn  |  j j ƒ  |  _ |  j j ƒ  |  _ | |  _ | j ƒ  |  _	 |  j	 j
 ƒ  j d ƒ s� t ‚ | j ƒ  |  _ t j | j ƒ  j ƒ  t ƒ |  _ d	 |  _ i  |  _ | j ƒ  |  _ | j ƒ  j ƒ  j ƒ  } d | k pd | k |  _ | j ƒ  } | j d ƒ j ƒ  |  _  | j d ƒ j ƒ  |  _! t" |  j  ƒ d k sjt ‚ |  j# ƒ  } t" | ƒ |  _$ | j d ƒ j ƒ  }	 t" |	 ƒ |  _% |  j j& |	 ƒ }
 t' j( t j) |
 ƒ ƒ |  _* t' j( |
 j+ ƒ  ƒ |  _, d |  _- t" |  j! ƒ d k r9t' j( t j) |  j j& |  j! ƒ ƒ ƒ |  _- n  d	 |  _. |  _/ |  j$ d k r |  j j& | ƒ } t' j( t j) | ƒ ƒ |  _. t' j( | j+ ƒ  ƒ |  _/ n  |  j0 d	 k	 rÂ|  j1 d | ƒ n" |  j2 rä| rä|  j3 d | ƒ n  d	 S(
   s@  
    Set the current atomic data: PDB hierarchy, Xray structure, and simple
    connectivity list.

    Parameters
    ----------
    pdb_hierarchy : iotbx.pdb.hierarchy.root
    xray_structure : cctbx.xray.structure.structure
    connectivity : ...
    log : file, optional
    refine_if_necessary : bool, optional
    t   update_f_calci    t   Ht   Ds	   element Cs   name CA and element Cs   not (element H or element D)R&   N(4   R#   R$   R(   t   update_xray_structureR   t
   sites_fract
   sites_cartR%   RD   t	   pdb_atomst   extract_i_seqt   all_eqt   AssertionErrort	   unit_cellR   R_   R^   R`   R1   Ra   R,   t   ax_chaint   _pair_asu_cachet   extract_u_iso_or_u_equivt	   u_iso_allt   scattering_type_registryt   type_count_dictt   keyst
   hd_presentRN   RR   RS   t
   carbon_selt
   calpha_selRE   RW   t   n_waterst   n_heavyt   selectR
   t   u_as_bt   meant
   b_mean_allt    standard_deviation_of_the_samplet   b_stddev_allt   b_mean_calphat
   b_mean_hoht   b_stddev_hohR0   RF   R2   RG   (   RH   R#   R$   R%   R&   t   refine_if_necessaryt	   sctr_keysRT   t	   water_selt
   not_hd_selt   u_iso_all_tmpt	   u_iso_hoh(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR;     sT    				!			c         C   s*   t  |  d d ƒ d k	 r |  j S|  j Sd S(   sé   
    Calculates the isotropic b-factor to assign to newly labeled ions during the
    building process. Uses either the mean b-factor of waters or of all atoms if
    the former is unavailable.

    Returns
    -------
    float
    Rˆ   N(   R6   R,   Rˆ   R„   (   RH   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   get_initial_b_isoX  s    
c      	   C   sV   |  j  j d | d t d t d |  j ƒ } | d k r: d S| j d d ƒ j ƒ  j ƒ  S(   s¬   
    Creates the real-space version of a given map type.

    Parameters
    ----------
    map_type : str

    Returns
    -------
    scitbx.array_family.flex.double
    t   map_typet   exclude_free_r_reflectionst   fill_missingR#   t   resolution_factorg      Ð?N(   R(   t   map_coefficientsR   R#   R,   t   fft_mapt   apply_sigma_scalingt   real_map_unpadded(   RH   R‘   t
   map_coeffs(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   get_mapg  s    c         C   s
  |  j  d k r d Sd d „ } d d g } d d g } |  j  j ƒ  j ƒ  r­ |  j j d k rn | j d ƒ n/ |  j j d k r� | j d	 ƒ n | j d
 ƒ | j d
 ƒ n  |  j rÓ | j d ƒ | j d ƒ n  |  j j	 ƒ  } |  j j
 ƒ  } d g t | ƒ |  _ d g t | ƒ |  _ i  |  _ d |  _ xdt | | ƒ D]S\ } } |  j | ƒ } | d k	 r?t j | j ƒ  d ƒ |  j | <d g t | ƒ |  j | <x× t | ƒ D]É \ }	 }
 |  j |	 } | j ƒ  j j ƒ  j ƒ  } | t t j j k s| j  j ƒ  j ƒ  d k r¬| j! |
 ƒ } | |  j | |	 <|  j rut" j# d |  j$ d | j% d | ƒ } | |  j | |	 <quq¬q¬W| d k rŒd d l& m' } xô t | ƒ D]ã \ }	 } |  j |	 j ƒ  j j ƒ  } | t t j j k rW| j( d | d | d |  j$ d |  j j) ƒ } | |  j |	 <| j* d | d |  j$ d | d |  j j) ƒ } | |  j |	 <q¢|	 |  j+ k r¢|  j | j! | |	 ƒ 7_ q¢q¢Wn  ~ q?q?W|  j d k rØt |  j+ ƒ } | d k sÆt, ‚ |  j | _ n  d |  _- t |  j. ƒ d k rt j ƒ  |  _- t j | j ƒ  d ƒ |  j d <| |  j  j/ d d d t0 d t0 ƒ ƒ } x² t | ƒ D]¤ \ }	 }
 |  j |	 j ƒ  j j ƒ  } |  j |	 j1 j ƒ  } | d k sº| d k rX| t k rX| j! |
 ƒ } | |  j d |	 <| d k rü|  j- j | ƒ qüqXqXW~ n  d S(   s‘  
    Generate new maps for the current structure, including anomalous map if
    data are anomalous.

    If Phaser is installed and anomalous data are available, the anomalous
    log-likelihood gradient (LLG) map can be used instead of the conventional
    anomalous difference map. This is only really useful if the anomalous
    scattering of existing atoms is modeled (and ideally, refined).
    Ng      Ð?c         S   s   |  j  d | ƒ j ƒ  j ƒ  S(   NR”   (   R–   R—   R˜   (   R™   R”   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR–   ‰  s    s   2mFo-DFcs   mFo-DFcR'   t   llgt   residualt   anom_residualt   anomt   mFoi    t   IONRt   t	   site_cartt   real_mapiÿÿÿÿ(   t   maptbxt   radiusR‘   R’   R“   t   Ct   O(   R    (   s   2mFo-DFc(2   R(   R,   R:   R9   R.   t   anom_map_typet   appendR"   R$   Rn   Ro   RE   t   _principal_axes_of_inertiat   _map_variancesR8   t   calpha_mean_two_fofct   zipRš   R   Rb   R`   R7   t	   enumerateRp   t   fetch_labelst   resnamet   stript   upperRQ   t   mmtbxt   ionst	   SUPPORTEDt   segidt   eight_point_interpolationR   t   fit_gaussianRt   t   xyzt   cctbxR£   t   principal_axes_of_inertiat   map_sampling_radiust   spherical_variance_around_pointR~   Rs   t   carbon_fo_valuesR}   R•   R   t   element(   RH   R–   t	   map_typest   map_keysRn   Ro   R‘   t   map_keyR¢   Rh   t	   site_fract   atomR¯   t   valuet   gaussian_fitR£   R¡   t   p_a_it   variancet   n_calphat   fo_mapR¾   t	   map_value(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR<   }  s¢    
												
	$c         C   sŒ  | d IJ| d IJ| d t  d t j |  j ƒ ƒ IJ|  j d k rc | d t  d |  j ƒ IJn  | d t  d |  j ƒ IJ|  j d k r© | d t  d |  j ƒ IJn  | d	 t  d |  j ƒ IJd } d } |  j ƒ  } | d
 t	 | ƒ IJxd | D]\ } |  j
 | ƒ } | j d k r'| d 7} n  | j d k	 rö | j d k rö | d 7} qö qö W| d | IJ|  j r~| d | IJn  | d IJd S(   sÊ   
    Prints out information about an entire model's scattering statistics, such
    as mean map heights and b-factors for carbons and waters.

    Parameters
    ----------
    out : file, optional
    t    s   Model and map statistics:s"     mean mFo map height @ carbon: %ss   %.2fi    s(     mean 2mFo-DFc map height @ C-alpha: %ss     mean B-factor: %ss     mean C-alpha B-factor: %ss     mean water B-factor: %ss     %d water moleculesg      @i   s)     %d waters have mFo-DFc map >= 3.0 sigmas+     %d waters have anomalous map >= 3.0 sigmaN(   R   R   t   maxR½   R«   R„   R‡   Rˆ   RW   RE   t	   map_statst   fofcRž   R,   R9   (   RH   R[   t   n_water_fofc_peakst   n_water_anom_peaksRŒ   Rh   RÍ   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt"   show_current_scattering_statisticsè  s:    	


	
c         C   s%   |  j  j ƒ  j ƒ  } | |  j j k  S(   s—   
    Checks whether the resolution of a model is high enough to use more strict
    thresholds for ion valences.

    Returns
    -------
    bool
    (   R(   R:   t   d_minR.   t   d_min_strict_valence(   RH   RÒ   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   get_strict_valence_flag  s    	g      @g      ø?c         C   sT  | t  |  j ƒ k  s t ‚ |  j j | d ƒ \ } } } | d k r‹ |  j j d | ƒ } | j ƒ  } | j	 ƒ  } | | | f |  j | <n  t
 j d | d |  j d |  j d | d | d |  j d | d	 | d
 | ƒ 	}	 | rPg  }
 xb |	 D]Z } | j ƒ  t k r6|  j d | j ƒ  } | |  j j j k  r6qé q6n  |
 j | ƒ qé W|
 }	 n  |	 S(   sž  
    Given site in the structure, return a list of contacts, optionally
    filtering by connectivity and 2mFo-DFc map level.

    Parameters
    ----------
    i_seq : int
    far_distance_cutoff : float, optional
    near_distance_cutoff : float, optional
    filter_by_bonding : bool, optional
    fitler_by_two_fofc : bool, optional

    Returns
    -------
    list of mmtbx.ions.environment.atom_contact
    t   distance_cutoffRh   R$   Rp   t   asu_mappingst	   asu_tableR%   t   far_distance_cutofft   near_distance_cutofft   filter_by_bondings   2mFo-DFcN(   NNN(   RE   Rn   Rs   Rv   t   getR,   R$   t   pair_asu_tableRÖ   t   tableR   t   find_nearby_atomsRp   R%   R¯   RQ   R7   t
   atom_i_seqR.   t   watert   min_2fofc_coordinatingR¨   (   RH   Rh   RØ   RÙ   RÚ   t   filter_by_two_fofcRÜ   RÖ   R×   t   contactst   filteredt   contactt   two_fofc(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRÞ     s<    									c         C   s€   |  j  | d d ƒ} t | ƒ d k r; t j |  j | ƒ Sd } x% | D] } | |  j | j ƒ  7} qH Wt j | t | ƒ ƒ S(   sb  
    Guess an approximate B_iso for an atom by averaging the values for
    coordinating atoms.  This should partially compensate for the deflation of
    the B-factor due to incorrect scattering type, and consequently make the
    occupancy refinement more accurate.

    Parameters
    ----------
    i_seq : int

    Returns
    -------
    float
    RØ   g      @i    (   RÞ   RE   R
   R‚   Rx   Rß   (   RH   Rh   Rã   t	   u_iso_sumRå   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   guess_b_iso_realQ  s    c         C   s   |  j  | S(   s&  
    Extracts the map grid points around a site, and calculates the axes of
    inertia (using the density values as weights). This is used to calculate
    the sphericity of the blob of density around a site.

    Parameters
    ----------
    i_seq : int

    Returns
    -------
    ...
    (   R©   (   RH   Rh   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRº   h  s    c         C   s   |  j  | S(   s  
    Calculate the density levels for points on a sphere around a given point.
    This will give us some indication whether the density falls off in the
    expected manner around a single atom.

    Parameters
    ----------
    i_seq : int

    Returns
    -------
    float
    (   Rª   (   RH   Rh   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   get_map_sphere_variancex  s    c         C   s,   |  j  j ƒ  | } t j | j |  j ƒ ƒ S(   sˆ   
    Calculates the isotropic b-factor of a site.

    Parameters
    ----------
    i_seq : int

    Returns
    -------
    float
    (   R$   R^   R
   R‚   t   u_iso_or_equivRt   (   RH   Rh   Ri   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt	   get_b_isoˆ  s    c         C   sd   |  j  d | } |  j  d | } d } d |  j  k rK |  j  d | } n  t d | d | d | ƒ S(   s6  
    Given a site in the structure, find the signal of the 2FoFc, FoFc, and
    anomalous map (When available).

    Parameters
    ----------
    i_seq : int

    Returns
    -------
    group_args
        Object with .two_fofc, .fofc, and .anom properties for the associated
        signals in each map.
    s   2mFo-DFcs   mFo-DFcRž   Ræ   RÎ   N(   R7   R,   R   (   RH   Rh   t   value_2fofct
   value_fofct
   value_anom(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRÍ   —  s    c         C   s-   |  j  j | d ƒ } | d k	 r) | | Sd S(   sß   
    Retrieves the two parameters of a gaussian function, fit to a given map at
    a site.

    Parameters
    ----------
    map_type : str
    i_seq : int

    Returns
    -------
    (tuple of float, float) or None
    N(   R8   RÛ   R,   (   RH   R‘   Rh   t   map_gaussians(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   get_map_gaussian_fit°  s    c         C   s_   |  j  j d d ƒ } | d k r% d S| | } t j |  j ƒ } | d k sS t ‚ d | | S(   sÖ   
    Guesses the molecular weight of a site by scaling the signal from
    the mFo map by the average signal from carbon atoms.

    Parameters
    ----------
    i_seq : int

    Returns
    -------
    float
    RŸ   i    i   N(   R7   RÛ   R,   R   Rƒ   R½   Rs   (   RH   Rh   t
   map_valuest   heightt   mean_carbon(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   guess_molecular_weightÃ  s     
g      à?c         C   sá  |  j  j d | ƒ } t j | g ƒ } |  j j d | d ƒ } | j | d |  j j ƒ  ƒt j	 d | d | ƒ } |  j j
 ƒ  j ƒ  } g  }	 g  }
 x| D]} | j | k  rÀ | j | k  sœ | j | k rä | j | k rä qœ n  | j | ƒ } | j | ƒ } | j ƒ  j | ƒ } | | } |  j  j d | ƒ } | j | k  rN| j n | j } t d | d	 | d
 | d t | j ƒ ƒ } | j | k  r |	 j | ƒ qœ |
 j | ƒ qœ W|	 j d d „  ƒ |
 j d d „  ƒ |	 |
 f S(   s[  
    Given an XYZ coordinate, finds atoms near that site, separating out those
    which are close enough to be essentially equivalent.  Used to analyze the
    anomalously-scattering substructure calculated by Phaser.

    Parameters
    ----------
    site_cart : tuple of float, float, float
    distance_cutoff : float, optional
    distance_cutoff_same_site : float, optional

    Returns
    -------
    same_atoms : list of group_args
        List of atoms within distance_cutoff_same_site of site_cart, and and
        other_atoms, the rest of the atoms within distance_cutoff of site_cart.
    R¡   t   buffer_thicknessgš™™™™™¹?t   min_distance_sym_equivRÖ   RÕ   RÂ   Rh   t   rt_mxt   new_site_cartt   distancet   keyc         S   s   |  j  S(   N(   Rù   (   t   x(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   <lambda>  s    c         S   s   |  j  S(   N(   Rù   (   Rû   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRü     s    (   Rt   t   fractionalizeR   t   vec3_doubleR$   RÖ   t   process_sites_fracRö   R	   t   neighbors_fast_pair_generatorR^   R`   Rh   t   j_seqt   get_rt_mx_it   get_rt_mx_jt   inverset   multiplyt   orthogonalizeR   R   t   dist_sqRù   R¨   t   sort(   RH   R¡   RÕ   t   distance_cutoff_same_siteRÂ   Rn   RÖ   t   pair_generatort   n_xrayt
   same_atomst   other_atomst   pairt   rt_mx_it   rt_mx_jt   rt_mx_jit   new_site_fracRø   t   atom_seqt	   site_info(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   _find_atoms_near_site×  sB    		
!c   
      C   s  d „  } |  j  d k	 s t ‚ t j |  j j ƒ  d ƒ |  _ | d k sO | r[ t ƒ  } n  d „  } t	 d d | ƒx‚|  j  D]w} | | | ƒ IJ|  j
 | j d |  j j j d |  j j j ƒ\ } } | | ƒ | | ƒ } } t | ƒ d k rD| d	 | | ƒ IJxé | D]- } | d
 |  j | j j ƒ  | j f IJqWq~ t | ƒ d k r²| d | | ƒ |  j | d j j ƒ  f IJt |  j | d j <| j |  j | d j <q~ | d | | ƒ IJx, | D]$ }	 | d |  j |	 j j ƒ  IJqÍWq~ W| d IJd S(   sà   
    Given a list of AX pseudo-atoms placed by Phaser, finds the nearest real
    atoms, and if possible determines their equivalence.

    Parameters
    ----------
    log : file, optional
    verbose : bool, optional
    c         S   s   d |  j  j ƒ  |  j f S(   sv   
      Parameters
      ----------
      atom : iotbx.pdb.hierarchy.atom

      Returns
      -------
      str
      s   AX %s (fpp=%.3f)(   t   serialR°   t   occ(   RÃ   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt
   ax_atom_id  s    
iÿÿÿÿc         S   sô   d d l  m } | ƒ  } xD |  D]< } | j | k rL | | j j | ƒ q  | g | | j <q  Wxp | j ƒ  D]b } t d „  | Dƒ ƒ r¼ x0 | D]% } | j j ƒ  s� | j | ƒ q� q� Wn  | j	 d d „  ƒ qm Wg  | j ƒ  D] } | d ^ qà S(   s…   
      Parameters
      ----------
      site_infos : list of group_args

      Returns
      -------
      list of group_args
      iÿÿÿÿ(   t   OrderedDictc         s   s   |  ] } | j  j ƒ  Vq d  S(   N(   R÷   t
   is_unit_mx(   t   .0RU   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pys	   <genexpr>B  s    Rú   c         S   s   |  j  S(   N(   Rù   (   Rû   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRü   F  s    i    (
   t   collectionsR  Rh   R¨   t   valuest   anyR÷   R  t   removeR  (   t
   site_infosR  t   i_seqsR  t   valRU   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   _filter_site_infos-  s    	s'   Analyzing Phaser anomalous substructureR[   RÕ   R	  i    s     No match for %ss       %s (distance = %.3f)i   s     %s maps to %ss     ambiguous results for %s:s       %sRË   N(   R0   R,   Rs   R   Rb   Rp   R`   R3   R   R   R  R¸   R.   R'   RÕ   R	  RE   Rh   t   id_strRù   R   Ra   R  (
   RH   R&   R*   R  R#  RÃ   R  R  t
   other_atomt	   same_atom(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRF     s8    
	 		''&c         C   sQ   |  j  | s d S|  j d k r+ |  j | S|  j | } | d k  rM d } n  | S(   s  
    Retrieve the refined f'' for a site.  Because this can come from either the
    built-in anomalous refinement or Phaser, it is handled differently than
    the f' retrieval.

    Parameters
    ----------
    i_seq : int

    Returns
    -------
    float or None
    i    N(   Ra   R,   R3   R5   (   RH   Rh   t   fpp(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   get_fppd  s     	c         C   s,   |  j  d k s |  j | r! d S|  j  | S(   s‡   
    Retrieve the refined f' for a site.

    Parameters
    ----------
    i_seq : int

    Returns
    -------
    float or None
    N(   R4   R,   Ra   (   RH   Rh   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   get_fpz  s    t   CLc         C   s0  |  j  | } |  j j ƒ  } | j ƒ  t j j k s: t ‚ |  j d k	 rf | j
 |  j |  j k rf t S|  j | d d d t ƒ} t j d | d | d |  j  d |  j j ƒ  d |  j d	 |  j d
 |  j j d | ƒ } |  j | ƒ } |  j | ƒ }	 t }
 |	 d k	 r,|	 j d k  r,|	 j d k  r,t }
 n  | S(   sS  
    Given a site, analyze the nearby atoms (taking geometry into account) to
    guess whether it might be a halide ion.  Among other things, halides will
    often be coordinated by amide hydrogens, and not in close contact with
    negatively charged atoms.  Note that this procedure has a very high
    false positive rate when used by itself, so additional information about
    the electron count (map, occ, b) is absolutely essential.

    Parameters
    ----------
    i_seq : int
    element : str
    assume_hydrogens_all_missing : bool, optional

    Returns
    -------
    bool
    RØ   g      @RÚ   Rh   Rã   Rp   Rn   Rt   R%   R.   t   assume_hydrogens_all_missingg      ø?gš™™™™™Ù?N(   Rp   R$   Rn   R±   R²   R³   t   HALIDESRs   Rˆ   R,   t   bR‰   R1   RÞ   R   t   is_favorable_halide_environmentRt   R%   R.   t   chlorideRº   Ré   Rƒ   t   standard_deviationR   (   RH   Rh   R¾   R+  RÃ   Rn   t   nearby_atomst   favorable_environmentt   pait   map_variancet   good_map_falloff(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   looks_like_halide_ionŠ  s6    							c   '         sO  ˆ j  | } | t k } | r. t j j } n9 t | t ƒ sL t | t ƒ rg | j d d ƒ j	 ƒ  } n  g  | D] } | j
 ƒ  j ƒ  ^ qn } | d g k r¤ g  } n  | j ƒ  j j
 ƒ  j ƒ  }	 |	 t k sÑ t ‚ ˆ j | ‰  d: }
 ˆ  j d ˆ j j d ˆ j j ƒ } | t k rd: Sˆ j s(t ‚ g  ‰ t } ˆ  j ƒ  } t j } ˆ j d: k	 rmt j ˆ j ƒ } n  x | D]} t j j j  | ƒ } | d: k rÌ| t j j! k r¹t" } qtqÌt# d | ƒ ‚ n  | t$ t% g k rð| d; k rðqtn  | r| t& k rqtn  t' j( | j ƒ  ƒ j) ƒ  | j* } | d k rKˆ  j+ d k rKqtn  ˆ  j, t | d ƒ } | d k  r| t$ k rqtn  ˆ j- | ƒ qtWt" ‡  ‡ ‡ f d † } | d t" ƒ \ } } t" } t. | ƒ d k rˆ j j/ r| d t ƒ \ } } t. | ƒ d k rt } qn  t } | p0| t0 k  p0| sst1 | ƒ j2 t j j! ƒ } g  } xÏ | D]Ç } ˆ  j3 d t j j4 d | d d ƒ d ˆ j5 d ˆ j j6 j7 d ˆ j j6 j8 ƒ } | d: k	 rú| d k rú| ˆ j j6 j7 k  s[| ˆ j j6 j8 k rúq[qún  ˆ j9 d | d | ƒ r[| j- | ƒ q[q[Wt. | ƒ d k } | g  | D]' } t j j4 d | d d ƒ d f ^ qB7} n  t. | ƒ d k rŒˆ j j/ rŒg  ˆ D]! } ˆ  j: t | ƒ ƒ r™| ^ q™} x,| D]$} t' j( | j; ƒ j) ƒ  }  d }! ˆ  j, d: k	 rˆ  j, |  | j* }! n  | j; t j j< k r­| t0 k r­| r­ˆ  j= | ƒ r­ˆ  j> | d d ƒ}" ˆ  j? d ƒ }# |" d k rëd |# k o�d k n rë| j- | d f ƒ qëqÇ| j; d< k rU| t0 k rU| rUˆ  j= | ƒ rUˆ  j> | d d" d# d$ g ƒ}" ˆ  j@ d% d" ƒ }$ ˆ  j? d% d" ƒ }# |" |$ d k rë|# d& k rë| j- | d f ƒ qëqÇ|  d' k rÇ| t0 k rÇ|! d( k r…|! d) k  s”ˆ  jA d* k rÇ| rÇˆ  j= | d+ ˆ jB ƒ  ƒrÇˆ  j? d ƒ }# |# d, k rë| j- | d f ƒ qëqÇqÇWt. | ƒ d k rŒˆ jB ƒ  rŒˆ  jC t | ƒ }% | d ˆ  jD k r‰ˆ  jE |% k r‰|% j2 ˆ  jF ˆ  jG g ƒ r‰tH | jI ƒ  ƒ tH ˆ ƒ tH | ƒ q‰qŒn  t. | ƒ d k r¯| d d }
 n  | r÷| r÷ˆ jJ d | d- | d. t" d/ | ƒ }& |& jK d: k	 r÷|& Sn  tL d0 ˆ  d1 ˆ d2 | d3 | d4 | d5 | d6 | d7 ˆ j jM d8 | d9 |
 d ˆ j5 d. | ƒ S(=   s+  
    Examines the environment around a single atom to determine if it is actually
    a misidentified metal ion.

    no_final is used internally, when candidates is not Auto, to try all of the
    Auto without selecting any as a final choice when none of the elements in
    candidates appear to probable ion identities.

    Parameters
    ----------
    i_seq : int
    debug : bool, optional
    candidates : list of str, optional
    no_file : bool, optional
    out : file, optional

    Returns
    -------
    mmtbx.ions.identify.water_result
    t   ,t    t   XR.   t
   aggressives   Element '%s' not supported!t   NAR   t   Ft   NEi   gš™™™™™¹?i   gš™™™™™Ù?c      
      sÒ   g  } g  } x¹ ˆ D]± } ˆ  j  d | d ˆ j d |  ƒ ˆ  j d | d ˆ j d ˆ j j j d ˆ j j j ƒ t | ƒ } ˆ  j d | ƒ rª | j	 | ˆ  j
 | f ƒ q | j	 | ˆ  j
 | f ƒ q W| | f S(   sá   
      Parameters
      ----------
      require_valence : bool, optional

      Returns
      -------
      list of tuple of mmtbx.ions.metal_parameters, float
      list of tuple of mmtbx.ions.metal_parameters, float
      t
   ion_paramsR)   t   require_valencet   fpp_ratio_mint   fpp_ratio_maxt   identity(   t   check_ion_environmentR)   t   check_fpp_ratioR.   R'   R@  RA  t   strt   is_correctly_identifiedR¨   t   score(   R?  t
   reasonablet   unreasonablet   elem_paramsRB  (   t
   atom_propst   filtered_candidatesRH   (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   try_candidates$  s"    				R?  i    R>  R¾   t   chargeiÿÿÿÿR)   R@  RA  R*  Rh   Rù   gš™™™™™@gffffff@i   i   t   KR   g333333@t   exclude_atomsR¦   RÕ   i   i   g      à?gÍÌÌÌÌÌð?i
   t   ignore_valencei   t   debugt   no_finalR[   RK  RL  t   matching_candidatest   rejected_candidatest   nuc_phosphate_sitet	   atom_typet   looks_like_halidet   ambiguous_valence_cutofft   valence_usedt   final_choiceN(   R;  R   R<  R=  (   RO  R   (N   Rp   R   R²   R³   t   DEFAULT_IONSt
   isinstanceRE  t   unicodet   replacet   splitR°   R±   R®   R¯   RQ   Rs   R-   R,   t   get_atom_typeR.   Rà   R:  t
   WATER_POORR"   R1   t$   looks_like_nucleotide_phosphate_sitet   syst   maxintR½   R   RÌ   t   servert   get_metal_parametersR,  R   R   t   WATERt	   LIGHT_IONt   NUC_PHOSPHATE_BINDINGR   RÝ   t   atomic_numberRN  R'  t   estimated_weightR¨   RE   R?  t	   HEAVY_IONt   sett   intersectionRD  t   metal_parametersR)   R'   R@  RA  R6  t   has_compatible_ligandsR¾   t   TRANSITION_METALSt   is_compatible_sitet!   number_of_favored_ligand_residuest   number_of_atoms_within_radiust   number_of_backbone_oxygensRc   RÔ   t   inaccuraciest
   fpp_ratiost   BAD_FPPt   BAD_GEOMETRYt   NO_GEOMETRYt   _PRINT_DEBUGR$  t   analyze_waterR[  t   water_resultRY  ('   RH   Rh   RR  t
   candidatesRS  R[   RÃ   t   auto_candidatesRU   R¯   R[  RW  t   halide_candidatesRV  t   max_carbon_fo_map_valuet   symbolt   elemt   n_elect
   mass_ratioRM  RH  RI  RZ  RX  t   candidate_halidest   filtered_halidesR¾   t	   fpp_ratiot   halideR.   t
   compatibleR>  Rk  t   weight_ratiot
   n_good_rest   n_total_coord_atomst   n_bb_oxygenRw  t   result(    (   RK  RL  RH   sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR}  Ã  s   %		"!				5!		(				
			c   	      C   sÕ   |  j  j ƒ  } g  } x¹ | j ƒ  D]« } x¢ | j ƒ  D]” } | j ƒ  } t | ƒ d k r_ q5 n  xg | D]_ } | j j ƒ  j ƒ  } | t	 k rf | j
 ƒ  } t | ƒ d k rÅ | j | d j ƒ qÅ qf qf Wq5 Wq" W| S(   Ni   i    (   R#   t
   only_modelt   chainst   residue_groupst   atom_groupsRE   R¯   R°   R±   RQ   RD   R¨   Rh   (	   RH   t   modelt   water_i_seqst   chaint   residue_groupR”  t
   atom_groupR¯   RD   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   _extract_watersÂ  s    &c      
      s8  ˆ  j  ƒ  } | d IJ| d t | ƒ IJt | ƒ d k r@ d St j ˆ  j ƒ } g  } t ‡  f d †  | Dƒ ƒ ˆ  _ | d k rL| d IJx˜| D]± } t j ƒ  } ˆ  j d | d | d	 | d
 | ƒ }	 |	 d k	 r9|	 j
 d
 | d | ƒ ˆ  j | ƒ }
 |	 j d k	 r9|	 j r9| j | |	 j g |
 j f ƒ q9n  t j ƒ  } q” WnÜ | d | IJ| d IJt d ˆ  d | d	 | d
 | ƒ } t j d | d | d | ƒ } x‚ | D]z } | d k rÂqªn  | \ } } } | d k	 rê| | IJn  | d k	 rªˆ  j | ƒ }
 | j | | g |
 j f ƒ qªqªWt | d „  ƒ S(   sø  
    Iterates through all of the waters in a model, examining the maps and local
    environment to check their identity and suggest likely ions where
    appropriate.

    Parameters
    ----------
    out : file, otpional
    debug : bool, optional
    candidates : list of str, optional

    Returns
    -------
    list of tuple of int, mmtbx.ions.metal_parameters
        i_seq and metal parameters which indicate that waters of i_seq would be
        better changed to that new metal identity.
    RË   s     %d waters to analyzei    Nc         3   s$   |  ] } | t  | ˆ  ƒ f Vq d  S(   N(   t   AtomProperties(   R  Rh   (   RH   (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pys	   <genexpr>ê  s   i   Rh   RR  R  R[   s#     Parallelizing across %d processesR!   t
   fixed_funct   argst	   processesc         S   s   t  | d |  d ƒ S(   Ni   (   t   cmp(   t   aR-  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRü     s    (   RW   RE   R   t   get_processesR/   t   dictR-   RA   R}  R,   t   show_summaryRÍ   R[  RS  R¨   Ræ   t   _analyze_water_wrappert   pool_mapt   sorted(   RH   R[   RR  R  t   watersR/   R³   t   water_i_seqRJ   t   water_propsRÍ   RL   R}  t   resultsR�  R[  t
   result_str(    (   RH   sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   analyze_watersÒ  s\    
 
		

			#c   	   	   C   sC  |  j  | } t j j j | j ƒ } t j j j | ƒ } | d
 k	 r½ | j d |  j	 j
 ƒ } | j d | d |  j d |  j	 j ƒ | j d | d |  j d |  j	 j j d |  j	 j j ƒ n‚ | t j j k r | j ƒ  } t ƒ  | j | <|  j d | d | ƒ s?| j | j | j ƒ q?n t d	 | | j j ƒ  f ƒ ‚ | S(   sè   
    Examines one site in the model and determines if it was correctly modelled,
    returning a boolean indicating correctness.

    Parameters
    ----------
    i_seq : int
    out : file, optional
    debug : bool, optional
    R.   R>  R)   R?  R@  RA  Rh   R¾   s   Element '%s' not supported:
%sN(   R-   R²   R³   Rf  t   get_elementRÃ   Rg  R,   Ra  R.   Rà   RC  R)   R?  RD  R'   R@  RA  R,  RB  Rn  Rw  R6  t   addt
   BAD_HALIDER   t   format_atom_record(	   RH   Rh   R[   RR  RK  R¾   RJ  RW  RB  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   validate_ion  s,    				c            s§  | d k r× g  } xï ˆ j j ƒ  D]® } x¥ | j ƒ  D]— } xŽ | j ƒ  D]€ } xw | j ƒ  D]i } | j j ƒ  t j	 j
 k r[ | j ƒ  }	 t |	 ƒ d k s  t ‚ x! |	 D] }
 | |
 j f 7} q§ Wq[ q[ WqH Wq5 Wq" Wn- ˆ j j ƒ  } | j d j | ƒ ƒ j ƒ  } t | ƒ d k rd Sg  } t ‡ f d †  | Dƒ ƒ ˆ _ x? | D]7 } ˆ j d | d | ƒ } | j | | j ƒ  f ƒ qFWˆ j j ƒ  } d# } d } t | d d d d ƒ} | | | IJ| d d d IJxÂ| D]º\ ‰  } ˆ  j j } | | } d } } | j j r(| j } | j } n  t  j! | j" d ˆ j# ƒ ƒ } ˆ  j$ ƒ  } d „  } | | ˆ  j j% d t& ƒ d d !| d ˆ  j j' ƒ | d | ƒ | d ˆ  j( ƒ | d ˆ  j) ƒ | d | ƒ | d | ƒ | d ˆ j* d k rêd n4 | t+ j, t j	 j- j. ˆ  j ƒ ƒ j/ ˆ j* ƒ j ƒ  ƒ | d ˆ  j0 j1 | ƒ ƒ | d ˆ  j2 j1 | ƒ ƒ f
 IJ| s‹| d  j3 ‡  f d! †  ˆ  j4 | Dƒ ƒ IJn  | d" IJqÛW| j5 ƒ  d S($   s  
    Iterate over all the ions built into the model by this module and double
    check their correctness. Looks for tell-tale signs such as negative peaks
    in the mFo-DFc and anomalous difference maps, abnormal b-factor, and
    disallowed chemical environments.

    Prints out a table of bad ions and their information and returns a list of
    their sites' i_seqs.

    Parameters
    ----------
    out : file, optional
    debug : bool, optional
    segid : str, optional
        If present, only validate ions with this segid.
    i   s	   segid {0}i    Nc         3   s$   |  ] } | t  | ˆ  ƒ f Vq d  S(   N(   R›  (   R  Rh   (   RH   (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pys	   <genexpr>a  s   Rh   RR  RÃ   R  t   b_isos   2mFo-DFcs   mFo-DFcRc   Rd   t   ratiot   BVSt   VECSUMs9   %-15s %-5s  %-5s  %-8s  %-7s  %-5s  %-5s  %-5s %-5s  %-6st   titles   Validating new ionst   widthiP   R8  t   -iK   Rt   c         S   s   t  |  | d d ƒS(   Nt   replace_none_withs   ---(   R   (   t   fsR"  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   ffy  s    t   suppress_segidi   iÿÿÿÿs   %.2fs   
c         3   s    |  ] } d  ˆ  j  | Vq d S(   s   !!! N(   t
   error_strs(   R  RU   (   t   props(    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pys	   <genexpr>„  s   RË   (
   s   atoms   occs   b_isos   2mFo-DFcs   mFo-DFcs   fps   fdpR³  R´  Rµ  (6   R,   R#   t   modelsR’  R“  R”  R¯   R°   R²   R³   R´   RD   RE   Rs   Rh   RN   RR   RO   RS   R¢  R-   R±  R¨   RF  R$   R^   R   RÃ   t   flagst
   use_fp_fdpRc   Rd   R
   R‚   Rê   Rt   RB  R$  R   R  t
   peak_2fofct	   peak_fofcR)   R   RÝ   Rf  R­  t   at_angstromt   valence_sumRÛ   t
   vector_sumRP   Rw  t   close(   RH   R[   RR  Rµ   R³   R•  R—  R˜  R™  RD   RÃ   RT   t
   ion_statusRh   RK  R^   t   headerst   fmtt   boxt	   okay_flagRi   Rc   Rd   R²  RB  R»  (    (   R¾  RH   sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   validate_ions<  sj    *		 

		 $.N($   t   __name__t
   __module__t   __doc__R,   R1   RM   RW   RG   R   R;   R�   Rš   R<   Rd  t   stdoutRÑ   RÔ   RÞ   Rè   Rº   Ré   Rë   RÍ   Rð   Rô   R  RF   R(  R)  R   R6  R}  Rš  R¬  R±  RÍ  (    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR!   �   sP   C		!;			k'	4							9Q		8ú	C'R¤  c           B   s    e  Z d  Z d „  Z d „  Z RS(   sÖ   
  Simple wrapper for calling manager.analyze_water with keyword arguments
  in a parallelized loop.  Because the water_result object is not pickle-able,
  we only return the final ion choice and summary string.
  c         K   s   | |  _  t | ƒ |  _ d  S(   N(   R!   R¢  t   kwds(   RH   R!   RÒ  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRM   �  s    	c         C   sÐ   y· |  j  j | |  j � } t j ƒ  } | d  k	 r[ | j d | d |  j j d t ƒ ƒ n  | j	 ƒ  } | d k r| d  } n  d  } t
 | d t ƒ s© t
 | d d  ƒ } n  | | | f SWn t k
 rË d SXd  S(   NR[   RR  RË   RS  R[  (   NNN(   R!   R}  RÒ  t	   cStringIOt   StringIOR,   R£  RÛ   R1   t   getvalueR6   t   KeyboardInterrupt(   RH   Rh   R�  R[   R«  R[  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   __call__“  s     	(   RÎ  RÏ  RÐ  RM   R×  (    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR¤  ‰  s   	t   _validate_ion_wrapperc           B   s    e  Z d  Z d „  Z d „  Z RS(   sÕ   
  Simple wrapper for calling manager.validate_ion with keyword arguments
  in a parallelized loop.  Because the water_result object is not pickle-able,
  we only return the final ion choice and summary string.
  c         K   s   | |  _  t | ƒ |  _ d  S(   N(   R!   R¢  RÒ  (   RH   R!   RÒ  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRM   «  s    	c         C   s?   y& |  j  j | |  j � } | | f SWn t k
 r: d SXd  S(   N(   NN(   R!   R±  RÒ  RÖ  R,   (   RH   Rh   t   correct(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR×  ¯  s
    (   RÎ  RÏ  RÐ  RM   R×  (    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRØ  ¥  s   	t
   ion_resultc           B   sH   e  Z d  Z e j j d d g Z e j d d „ Z e j d d „ Z	 RS(   s®   
  Class for validation results for an ion site. This includes information about
  both the atom modeled at that site as well as its chemical and scattering
  environment.
  t   chem_envt   scatter_envRË   c         C   s   d  S(   N(    (   RH   R[   t   prefix(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   show¾  s    c         C   s   d  S(   N(    (   RH   R[   RÝ  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt
   show_briefÁ  s    (
   RÎ  RÏ  RÐ  R   RÃ   t	   __slots__Rd  RÑ  RÞ  Rß  (    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRÚ  ¶  s   R~  c           B   s,   e  Z d  Z d e d „ Z d e d „ Z RS(   sc   
  Container for storing the results of manager.analyze_water for later display
  and retrieval.
  c         C   s   t  |  t ƒ  ƒ d  S(   N(   R   t   locals(   RH   RK  RL  RT  RU  RV  RW  RX  RY  RZ  R[  R)   RS  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRM   Ê  s    c      	   C   s~  | d k r t j } n  |  j } t | ƒ d k rP|  j j d d d | ƒ |  j rb | d IJn  |  j r” | d t | ƒ d k rŠ d n d	 IJn  |  j	 d k	 r| d \ } } | j
 t j j k rü |  j j d t |  j	 ƒ d | d
 |  j d t ƒ n | d It | ƒ IJ| d	 IJqzt | ƒ d k rzg  | D]! \ } } | |  j k  r8| ^ q8} t | ƒ d k rÁ| d } | d t | ƒ IJ|  j j d t | ƒ d | d
 t ƒ | d	 IJqMg  t | d d „  ƒD] } t | d ƒ ^ q×} | d d j | ƒ IJx3 | D]+ \ } } |  j j d t | ƒ d | ƒ qW| d	 IJqzn*|  j t k sh|  j rz|  j j d d d | ƒ |  j r—| d IJn  |  j rÄ| d t |  j	 ƒ IJ| d	 IJqz| rmt |  j ƒ d k rm| d IJt }	 x{ |  j D]m }
 |  j j t |
 ƒ ƒ rR|	 r0| d IJt }	 n  |  j j d t |
 ƒ d | ƒ qù| d t |
 ƒ IJqùWn  | d	 IJn  d S(   s¢   
    Prints out a summary of a site's chemical and scattering environment.

    Parameters
    ----------
    out : file, optional
    debug : bool, optional
    i    RB  t   HOHR[   s,     appears to be nucleotide coordination sites1     Found potential ion%s outside of specified set:i   t   sRË   RZ  t	   confirmeds     Probable anion:s(     ambigous results, best valence from %sRú   c         S   s   |  d S(   Ni   (    (   Rû   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRü     s    s      ambiguous results, could be %ss   , s     Probable cation: %ss$     insufficient data to identify atoms     possible candidates:s     incompatible ligands for %sN(   R,   Rd  RÑ  RT  RE   RK  t   show_propertiesRV  RS  R[  R¾   R²   R³   R,  t   show_ion_resultsRE  RZ  R   RY  R¦  RP   RW  Rh  RX  RL  Rq  R1   (   RH   R[   RR  Rª  RJ  RG  t   below_cutoffRU   R³   t   possibleR.   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR£  Ù  sr    	 			"	

2		

	
N(   RÎ  RÏ  RÐ  R,   R1   RM   R£  (    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR~  Å  s   R›  c           B   sé  e  Z d  Z e d ƒ \ Z Z Z Z Z Z	 Z
 Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z i d e 6d e 6d e 6d e 6d e 6d e	 6d e
 6d	 e 6d
 e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6d e 6Z d „  Z d0 d „ Z  d „  Z! e" e# d „ Z$ d d1 d  „ Z% d! „  Z& d d" „ Z' d# „  Z( d$ „  Z) d0 e" d% „ Z* d& d' d( „ Z+ e, j- d) „ Z. d0 e, j- e# e" d* „ Z/ d+ d, d- „ Z0 d0 d. „ Z1 e# d/ „ Z2 RS(2   s™   
  Collect physical attributes of an atom, including B, occupancy, and map
  statistics, and track those which are at odds with its chemical identity.
  i   s   Abnormally low b-factors   Abnormally high b-factors   Abnormally low occupancys   Abnormally high occupancys   No 2mFo-DFc map peaks   Peak in mFo-DFc maps   Negative peak in dFo-mFc maps   Peak in the anomalous maps   No peak in the anomalous maps*   Unexpected geometry for coordinating atomss+   No distinct geometry for coordinating atomss   VECSUM above cutoffs   BVS above or below cutoffs$   Too few non-water coordinating atomss   Too few coordinating atomss   Too many coordinating atomss   Like charge coordinating likes   Disallowed coordinating atoms   Bad refined f'' values   Disallowed coordinating residues   BVS far above or below cutoffs   Bad halide sites    Unexpectedly high 2mFo-DFc valuesI   No distinct geometry and coordinating another atom with distinct geometrys   Close contact to oxygen atomc         C   s7  | |  _  | j | j ƒ  |  _ |  j j j ƒ  j ƒ  |  _ | j j ƒ  j	 ƒ  |  _	 | j j ƒ  j
 ƒ  |  _
 | j ƒ  |  _ | j d | d d ƒ } g  |  _ g  } x^ | D]V } | j d k r§ |  j j | ƒ x. | D] } | | k rÓ PqÓ qÓ W| j | ƒ q§ q§ Wt j |  j ƒ |  _ t | ƒ |  _ | j | ƒ } | j |  _ | j |  _ | j |  _ | j | ƒ |  _ | j | ƒ |  _  | j! |  _! | j" |  _" | j# |  _# | j$ |  _$ i  |  _% i  |  _& i  |  _' i  |  _( i  |  _) i  |  _* i  |  _+ i  |  _, i  |  _- | j. | ƒ |  _/ i  |  _0 | j1 | ƒ |  _2 | |  _3 d  S(   NRh   RØ   g      @Rk   Rl   (   Rk   Rl   (4   Rh   Rp   R®   RÃ   R¯   R°   R±   R(   R:   RÒ   R9   RÔ   t   strict_valenceRÞ   R1  R¾   R¨   R   t   count_coordinating_residuest   residue_countsR   t
   geometriesRÍ   Ræ   RÂ  RÎ   RÃ  Rž   t	   peak_anomRô   Rl  Rë   R²  Rˆ   R‰   R‡   R«   Rw  t   ignoredt   vectorsRÅ  RÆ  RG  t   fpp_expectedt   expected_paramst
   bad_coordsR(  R'  Rx  R)  Rc   R!   (   RH   Rh   R!   t   nearby_atoms_unfilteredt   nearby_atoms_no_altsRå   t   otherRÍ   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRM   U  sX    														c         C   s2   | d k r |  j ƒ  } n  t |  j | ƒ d k S(   sÁ   
    Calculates whether factors indicate that the atom was correctly identified.

    Parameters
    ----------
    identity : mmtbx.ions.metal_parameters

    Returns
    -------
    bool
    i    N(   R,   RB  RE   Rw  (   RH   RB  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRF  Œ  s    c         C   s-   t  |  j | ƒ d k o, |  j |  j | k S(   s'  
    Indicates whether the coordinating atoms are of the allowed type (e.g.
    no N or S atoms coordinating CA, etc.) and residue (e.g. Ser is not an
    appropriate ligand for ZN).

    Parameters
    ----------
    identity : mmtbx.ions.metal_parameters

    Returns
    -------
    bool
    i    (   RE   Rò  t   BAD_COORD_RESIDUERw  (   RH   RB  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRq  �  s    c         C   su   |  j  t | ƒ } |  j | ƒ p& | } |  j t | ƒ ƒ ot |  j | k ot | sb |  j | k ot |  j | k ot | S(   s=  
    More minimal criteria for determining whether a site is chemically
    compatible, allowing for incomplete coordination shells.

    Parameters
    ----------
    ion_params : mmtbx.ions.metal_parameters
    require_anom : bool, optional
    ignore_valence : bool, optional

    Returns
    -------
    bool
    (   Rw  RE  t"   is_compatible_anomalous_scatteringRq  t   TOO_MANY_COORDt   VERY_BAD_VALENCESRö  (   RH   R>  t   require_anomRQ  Rw  t   anom_allowed(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRs  ®  s    g      @c   
      C   sÃ   d } g  } x° |  j  D]¥ } | j ƒ  | k r4 q n  | j ƒ  | k  r | j j ƒ  } | j ƒ  } | j | j ƒ  }	 | j d k	 r» | | j k r» |	 | k r» | d 7} | j
 |	 ƒ q» q q W| S(   s<  
    Counts the number of preferred residues coordinating the atom.  Used for
    approximate detection of transition-metal binding sites.

    Parameters
    ----------
    ion_params : mmtbx.ions.metal_parameters
    distance : float, optional
    exclude_atoms : tuple of ...

    Returns
    -------
    int
    i    i   N(   R1  t	   atom_nameRù   RÃ   R®   R¯   t   chain_idt   residt   allowed_coordinating_residuesR,   R¨   (
   RH   R>  Rù   RP  t   n_rest   residsRå   t   labelst   other_resnamet   other_resid(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRt  Ç  s    
c         C   sk   d } g  } xX |  j  D]M } | j ƒ  } | | k r | j ƒ  | k  rS | d 7} n  | j | ƒ q q W| S(   s’   
    Counts the number of coordinating atoms within a given radius.

    Parameters
    ----------
    float

    Returns
    -------
    int
    i    i   (   R1  t   atom_id_no_altlocRù   R¨   (   RH   RÕ   t   n_atomst   atom_idsRå   t   other_id(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRu  ç  s    c         C   sg   d } xZ |  j  D]O } | j ƒ  d k r | j ƒ  | k r_ | j ƒ  t k r\ | d 7} q\ q_ q q W| S(   sª   
    Counts the number of backbone oxygens coordinating a site.

    Parameters
    ----------
    distance_cutoff : float, optional

    Returns
    -------
    int
    i    R¦   i   (   R1  Rü  Rù   R¯   RQ   (   RH   RÕ   t   n_bb_oxRå   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRv  ý  s    c         C   s¤   | j  j ƒ  d k r@ |  j d  k o? |  j d  k	 o? |  j d k  S|  j d  k rk |  j d  k	 oj |  j d k S|  j d | ƒ } | |  j k r  |  j |  j | k St	 S(   NR   R;  g      ð?g      @t   ion(   s   MGs   NA(
   R¾   R±   R'  R,   Rí  RB  Rx  Ry  Rw  R1   (   RH   R>  RB  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR÷    s    c         C   s­   |  j  t k r d n	 |  j ƒ  } | d k rM |  j j | j | j k rM d S|  j d | ƒ rc d S|  j |  j	 | k s‹ |  j j d k  r� d S|  j
 |  j	 | k r© d Sd S(   s0  
    Evaluates whether factors indicate that the atom is lighter, heavier, or
    isoelectric to what it is currently identified as.

    Parameters
    ----------
    manager : mmtbx.ions.identify.manager

    Returns
    -------
    int
        -1 if lighter, 0 if isoelectronic, and 1 if heavier.
    Râ  i    RB  i   iÿÿÿÿ(   R¯   RQ   RB  RÃ   R-  Rˆ   R‰   RF  t	   FOFC_PEAKRw  t	   FOFC_HOLE(   RH   R!   RB  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   atom_weight!  s    !(c         C   sk  d d l  m } |  j | ƒ } t ƒ  } |  j | <| |  j | <t ƒ  } |  j | <| p� |  j d d ƒ p� |  j p� | j	 d k } d }	 g  }
 xŸ t
 |  j ƒ D]Ž \ } } | j ƒ  } | d k  r  xg |  j | d	 D]+ } | | k sý | j | ƒ d
 k rÖ PqÖ qÖ W|
 j | ƒ | d k  r.|	 d	 7}	 q.q  q  Wt |
 ƒ | j k  rZ| j |  j ƒ n  |	 | j k r|| j |  j ƒ n  d } g  |  j | <x(|  j D]} | j ƒ  } | j ƒ  } | j	 } | t k r™| d	 7} n q™| j ƒ  d k  r™| j d k	 r3| | j k r3|  j | j | ƒ | j |  j ƒ n  | | ƒ d k r| d k r®| j d k so| | j k r®| d k r‡| j r‡q®|  j | j | ƒ | j |  j ƒ n  | j d k	 r³| j } | | k r| d k r|  j | j | ƒ | j |  j ƒ qq³q¶t  d t! j" j# j$ | j% ƒ ƒ t  d | j& ƒ k re|  j | j | ƒ | j |  j' ƒ q¶| j& d k r¶| d k r¶| d  k r¶|  j | j | ƒ | j |  j' ƒ q¶q™q™W| | j( k  rÜ| j |  j) ƒ n  | j* rs| rsg  |  j+ D] } | d | j* k ^ qõ} d | j* k r&qs|  j+ sK| rp| j |  j, ƒ qpqst- | ƒ sj| j |  j. ƒ qst/ } n  |  j+ g  k rïxj |  j D]\ } | j% } | j0 |  j1 j2 k rŒ|  j1 j2 | j0 j+ } | g  k rè| j |  j3 ƒ qèqŒqŒWn  t! j" j# j4 | |  j ƒ } | |  j5 | <t6 g  | D] } t7 | ƒ ^ q!ƒ |  j8 | <t7 t6 | t9 d! ƒ ƒ ƒ |  j: | <|  j: | | j; k r§| r”| j |  j< ƒ q§| j |  j< ƒ n  |  j8 | | j= d k  sÛ|  j8 | | j= d k rî| j |  j> ƒ nX |  j8 | | j? k  s|  j8 | | j@ k rF| r3| j |  jA ƒ qF| j |  jA ƒ n  t7 |  j8 | | j= ƒ |  jB | <d S("   s±  
    Checks whether or not the specified ion satisfies the metal-coordination
    parameters, specified by ion_params, such as valence sum, geometry, etc.
    The criteria used here are quite strict, but many of the analyses are
    saved for later if we want to use looser critera.

    Parameters
    ----------
    ion_params : mmtbx.ions.metal_parameters
    wavelength : float, optional
    require_valence : bool, optional
    iÿÿÿÿ(   t   common_residue_names_get_classRB  Râ  R;  R   i    g      @i   g333333Ó?gš™™™™™@t   common_amino_acidR¥   t   NR¦   R   Rk   t   HAt   OXTt   LYSt   ARGt   ASNt   GLNR  g      Ð?g      ô?N(   s   NAs   MG(   R¥   R  R¦   s   CARk   R  (   R¥   R¦   R  s   CAR  (   R  (   R  R  R  R  (   i    i    i    (C   t	   iotbx.pdbR  RB  Rn  Rw  Rñ  Rî  RF  Ré  R¾   R­   R1  Rù   t   distance_fromR¨   RE   t   coord_num_lowerR®  t   TOO_FEW_COORDt   coord_num_upperRø  Rò  Rü  R¯   RQ   t   allowed_coordinating_atomsR,   t   BAD_COORD_ATOMt   allowed_backbone_atomst   is_carboxy_terminusRÿ  Rö  RŸ  R²   R³   Rf  t
   get_chargeRÃ   RN  t
   LIKE_COORDt   min_coordinating_non_waterst   TOO_FEW_NON_WATERSt   allowed_geometriesRì  R{  R  Rz  R1   Rh   R!   R-   t   COORDING_GEOMETRYt   calculate_valencesRï  t   sumt   absRÅ  R   RÆ  t   vec_sum_cutofft   BAD_VECTORSt   cvbs_expectedRù  t
   cvbs_lowert
   cvbs_uppert   BAD_VALENCESRG  (   RH   R>  R)   R?  t	   get_classRB  Rw  Rî  t   strict_rulest	   n_closestt   coord_atomst   i_pairt   contact1Rù   t   contact2t   n_non_waterRå   t
   other_nameR  t   other_elementt   allowedRU   t   o_atomt
   o_geometryRï  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRC  >  sÊ    			&			,"g333333Ó?gÍÌÌÌÌÌð?c   	      C   sÊ  t  | ƒ } |  j j | d ƒ } | d k rD t ƒ  } |  j | <n  | j j ƒ  d	 k r� |  j d k	 sw |  j d k rº| j	 |  j
 ƒ qºn-| d k	 rº|  j rºt j | j ƒ j | ƒ j ƒ  } t j | j ƒ j | ƒ j ƒ  } t | | ƒ |  j | <|  j d k	 r‚|  j | d k r‚|  j |  j | |  j | <|  j | | k sl|  j d k r·|  j | | k  r·| j	 |  j
 ƒ q·qº|  j | d k rº|  j d k  rº| j	 |  j
 ƒ qºn  |  j j | ƒ S(
   s/  
    Compare the refined and theoretical f'' values if available.

    Parameters
    ----------
    ion_params : mmtbx.ions.metal_parameters
    wavelength : float
    fpp_ratio_min : float, optional
    fpp_ratio_max : float, optional

    Returns
    -------
    float
        f'' / f''_expected
    R   R;  i   i    gš™™™™™É?g      è?i   N(   s   MGs   NA(   RE  Rw  RÛ   R,   Rn  R¾   R±   R'  Rí  R®  Ry  R9   R   RÝ   RÄ  Rd   R   RÌ   Rð  Rx  (	   RH   R>  R)   R@  RA  RB  Rw  t   fpp_expected_sasakit   fpp_expected_henke(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRD  ï  s.    ""c         C   s}  | d |  j  j ƒ  IJd } |  j |  j | k r< d } n |  j |  j | k r[ d } n  | d |  j  j | f IJd } |  j |  j | k rš d } n |  j |  j | k r¹ d } n  | d |  j  j | f IJd } |  j	 |  j | k rø d } n |  j
 |  j | k rd } n  | d |  j | f IJd } |  j |  j | k rSd } n |  j |  j | k rrd } n  | d |  j | f IJ|  j d k	 röd } |  j |  j | k r½d } n |  j |  j | k rÜd } n  | d	 |  j | f IJn  |  j d k	 r| d
 |  j IJn  |  j d k	 rƒd } |  j d k rFd } n  | d |  j | f IJ| d t d |  j j | ƒ ƒ IJn  |  j d k	 ryd j d d ƒ }	 d j d d ƒ }
 | d t g  |  j D] } | j ƒ  d k  rÊ| ^ qÊƒ |	 f IJx4 |  j D]) } | d | j ƒ  | j ƒ  |	 f IJqW|  j ry| d IJx1 |  j D]# \ } } | d | | |
 f IJqLWqyn  d S(   s³   
    Show atomic properties that are independent of the suspected identity.

    Parameters
    ----------
    identity : mmtbx.ions.metal_parameters
    out : file, optional
    s   %s:RË   s    <<<s    !!!s     B-factor:      %6.2f%ss     Occupancy:     %6.2f%ss     2mFo-DFc map:  %6.2f%ss     mFo-DFc map:   %6.2f%ss     Anomalous map: %6.2f%ss     Approx. mass:  %6dgš™™™™™É?s     f'':           %6.2f%ss     f'' ratio:     %ss   %6.2fu   â„«s   utf-8t   strictu   Â°s"     Nearby atoms: (%d within 3.0 %s)i   s       %s (%5.3f %s)s     Coordinating geometry:s%       %-15s (average deviation: %.3f%s)N(   RÃ   R$  t   LOW_BRw  t   HIGH_BR-  t   LOW_OCCt   HIGH_OCCR  t   NO_2FOFC_PEAKt
   HIGH_2FOFCRÂ  R  R  RÃ  Rí  R,   t	   ANOM_PEAKt   NO_ANOM_PEAKRl  R'  R   Rx  RÛ   R1  t   encodeRE   Rù   Rì  (   RH   RB  R[   t   b_flagt   occ_flagt   twofofc_flagt	   fofc_flagt	   anom_flagt   fpp_flagt   angstromt   degreeRU   Rå   t   geometryt	   deviation(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRå     sl    												; 	
c         C   s.  | s |  j  |  j ƒ } n  |  j j | t g  ƒ ƒ } |  j j | t g  ƒ ƒ } | |  j  ƒ  k r‹ | rz | d | IJq¢ | d | IJn | d |  j j ƒ  IJ| |  j k r|  j | d k	 r|  j	 | k pß |  j	 | k } | d |  j | | rÿ d n d f IJn  | |  j
 k r�|  j
 | d k	 r�| j | ƒ j |  j |  j g ƒ } | d |  j
 | IJ| r�| d |  j | j | r�d n d f Iq�n  |  j | k r¹| d	 IJn  |  j | k rÕ| d
 IJn  |  j |  j |  j g } | j | ƒ r…| d t |  j | ƒ d k r"d n d IJd j d d ƒ j ƒ  }	 xA |  j | D]/ \ }
 } | d |
 j ƒ  t | ƒ |	 f IJqOWn  |  j | k r¡| d IJn  |  j | k r½| d IJn  |  j | k rÙ| d IJn  |  j d k	 r*| |  j k r*| d |  j | |  j  | k rd n d f IJn  d S(   sÞ   
    Show statistics for a proposed element identity.

    Parameters
    ----------
    identity : mmtbx.ions.metal_parameters
    out : file, optional
    confirmed : bool, optional
    valence_used : bool, optional
    s     Probable cation: %ss     Atom as %s:s       %s:s       Vector sum:  %6.3f %ss    !!!RË   s       Valence sum: %6.3fs   (expected: %6.3f) %ss       No distinct geometry !!!s       Unexpected geometry  !!!s       Bad coordinating atom%s:i   Rã  u   Ã…s   utf-8R>  s       %s (%5.3f %s) !!!s'       Too few coordinating non-waters !!!s"       Too few coordinating atoms !!!s#       Too many coordinating atoms !!!s       f'' ratio:   %6.3f%sN(!   RB  RÃ   Rw  RÛ   Rn  Rî  R$  RÆ  R,   R*  RÅ  t   unionRo  R.  Rù  Rñ  R+  R{  Rz  R!  R  Rö  RE   Rò  RG  R°   R(  R#  R  Rø  R'  Rx  Ry  (   RH   RB  R[   Rä  RZ  Rw  Rî  t   problemt	   bad_coordRN  RÃ   t   vector(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRæ  c  sT    "#")&#i   g      @c         C   sœ   d } x‰ |  j  D]~ } | j ƒ  } t | ƒ d k  s | j d k rI q n  | d d !d k r | d d k r | j ƒ  | k rŽ | d 7} qŽ q q W| | k S(   s  
    Decide whether the atom is coordinating phosphate oxygens from a
    nucleotide, based on common atom names.

    Parameters
    ----------
    min_phosphate_oxygen_atoms : int, optional
    distance_cutoff : float, optional

    Returns
    -------
    bool
    i    i   R¦   i   t   O1t   O2t   O3t   At   Bt   Gi   (   R¦   (   RV  RW  RX  (   RY  RZ  R[  (   R1  Rü  RE   R¾   Rù   (   RH   t   min_phosphate_oxygen_atomsRÕ   t   n_phosphate_oxygensRå   Rü  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRc  ©  s    !c         C   sR   | d k r |  j } n  t j j j | ƒ } t j j j | ƒ } d j | | ƒ S(   s¸   
    Covers an atom into a string representing its element and charge.

    Parameters
    ----------
    ion : iotbx.pdb.hierarchy.atom, optional

    Returns
    -------
    str
    s   {}{:+}N(   R,   RÃ   R²   R³   Rf  R­  R   RO   (   RH   R
  R¾   RN  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRB  Ä  s
    c         C   s  t  ƒ  } |  j d <t } |  j | j k  s; |  j d k  r? t S|  j d k	 rd |  j | j	 k rd t
 S|  j d k	 r‰ |  j | j k r‰ t
 S|  j | j k r´ | j |  j ƒ t
 } n  |  j | j k rß | j |  j ƒ t
 } n  |  j j | j k r| j |  j ƒ t
 } n  |  j j | j k  r;| j |  j ƒ t
 } n® |  j d k	 ré|  j d k ré|  j |  j |  j } | | j k  r“| j |  j ƒ n/ |  j j |  j | j k  rÂ| j |  j ƒ n  | t k ré|  j | k rét } qén  | r’| t k r’|  j  d k rE|  j |  j  } | | j! k  rE| j |  j ƒ t } qEn  |  j" d k r’|  j |  j" } | | j# k r�| j |  j$ ƒ t } q�q’n  xu t% |  j& ƒ D]d \ } }	 |	 j' j( ƒ  d k r¢|	 j) ƒ  }
 |
 d k  r| j |  j* ƒ | t k  rt } qqq¢q¢W| S(   sè  
    Checks the atom characteristics against what we would expect for a water.
    Updates self with any inaccuracies noticed (Surpringly low b-factor,
    high occupancy, etc).  Note that HEAVY_ION does not necessarily rule out
    NA/MG, as these often have mFo-DFc peaks at high resolution.

    Parameters
    ----------
    params : libtbx.phil.scope_extract
    aggressive : bool, optional

    Returns
    -------
    int
        One of WATER, WATER_POOR, HEAVY_ION, LIGHT_ION
    Râ  g       Ài    R¦   g333333@N(+   Rn  Rw  Rh  RÂ  t   min_2fofc_levelRÃ  Rb  R'  R,   t   fpp_maxRm  Rc   t   fp_maxRí  t   max_anom_levelR®  RE  t   max_fofc_levelR  RÃ   R  t   max_occRB  R-  t	   min_b_isoR?  R‰   R²  Rˆ   t   max_stddev_b_isot   min_frac_b_isoRi  R‡   t   min_frac_calpha_b_isoR«   t   max_frac_calpha_2fofcRD  R­   R1  R¾   R°   Rù   t   CLOSE_CONTACT(   RH   R.   R:  Rw  RW  t   z_valuet
   relative_bt   relative_2fofcR3  R4  Rù   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRa  Ö  s`    !!				N(    (3   RÎ  RÏ  RÐ  t   rangeR?  R@  RA  RB  RC  R  R  RE  RF  Rz  R{  R*  R.  R#  R  Rø  R!  R  Ry  Rö  Rù  R¯  RD  R%  Ri  R½  RM   R,   RF  Rq  R   R1   Rs  Rt  Ru  Rv  R÷  R  RC  RD  Rd  RÑ  Rå  Ræ  Rc  RB  Ra  (    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR›  ,  sd   W
	7				±-C	Fc          O   sS   t  j j d ƒ s3 d | k r/ | d d IJn  d Sd d l m } | j |  | Ž  S(   sg   
  Wrapper for corresponding method in phaser.substructure, if phaser is
  available and configured.
  R'   R&   s   Phaser not availableiÿÿÿÿ(   t   substructureN(   R   R?   R@   R,   R'   Rn  RB   (   R�  RÒ  Rn  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyRB   	  s    g      Ð?c
         C   sn   | j  d j ƒ  }
 |	 d k r( t }	 n  |	 d | d |  d | j d |
 d | d | d | d	 | d
 | ƒ 	} | S(   sR  
  Wrapper around mmtbx.ions.identify.manager init method. Retrieves the
  connectivity and xray_structure from fmodel automatically.

  Parameters
  ----------
  pdb_hierarchy : iotbx.pdb.hierarchy.root
  geometry_restraints_manager : cctbx.geometry_restraints.manager.manager
  fmodel : mmtbx.f_model.manager
  wavelength : float
  params : libtbx.phil.scope_extract
  resolution_factor : float, optional
  nproc : int, optional
  verbose : bool, optional
  log : file, optional
  manager_class : class, optional

  Returns
  -------
  mmtbx.ions.identify.manager or mmtbx.ions.svm.manager
  i    R(   R#   R$   R%   R)   R.   R/   R*   R&   N(   t   shell_sym_tablest   full_simple_connectivityR,   R!   R$   (   R#   t   geometry_restraints_managerR(   R)   R.   R”   R/   R*   R&   t   manager_classR%   t   manager_obj(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   create_manager*	  s    !			c          G   s   t  j t  j I|  IJd S(   s+   
  Prints a debugging message to stderr.
  N(   Rd  t   stderr(   R�  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyR|  Z	  s    (A   RÐ  t
   __future__R    t   mmtbx.ions.geometryR   t
   mmtbx.ionsR   R   R   R²   R   R  R   RQ   t   cctbx.eltbxR   R   R¹   R	   R
   t   scitbx.array_familyR   t   scitbx.matrixR   t   libtbx.str_utilsR   R   R   R   R   R   R   t   libtbx.utilsR   R   R   t   libtbx.load_envt   libtbx.philt   mathR   RÓ  RA   Rd  t   chloride_params_strR   R   Rm  Rh  Rb  Ri  Rm  Rj  t   objectR!   R¤  RØ  RÃ   RÚ  R~  R›  RB   R1   R,   Rt  R|  (    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/identify.pyt   <module>
   sZ   s	ÿ ÿ ÿ ÿ ðgÿ ÿ ô	&