ó
±™xTc           @   sý   d  d l  m Z d  d l Z d  d l m Z m Z m Z d  d l Z d  d l	 Z	 d Z
 e j j d e
 ƒ Z d „  Z d d d e d „ Z d d „ Z d	 „  Z d
 e f d „  ƒ  YZ d „  Z e d „ Z d „  Z e d k rù e e	 j d d e ƒn  d S(   iÿÿÿÿ(   t   divisionN(   t   Sorryt   Usaget   null_outsŸ   
model_1 = None
  .type = path
  .optional = False
chain_1 = None
  .type = str
model_2 = None
  .type = path
  .optional = False
chain_2 = None
  .type = str
sU  
calculate_matrix
  .caption = This tool calculates a distance-difference matrix for two     protein chains.  The resulting plot shows the change in interatomic     distances (between C-alpha atoms), illustrating correlated motions and     rigid bodies in the structures.  The input structures are assumed to be     identical in sequence numbering, but point mutations and missing regions     are allowed.
  .short_caption = Calculate distance-difference matrix
  .style = auto_align box caption_img:icons/custom/distance_difference.png
{
%s
display_plot = False
  .type = bool
  .style = hidden
}c           C   s   t  d ƒ ‚ d  S(   Ns}  
mmtbx.distance_difference model1.pdb CHAIN_1 model2.pdb CHAIN_2
mmtbx.distance_difference model_1=... model_2=... chain_1=... chain_2=...

other options:
  --display_plot or display_plot=True : display plot interactively

Calculate and plot a distance difference matrix for two (near-identical)
protein chains.  Chain IDs are optional for models that have only one protein
chain.
(   R   (    (    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyt   usage*   s    
c         C   sC  | d  k r t j } n  g  } g  } g  } t j j j d t d d ƒ } | d  k rt |  ƒ d k rp t	 ƒ  n  d d  l
 } xÚ |  D]Ò }	 t j j |	 ƒ rÜ | j j |	 ƒ r½ | j |	 ƒ qU| j t j j d |	 ƒ ƒ qƒ t |	 ƒ d k rþ | j |	 ƒ qƒ |	 j d ƒ r|	 d d	 }	 n  y | j |	 ƒ }
 Wn t k
 rDqƒ X| j |
 ƒ qƒ qƒ WxD t | ƒ D]6 \ } } | d
 7} | j | j d | | f ƒ ƒ qfWxD t | ƒ D]6 \ } } | d
 7} | j | j d | | f ƒ ƒ q­Wt j d | ƒ } | j ƒ  } t | ƒ n  | j } t | d | ƒ} d t j j | j ƒ | j t j j | j ƒ | j f } | j | ƒ | rä| j  räy t! | ƒ Wq?t" k
 r°t# d ƒ ‚ q?t$ k
 rà} | d IJ| d t% | ƒ IJq?Xn[ | r?y d d  l& } Wn t" k
 rt# d ƒ ‚ n X| j' d ƒ t! | d t( ƒd GHn  | S(   Nt   master_philt
   home_scopet   calculate_matrixi    iÿÿÿÿt	   file_namei   s   --s   =Truei   s   model_%d="%s"s   chain_%d="%s"t   sourcest   logs+   Distance-difference matrix: %s:%s vs. %s:%ss8   matplotlib is not installed - can't generate plot image.s)   Oops!  Can't display an interactive plot:s     %st   Aggt   savefigs%   Saved plot as distance_difference.png()   t   Nonet   syst   stdoutt   libtbxt   philt   command_linet   argument_interpreterR   t   lenR   t	   iotbx.pdbt   ost   patht   isfilet   pdbt   is_pdb_filet   appendt   parset
   startswitht   process_argt   RuntimeErrort	   enumeratet   fetcht   extractt   validate_paramsR   t   basenamet   model_1t   chain_1t   model_2t   chain_2t	   set_titlet   display_plott   display_plot_pylabt   ImportErrorR   t	   Exceptiont   strt
   matplotlibt   uset   True(   t   argst   paramst   outR*   t	   user_philt	   pdb_filest	   chain_idst   interpt   iotbxt   argt   arg_philt   iR   t   chain_idt   working_philt   ddmt   titlet   eR/   (    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyt   run7   sv    	

$
$	
c   
      C   sê  | d  k r t ƒ  } n  d d l m } | j |  j d d ƒ} | j d ƒ | j j } | j	 ƒ  j
 ƒ  | j |  j d d ƒ} | j d ƒ | j j } | j	 ƒ  j
 ƒ  xt | | g ƒ D]þ \ } } | d 7} t |  d | ƒ d  k r½ yb t | ƒ }	 |	 d  k r9t d d d	 d
 t |  d | ƒ | f ƒ ‚ n  t |  d | |	 ƒ Wq»t k
 r‚t d d t |  d | ƒ ƒ ‚ q»t k
 r·t d d d t |  d | ƒ ƒ ‚ q»Xq½ q½ Wt d | d |  j d | d |  j d | ƒ S(   Niÿÿÿÿ(   t   file_readert
   force_typeR   i   s   chain_%ds0   The file %s does not appear to have any protein s>   chains!  If you think this is an error, you should explicitly s<   specify the parameter chain_%d.  (Nucleic acids are not yet s   supported, sorry.)s   model_%ds4   The file %s has more than one protein chain, and no s'   explicit chain ID to use was specified.s3   The file %s contains multiple models.  You can use sA   iotbx.pdb.split_models to extract the individual models from the s(   file (also available in the PHENIX GUI).t   hierarchy_1t
   chain_id_1t   hierarchy_2t
   chain_id_2R
   (   R   R   R9   RC   t   any_fileR%   t   check_file_typet   file_objectt	   hierarchyt   atomst   reset_i_seqR'   R    t   getattrt   find_single_protein_chainR   t   setattrR   t   AssertionErrort   distance_difference_matrixR&   R(   (
   R3   R
   RC   t   pdb_1RE   t   pdb_2RG   t   kRL   R=   (    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyR   w   sH     
$"		c         C   sŒ   t  |  j ƒ  ƒ d k s t ‚ d  } xa |  j ƒ  d j ƒ  D]I } | j ƒ  d } | j ƒ  r; | d  k	 rx t d ƒ ‚ n  | j } q; q; W| S(   Ni   i    s)   More than one protein chain in hierarchy.(	   R   t   modelsRR   R   t   chainst
   conformerst
   is_proteinR   t   id(   RL   R=   t   chaint	   main_conf(    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyRP   ž   s    RS   c           B   s   e  Z d d  „ Z d „  Z RS(   c         C   sÁ  d  | | | | g k s t ‚ t | j ƒ  ƒ d k rN t | j ƒ  ƒ d k sT t ‚ | j ƒ  j ƒ  j d ƒ sv t ‚ | j ƒ  j ƒ  j d ƒ s˜ t ‚ d d l m } | d  k rÀ t	 ƒ  } n  g  |  _
 d  } } xp | j ƒ  d j ƒ  D]X }	 |	 j | k rê |	 j ƒ  d }
 |
 j ƒ  rB| d  k	 r6t d ƒ ‚ q?|	 } qBqê qê Wxp | j ƒ  d j ƒ  D]X }	 |	 j | k r]|	 j ƒ  d }
 |
 j ƒ  rµ| d  k	 r©t d ƒ ‚ q²|	 } qµq]q]W| d  k rØt d | ƒ ‚ n  | d  k r÷t d | ƒ ‚ n  g  g  g } | j ƒ  | j ƒ  g } xÏ t | | g ƒ D]» \ } }	 x¬ |	 j ƒ  D]ž } | j ƒ  } | j ƒ  } t | ƒ d k r’| d | d | f IJn  xP | d j ƒ  D]> } | j d	 k r£| | j | ƒ | | j | j ƒ Pq£q£WqGWq.Wxž d d g D]� \ } } d } t | | ƒ t | | ƒ k s2t ‚ xU | t | | ƒ k  r‰| | | | | k r|| | | =| | | =q5| d 7} q5WqúWt | d ƒ t | d ƒ k s´t ‚ t | d ƒ t | d ƒ k sÚt ‚ t | d ƒ d k rt d
 d ƒ ‚ n  t | d ƒ d k r,t d d ƒ ‚ n  | j ƒ  j ƒ  } | j | d ƒ } | j ƒ  j ƒ  } | j | d ƒ } d d  l } | j j | | ƒ |  _ | d |  _ | d |  _ d |  _  d  S(   Ni   i    iÿÿÿÿ(   t   flexs3   Multiple protein chains with ID '%s' in hierarchy_1s+   Can't find protein chain '%s' in 1st model.s+   Can't find protein chain '%s' in 2nd model.s.   Warning: multiple conformers in model %d at %ss    CA s2   No matching residues in model 1!  Make sure it is s6   really a protein chain with CA atoms for each residue.s2   No matching residues in model 2!  Make sure it is s   Distance-difference matrix(   i    i   (   i   i    (!   R   RR   R   RW   RM   t   extract_i_seqt   all_eqt   scitbx.array_familyR^   R   t   matching_residsRX   R[   RY   RZ   R   t   size_tR    t   residue_groupst   atom_groupst   residt   nameR   t   i_seqt   extract_xyzt   selectt   scitbx.matht   mathRS   t   mt   resids_1t   resids_2R@   (   t   selfRE   RF   RG   RH   R
   R^   R&   R(   R\   R]   t   residst
   selectionsR<   t   residue_groupRe   Rf   t   atomt   jRV   t   sites_1t   sites_2t   scitbx(    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyt   __init__ª   s„    6""	
&&&c         C   s   | |  _  d  S(   N(   R@   (   Rp   R@   (    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyR)   ö   s    N(   t   __name__t
   __module__R   Ry   R)   (    (    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyRS   ©   s   Gc   	      C   s  | j  d d d d g ƒ } | j |  j j ƒ  d d ƒ} | j d ƒ | j d ƒ g  } x_ | j ƒ  D]Q } | d k rª | t |  j ƒ k  rª | j	 |  j t
 | ƒ ƒ qf | j	 d ƒ qf W| j | ƒ g  } x_ | j ƒ  D]Q } | d k r| t |  j ƒ k  r| j	 |  j t
 | ƒ ƒ qÛ | j	 d ƒ qÛ W| j | ƒ | j | d | d	 d
 d d ƒ} | j d ƒ | j |  j ƒ d  S(   Ngš™™™™™¹?gš™™™™™é?t   origint   lowers
   Residue IDi    t    t   axt   fractiongš™™™™™©?t   aspecti(   s"   Change in C-alpha:C-alpha distance(   t   add_axest   imshowRm   t   as_numpy_arrayt
   set_xlabelt
   set_ylabelt
   get_xticksR   Rn   R   t   intt   set_xticklabelst
   get_yticksRo   t   set_yticklabelst   colorbart	   set_labelR)   R@   (	   R?   t   figuret   plott   imt   xticklabelst   xt   yticklabelst   yt   cb(    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyt	   draw_plotù   s&    !!!c         C   sY   d d l  m } | j d d	 ƒ } t |  | ƒ | rK | j d d d ƒn
 | j ƒ  d  S(
   Niÿÿÿÿ(   t   pyplott   figsizei   i
   s   distance_difference.pngt   formatt   png(   i   i
   (   R/   R—   RŽ   R–   R   t   show(   R?   R   t   pltRŽ   (    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyR+     s    c         C   sÕ   |  j  }  xÅ d d g D]· } t |  d | ƒ } t |  d | ƒ } | d  k ra t d | ƒ ‚ n% t j j | ƒ s† t d | ƒ ‚ n  | d  k	 r t | ƒ d k s¶ t | ƒ d k r t d d	 | ƒ ‚ q q Wt S(
   Ni   i   s   model_%ds   chain_%ds   Missing file for model_%d!s#   %s is not a file or does not exist.i    s5   Invalid chain ID '%s' - must be 1 or 2 characters in s   length if explicitly set.(	   R   RO   R   R   R   R   R   R   R1   (   R3   R<   t
   file_paramt   chain_param(    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyR#     s    	t   __main__i   R*   (    (   t
   __future__R    t   libtbx.phil.command_lineR   t   libtbx.utilsR   R   R   R   R   t   calculate_matrix_philR   R   R   R   R   t   FalseRB   R   RP   t   objectRS   R–   R+   R#   Rz   t   argvR1   (    (    (    sT   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/distance_difference.pyt   <module>   s"   		@'	P			