ó
¢™xTc           @   sö   d  Z  d d l m Z d d l m Z m Z m Z m Z d d l m	 Z	 d d l
 Z d d l Z d d l Z d d l Z d e f d „  ƒ  YZ d e f d	 „  ƒ  YZ d
 e f d „  ƒ  YZ e d „ Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   sO   
All-atom contact analysis.  Requires Reduce and Probe (installed separately).
iÿÿÿÿ(   t   division(   t
   validationt   atomst	   atom_infot   residue(   t   easy_runNt   clashc           B   sl   e  Z d  d d g Z e j e Z e d „  ƒ Z d d „ Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z RS(   t   overlapt
   probe_typet   max_b_factorc           C   s   d d S(   Ns   %-20s %-20s  %7ss   Atom 1s   Atom 2t   Overlap(   s   Atom 1s   Atom 2R
   (    (    (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   header   s    t    c         C   s+   d |  j  d j ƒ  | |  j  d j ƒ  f S(   Ns   %s%s%si    i   (   t
   atoms_infot   id_str(   t   selft   spacer(    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR      s    c         C   s6   d |  j  d j ƒ  d d !|  j  d j ƒ  d d !f S(   Ns   %s %si    i   i   (   R   R   (   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   id_str_no_atom_name   s    c         C   s   d |  j  ƒ  |  j f S(   Ns   %s :%.3f(   R   R   (   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt
   format_old"   s    c         C   s.   d |  j  d j ƒ  |  j  d j ƒ  |  j f S(   Ns   %-20s %-20s  %7.3fi    i   (   R   R   R   (   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt	   as_string%   s    c         C   s*   |  j  d j ƒ  |  j  d j ƒ  |  j g S(   Ni    i   (   R   R   R   (   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   as_table_row_phenix)   s     c         C   s   t  |  j | j ƒ S(   N(   t   cmpR   (   R   t   other(    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   __cmp__-   s    (   t   __name__t
   __module__t   __clash_attr__R   t	   __slots__t   staticmethodR   R   R   R   R   R   R   (    (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR      s   					t
   clashscorec        
   B   sñ   e  Z e j d  d d d d d d g Z d Z d d	 d
 g Z d d d g Z d g d Z d „  Z e	 e
 e
 d d d e
 e
 e j d „	 Z d „  Z d „  Z e j e
 d „ Z e j d d „ Z e j d „ Z e j d d d d „ Z d „  Z RS(   R   t   clashscore_b_cutofft
   clash_dictt   clash_dict_b_cutofft	   list_dictt   b_factor_cutofft
   probe_files$   Analyze clashscore for protein models   Atom 1s   Atom 2R
   s   %ss   .3fiÈ   i   c         C   s   t  S(   N(   R   (   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   get_result_class?   s    ix   c         C   sü  t  j |  ƒ | |  _ d  |  _ d  |  _ i  |  _ i  |  _ i  |  _ d  |  _	 t
 j j d d ƒ sx t d d d ƒ ‚ n  |	 r” | sŒ d GHq” d GHn  d d  l } d d	 l m } d d
 l m } t | j ƒ  ƒ } | j d | ƒ } xt | j ƒ  ƒ D]ý\ } } | j j j ƒ  } | j ƒ  } | j | ƒ | } | r£| j ƒ  j ƒ  } | j d ƒ | j d ƒ } | d k r}t } n t  } | s£|	 r—d GHn  t  } q£n  | j! ƒ  } | j" | j ƒ  j# ƒ  ƒ } t$ d | d | d | d | d | d | d | d |	 ƒ } | r*t j j% d | j& ƒ j |  _' n  | j |  j | j( <| j |  j | j( <| j) |  j | j( <| d k s~|  j d  k r·| j) |  _* t |  j* ƒ |  _+ | j |  _ | j |  _ n  | d  k	 r÷ | d k r÷ t, | d ƒ j- | j. ƒ | |  _	 q÷ q÷ Wd  S(   Nt   namet   probes>   Probe could not be detected on your system.  Please make sure s-   Probe is in your path.
Probe is available at s!   http://kinemage.biochem.duke.edu/s1   
Using electron cloud x-H distances and vdW radiis0   
Using nuclear cloud x-H distances and vdW radiiiÿÿÿÿ(   t   flex(   t   utilst	   hierarchys    Hs    Di    s4   
No H/D atoms detected - forcing hydrogen addition!
t
   pdb_stringt   keep_hydrogenst   nucleart
   time_limitt   largest_occupancyR"   t
   use_segidst   verbosei   t   w(/   R   t   __init__R"   t   NoneR   R   R   R    R!   R#   t   libtbxt   envt
   has_modulet   RuntimeErrort   iotbx.pdb.hierarchyt   scitbx.array_familyR'   t   mmtbx.validationR(   t   lent   modelst   use_segids_in_place_of_chainidst	   enumeratet   pdbR)   t   roott   detached_copyt   append_modelR   t   extract_elementt   countt   Truet   Falset   as_pdb_stringt   maxt   extract_occt   probe_clashscore_managert   inputt   h_pdb_stringt   pdb_hierarchyt   idt   bad_clashest   resultst
   n_outlierst   opent   writet   probe_unformatted(   R   RM   R+   R,   t   force_unique_chain_idsR-   R"   t   save_probe_unformatted_filet   save_modified_hierarchyR0   t   outt   iotbxR'   R(   t   n_modelsR/   t   i_modt   modelt   rt   mdct   tmp_rt   elementst   h_countt   has_hdt	   input_strt   occ_maxt   pcm(    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR2   A   s|    											c         C   s   |  j  S(   N(   R   (   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   get_clashscore¡   s    c         C   s   |  j  S(   N(   R   (   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   get_clashscore_b_cutoff¤   s    c         C   s$   |  j  d | ƒ |  j d | ƒ d  S(   NRX   (   t   print_clashlist_oldt   show_summary(   R   RX   R0   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   show_old_output§   s    t    c         C   sß   t  |  j ƒ d k re | | d |  j d IJ|  j d d  k	 rÛ | d |  j |  j d f IJqÛ nv xs t |  j j ƒ  ƒ D]\ } | | d | |  j | f IJ|  j | d  k	 r{ | d | |  j |  j | f IJq{ q{ Wd  S(   Ni   s   clashscore = %.2fRk   s&   clashscore (B factor cutoff = %d) = %fs   MODEL %s clashscore = %.2fs.   MODEL%s clashscore (B factor cutoff = %d) = %f(   R;   R   R    R3   R"   t   sortedt   keys(   R   RX   t   prefixt   k(    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyRi   «   s    c         C   s•   xŽ |  j  j ƒ  D]} } | d k rW | d IJx^ |  j  | D] } | | j ƒ  IJq: Wq | d | IJx% |  j  | D] } | | j ƒ  IJqs Wq Wd  S(   NRk   s   Bad Clashes >= 0.4 Angstrom:s#   Bad Clashes >= 0.4 Angstrom MODEL%s(   R!   Rm   R   (   R   RX   Ro   t   result(    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyRh   º   s    
c         C   s¤   t  |  j ƒ d k rD xr |  j d D] } | | t | ƒ IJq# WnF xC |  j j ƒ  D]2 } x) |  j | D] } | | t | ƒ IJqh WqT W|  j d | d | ƒ d  S(   Ni   Rk   RX   Rn   (   R;   R   R!   t   strRm   Ri   (   R   RX   Rn   t   outliers_onlyR0   Rp   Ro   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   showÅ   s    c         C   sf   g  } xY |  j  D]N } | j ƒ  r | j | j d j ƒ  | j d j ƒ  | j | j f ƒ q q W| S(   Ni    i   (   RP   t
   is_outliert   appendR   R   R   t   xyz(   R   t   dataRp   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   as_coot_dataÏ   s    *N(   R   R   R   R   t   program_descriptiont   gui_list_headerst   gui_formatst   wx_column_widthsR$   RE   RF   R3   t   syst   stdoutR2   Rf   Rg   Rj   Ri   Rh   Rs   Rx   (    (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR   0   s:   
	V		
RJ   c           B   s8   e  Z e e d  d d e e d „ Z d „  Z d „  Z RS(   ix   i
   c	         C   s|  t  j j d d ƒ r* t  j j d d ƒ s0 t ‚ | |  _ | |  _ d }	 |  j }
 | |	 k  rf | }	 n  d |  _ d  |  _ | sÔ d d | |  _	 d |	 |	 f |  _
 d	 |	 |  _ |
 d  k	 r3d
 |
 |	 f |  _ q3n_ d d | |  _	 d d |	 |	 f |  _
 d d |	 |  _ |
 d  k	 r3d d |
 |	 f |  _ n  | sK|  j | ƒ } n | rYd GHn  | } | |  _ |  j |  j ƒ d  S(   NR%   t   reduceR&   i
   s   phenix.reduce -quiet -trim -s%   phenix.reduce -oh -his -flip -pen9999s    -keep -allalt -limit%d -s=   phenix.probe -u -q -mc -het -once "ogt%d not water" "ogt%d" -s:   phenix.probe -q -mc -het -dumpatominfo "ogt%d not water" -s@   phenix.probe -q -mc -het -dumpatominfo "blt%d ogt%d not water" -s    -keep -allalt -limit%d -nuc -s*   phenix.probe -u -q -mc -het -once -nuclears    "ogt%d not water" "ogt%d" -s/   phenix.probe -q -mc -het -dumpatominfo -nuclears    "ogt%d not water" -s    "blt%d ogt%d not water" -s    
Using input model H/D atoms...
(   R4   R5   R6   t   AssertionErrorR"   R/   t   trimR3   t   probe_atom_b_factort   buildt	   probe_txtt   probe_atom_txtt
   run_reduceRL   t   run_probe_clashscore(   R   R*   R+   R,   R-   R.   R"   R/   R0   t   ogtt   bltRL   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR2   Ø   sF    								c         C   sº   t  j |  j d | ƒ} | j d k rO t d |  j d j | j ƒ f ƒ ‚ n  t  j |  j d | j ƒ} | j d k r¡ t d |  j d j | j ƒ f ƒ ‚ n  t	 j | j d ƒ } | S(   Nt   stdin_linesi    s5   Reduce crashed with command '%s' - dumping stderr:
%ss   
(
   R   t   fully_bufferedR�   t   return_codeR7   t   joint   stderr_linesRƒ   t   stdout_linest   string(   R   R*   t	   clean_outt	   build_outt
   reduce_str(    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR†     s    	""c   ,      C   sÛ  i  } i  } d  } t j |  j d | ƒ} | j d k rX t d d j | j ƒ ƒ ‚ n  | j } d j | ƒ |  _	 xä| D]Ü} | j
 d ƒ \ } }	 }
 } } } } } } } } } } } } } } } } t | |  j ƒ } t | |  j ƒ } t | | ƒ d k  r| | g } n | | g } t | ƒ } t | ƒ t | ƒ t | ƒ } } } t d | d | d |
 d	 t | ƒ d
 k d t t | ƒ t | ƒ ƒ d | | | f ƒ } | } |
 d k sÃ|
 d k r| d k rV| | k rþ| | | j k  r| | | <qq| | | <qVqz |
 d k rz | | k rI| | | j k  rS| | | <qSqV| | | <qz qz Wg  }  x4 | j ƒ  D]& }! |! | k rm|  j | |! ƒ qmqmWt |  ƒ |  _ |  j d  k	 r÷d }" x- |  D]% } | j |  j k  rÂ|" d 7}" qÂqÂW|" |  _ n  g  }# g  |  _ xL t |  ƒ D]> } | j ƒ  }$ |$ |# k r|# j |$ ƒ |  j j | ƒ qqWt j |  j d | ƒj ƒ  j }% t |% ƒ d k r—t d ƒ ‚ n  d |  _ x# |% D] } | j
 d ƒ \ }& }' q§Wt  |' ƒ |  _ d  |  _! |  j" d  k	 rFt j |  j" d | ƒj ƒ  j }( x# |( D] } | j
 d ƒ \ }) }* qWt  |* ƒ |  _! n  |  j d k r^d } n |  j d |  j } | |  _# d  }+ |  j! d  k	 r¨|  j! d k r¨d }+ n& |  j! d  k	 rÎ|  j d |  j! }+ n  |+ |  _$ d  S(   NRŠ   i    s"   Probe crashed - dumping stderr:
