ó
Ë™xTc           @   s2  d  d l  m Z d  d l m Z d  d l m Z m Z m Z m Z d  d l	 Z	 d  d l
 m Z d  d l m Z m Z d  d l m Z d  d l m Z m Z d  d	 l m Z d  d
 l m Z d  d l m Z e	 j d „ Z d „  Z d „  Z d d d d d d „ Z  d e d d „ Z! d d „ Z" d d „ Z# d S(   iÿÿÿÿ(   t   division(   t   defaultdict(   t   cost   pit   sint   sqrtN(   t   crystal(   t   sasakit   chemical_elements(   t   common_residue_names_water(   t   null_outt   xfrange(   t   server(   t   flex(   t   gaussian_fit_1d_analyticalc         C   sñ  t  t j ƒ  ƒ } x1 t j d D]" } | t k r  | j | ƒ q  q  Wd } |  j ƒ  }  xŒ|  j ƒ  D]~} xu| j	 ƒ  D]g} x^| j
 ƒ  D]P} xG| j ƒ  D]9} | j j ƒ  | k rž | j ƒ  }	 g  }
 x³ |	 D]« } | j j ƒ  } | d k rü d } n* | d k rd } n t j | ƒ j ƒ  } |
 j | j ƒ  ƒ | j | _ d | _ d	 | _ d
 | _ d | _ | j d | | _ qÒ Wd | _ xJ t |	 |
 ƒ D]6 \ } } | d | | j ƒ  | j f IJ| d 7} qšWqž qž Wq‹ Wqx Wqe W|  | f S(   sQ  
  Convert any elemental ions in the PDB hierarchy to water, resetting the
  occupancy and scaling the B-factor.  The atom segids will be set to the old
  resname.  NOTE: this does not change the corresponding scatterer in the xray
  structure, but a new xray structure can be obtained by calling
  hierarchy.extract_xray_structure(crystal_symmetry).

  Parameters
  ----------
  pdb_hierarchy : iotbx.pdb.hierarchy.root
  log : file, optional

  Returns
  -------
  iotbx.pdb.hierarchy.root
      New pdb hierarchy with its ions anonymized
  int
      Number of atoms that were anonymized.
  s   _lib_charge.resnamei    t   Ht   Di   t   HEi   s    O  t   Ot    g      ð?i
   t   HOHs   %s --> %s, B-iso = %.2f(   R   R   (   R   (   t   setR   t   proper_upper_listR   t   paramst   WATER_RES_NAMESt   addt	   deep_copyt   modelst   chainst   residue_groupst   atom_groupst   resnamet   stript   atomst   elementR   t   tablet   atomic_numbert   appendt   id_strt   segidt   namet   charget	   occupancyt   bt   zip(   t   pdb_hierarchyt   logt   ion_resnamesR   t   n_convertedt   modelt   chaint   residue_groupt
   atom_groupR!   t   id_strst   atomt   elemR$   R&   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   anonymize_ions   sB    							!c         C   sr   |  j  ƒ  | j ƒ  j  ƒ  k s$ t ‚ |  j ƒ  t |  d d „  d t ƒ} t j g  | D] } | j ^ qV ƒ } | S(   sN  
  Creates a list of atoms in pdb_atoms, sorted first by their atomic number,
  then by occupancy, and finally, by isotropic b-factor.

  Parameters
  ----------
  pdb_atoms : iotbx.pdb.hierarchy.af_shared_atom
  xray_structure : cctbx.xray.structure.structure

  Returns
  -------
  flex.size_t of int
      i_seqs of sorted atoms
  t   keyc         S   s1   t  j |  j j ƒ  j ƒ  ƒ j ƒ  |  j |  j f S(   N(   R   R#   R"   R    t   upperR$   t   occR+   (   t   x(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   <lambda>Z   s    t   reverse(	   t   sizet
   scattererst   AssertionErrort   reset_i_seqt   sortedt   TrueR   t   size_tt   i_seq(   t	   pdb_atomst   xray_structuret   atoms_sortedR6   t   sele(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   sort_atoms_permutationG   s    $
		%c   	      C   sÌ   t  j ƒ  } g  } x³ |  j ƒ  D]¥ } xœ | j ƒ  D]Ž } x… | j ƒ  D]w } xn | j ƒ  D]` } | j j ƒ  | k rX | j ƒ  } t	 | ƒ d k s— t
 ‚ x | D] } | j | ƒ qž WqX qX WqE Wq2 Wq W| S(   s±   
  Collects a list of all ions in pdb_hierarchy.

  Parameters
  ----------
  pdb_hierarchy : iotbx.pdb.hierarchy.root

  Returns
  -------
  list of iotbx.pdb.hierarchy.atom
  i   (   R   R   R   R   R   R   R   R    R!   t   lenRA   R%   (	   R-   t   elementst   ionsR1   R2   R3   R4   R!   R6   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   collect_ionsa   s    $g       @s	   segid IONc   %      C   s  | d k r t ƒ  } n  |  j ƒ  } | }	 t | ƒ d k rm |	 d d j g  | D] }
 d |
 ^ qO ƒ 7}	 nC t | ƒ d k r° |	 d d j g  | D] }
 d |
 ^ q’ ƒ 7}	 n  | j |	 ƒ j ƒ  } t | ƒ d k rá g  g  f S|  j ƒ  } | j ƒ  | j	 | ƒ } | j
 d | d ƒ } | j ƒ  } | j ƒ  } | j d | ƒ } | j | d	 | j ƒ  ƒt j d
 | d | ƒ } | j ƒ  } | j ƒ  j ƒ  } g  } x' t t | ƒ ƒ D] } | j g  ƒ q®WxÀ | D]¸ } | j | k  rð| j | k  sÌ| j | k r| j | k rqÌn  | j | k  r9| j | j } } n | j | j } } | | | } t | j ƒ } | | } | | j | ƒ qÌWg  } g  } xjt | ƒ D]\\ } }  | | }! t |  ƒ d k ró| d |! j ƒ  IJ| j |! j ƒ  ƒ q¡g  }" xL |  D]D } | | }# |! j j ƒ  |# j j ƒ  k r |" j |# j ƒ  ƒ q q Wt |" ƒ d k rÖ| j |! j ƒ  ƒ t |" ƒ d k rµ| d |! j ƒ  IJx= |" D] }$ | d |$ IJqšWqý| d |! j ƒ  |" d f IJq¡| d |! j ƒ  IJ| j |! j ƒ  ƒ q¡W| | f S(   s�  
  Compares two pdb structures to determine the number of ions that appear in the
  reference structure and are either matched or missing in the other structure.

  Parameters
  ----------
  hierarchy : iotbx.pdb.hierarchy.root
  reference_hierarchy : iotbx.pdb.hierarchy.root
  reference_xrs : ...
  distance_cutoff : float, optional
  log : file, optional
  ignore_element : iterable, optional
  only_elements : iterable, optional
  sel_str_base : str, optional

  Returns
  -------
  int
      Number of ions in reference_hierarchy that were also found in hierarchy.
  int
      Number of ions in reference_hierarchy that were not found in hierarchy.
  i    s	    and (%s)s    or s
   element %ss    and not (%s)t   buffer_thicknessgš™™™™™¹?t
   sites_cartt   min_distance_sym_equivt   asu_mappingst   distance_cutoffs   No match for %si   s   Multiple matches for %s:s     %ss   Ion %s matches %sN(   t   NoneR
   t   atom_selection_cacheRL   t   joint	   selectiont
   iselectionR!   RB   t   selectRS   t	   unit_cellt   extract_xyzt   fractionalizet   process_sites_fracRR   R   t   neighbors_fast_pair_generatorR@   R?   t   rangeR%   RF   t   j_seqR   t   dist_sqt	   enumerateR&   R"   R:   (%   t	   hierarchyt   reference_hierarchyt   reference_xrsRT   R.   t   ignore_elementst   only_elementst   sel_str_baset	   sel_cachet   sel_strt   et   ion_iselRG   RN   RS   R[   RQ   t
   sites_fract   pair_generatort   reference_atomst   n_xrayt   ion_ref_i_seqst   kt   pairt   ion_seqt   ref_seqt	   site_fract   dxyzRa   t   matchedt   missingRF   t
   ref_i_seqst   iont   ref_ionst   ref_atomt   ref_ion(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   compare_ions{   s‚    %%

			


gš™™™™™É?i   c         C   sô   |  g } d g } xÕ t  | | | ƒ D]Á } x¸ t  t t | ƒ D]£ } xš t  t t | ƒ D]… } | t | ƒ t | ƒ |  d }	 | t | ƒ t | ƒ |  d }
 | t | ƒ |  d } | j |	 |
 | f ƒ | j | ƒ qY Wq? Wq% W| | f S(   s  
  Generates a list of points and their associated radius in steps around a
  sphere.

  Parameters
  ----------
  point : tuple of float, float, float
      X, Y, Z, coordinates to center the sampling around.
  radius : float
      Max radius around the center to sample.
  radius_step : float, optional
      Steps along the radius to use when sampling.
  angle_step : float, optional
      Steps around each radii distance to use when sampling. Amount is in
      radians.

  Returns
  -------
  list of tuple of float, float, float
      List of points to be sampled.
  list of float
      List of radii corresponding to each point.
  i    i   i   (   R   R   R   R   R%   (   t   pointt   radiust   radius_stept
   angle_stept   pointst   radiusest   rt   thetat   phiR<   t   yt   z(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   _get_points_within_radiusÜ   s    		""gš™™™™™ù?c         C   së   t  | | ƒ \ } } g  | D] } | j |  j | ƒ ƒ ^ q } t j ƒ  t j ƒ  } }	 xF t | | ƒ D]5 \ }
 } | d k ri | j |
 ƒ |	 j | ƒ qi qi Wy t d | d |	 ƒ } Wn t k
 rÖ } | GHd SX| j	 | j
 f Sd S(   s–  
  Fit a gaussian function to the map around a site. Samples points in concentric
  spheres up to radius away from the site.

  f(x) = a * exp(-b * x ** 2)

  Parameters
  ----------
  unit_cell : uctbx.unit_cell
  site_cart : tuple of float, float, float
      The site's cartesian coordinates to sample the density around.
  real_map : scitbx.array_family.flex
      Real space map of the electron density in the unit cell.
  radius : float, optional
      The max radius to use for sampling.

  Returns
  -------
  float
      Height of gaussian curve.
  float
      Spread of guassian curve.

  See Also
  --------
  scitbx.math.gaussian_fit_1d_analytical
  i    R<   RŠ   g        N(   g        g        (   RŒ   t   tricubic_interpolationR]   R   t   doubleR,   R%   R   t   RuntimeErrort   aR+   (   R[   t	   site_cartt   real_mapR‚   R…   R†   t   it   map_heightsR<   RŠ   t   radt   heightt   fitt   err(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   fit_gaussian  s    (g      @c         C   s’   g  } t  t ƒ } xy |  D]q } | j ƒ  | k r | j j ƒ  } xG | D] } | | k rG PqG qG W| j } | | c d 7<| j | ƒ q q W| S(   s]  
  Count the number of residues of each type involved in the coordination
  sphere.  This may yield additional clues to the identity of ions, e.g. only
  Zn will have 4 Cys residues.

  Parameters
  ----------
  nearby_atoms : list of mmtbx.ions.environment.atom_contact
  distance_cutoff : float, optional

  Returns
  -------
  dict of str, int
  i   (   R   t   intt   distanceR6   t   parentR   R%   (   t   nearby_atomsRT   t   unique_residuest   residue_countst   contactRœ   t   residueR   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   count_coordinating_residues6  s    	(    (    ($   t
   __future__R    t   collectionsR   t   mathR   R   R   R   t   syst   cctbxR   t   cctbx.eltbxR   R   t	   iotbx.pdbR	   R   t   libtbx.utilsR
   R   t
   mmtbx.ionsR   t   scitbx.array_familyR   t   scitbx.mathR   t   stdoutR8   RK   RO   RU   R€   RŒ   R™   R¢   (    (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ions/utils.pyt   <module>   s&   "7		_&3