%ss   
t   :R   R   R   t   outliergš™™™™™Ù?R	   Rv   t   sot   bogš™™™™™Ù¿t   hbi   s   Empty PROBE output.g        iè  (%   R3   R   R‹   R„   RŒ   R7   R�   RŽ   R�   RT   t   splitt   decode_atom_stringR/   R   t   floatR   t   absRH   R   Rm   Ru   R;   t	   n_clashesR"   R	   t   n_clashes_b_cutoffRO   Rl   R   R…   t   raise_if_errorst   n_atomst   intt   natoms_b_cutoffR‚   R   R   (,   R   R*   t
   clash_hasht
   hbond_hashR   t	   probe_outRT   t   lineR%   t   patt   typet   srcAtomt   targAtomt   min_gapt   gapt   kissEdge2BullsEyet   dot2BEt   dot2SCt   spiket   scoret   stypet   ttypet   xt   yt   zt   sBvalt   tBvalt   atom1t   atom2R   t	   clash_objt   keyt   tempRo   t   clashes_b_cutofft   usedt   test_keyt
   probe_infot   dumpR    t   probe_info_b_factort   dump_bR¢   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR‡   !  s¢    		H&						N(   R   R   RE   RF   R3   R2   R†   R‡   (    (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyRJ   ×   s   0	c         C   s»   | s t  |  ƒ d k rh t d |  d d !d |  d d !d |  d d |  d	 d
 !d |  d d |  d d !ƒ St d |  d d !d |  d d !d |  d d |  d d !d |  d d |  d d !ƒ Sd  S(   Ni   t   chain_idi    i   t   resseqi   t   icodet   resnamei   i
   t   altloci   R%   i   i   i   i	   i   i   i   (   R;   R   (   t   atom_strR/   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyRš   }  s    



t   nqh_flipc           B   s    e  Z d  Z d „  Z d „  Z RS(   sc   
  Backwards Asn/Gln/His sidechain, identified by Reduce's hydrogen-bond
  network optimization.
  c         C   s
   |  j  ƒ  S(   N(   R   (   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR   ™  s    c         C   s   |  j  d |  j |  j f g S(   Ns   %s %s(   RÅ   RÈ   t   resid(   R   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR   œ  s    (   R   R   t   __doc__R   R   (    (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyRË   ”  s   	t	   nqh_flipsc           B   sM   e  Z d  Z d d g Z d d g Z d d g Z d „  Z e j d d „ Z	 RS(	   s1   
  N/Q/H sidechain flips identified by Reduce.
  t   Chaint   Residues   %sid   iÜ   c         C   sì   t  j d ƒ } t j |  ƒ t j d d | j ƒ  ƒ} x® | j D]£ } | j | ƒ rA | d d !} | d k su t	 ‚ t
 d	 | d
 d | d d !j ƒ  d | d d | d d | ƒ } | j | ƒ |  j j | ƒ |  j d 7_ qA qA Wd  S(   Ns   :FLIPs   phenix.reduce -BUILD -RŠ   i   i   t   ASNt   GLNt   HISRÅ   i   RÆ   i   i   RÇ   RÉ   i   RÈ   i   (   RÑ   RÒ   RÓ   (   t   ret   compileR   R2   R   R‹   RG   RŽ   t   searchR€   RË   t   stript   set_coordinates_from_hierarchyRP   Ru   RQ   (   R   RM   t   re_flipt
   reduce_outR¦   RÈ   t   flip(    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyR2   ¦  s"    


	Rk   c         C   sL   |  j  d k r  | | d IJn( x% |  j D] } | | | j ƒ  IJq* Wd  S(   Ni    s*   No backwards Asn/Gln/His sidechains found.(   RQ   RP   R   (   R   RX   Rn   RÛ   (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyRs   º  s    (
   R   R   RÍ   Rz   R{   R|   R2   R}   R~   Rs   (    (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyRÎ   Ÿ  s   	(   RÍ   t
   __future__R    R:   R   R   R   R   R4   R   t   libtbx.load_envR�   RÔ   R}   R   R   t   objectRJ   RF   Rš   RË   RÎ   (    (    (    sI   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/validation/clashscore.pyt   <module>   s   ""§¦