ó
±™xTc           @   sç   d  d l  m Z d  d l Z d  d l Z d  d l Z d  d l m Z d  d l m	 Z	 d  d l m
 Z
 d  d l m Z d  d l Z d  d l m Z d Z d	 „  Z d
 „  Z d „  Z e j d „ Z e d k rã e d e j d ƒ n  d S(   iÿÿÿÿ(   t   divisionN(   t   Sorry(   t   maptbx(   t   adptbx(   t   eigensystem(   t   matrixsm  phenix.angle:
  Given PDB file and two atom selections that allow to define two lines compute
  the angle between these two lines. If atom selection defines two points then
  the line is defined uniquely and passes through these points. If atom
  selection defines more than two points then line coincides with the longest
  axis of the cloud of points.

How to run:
  phenix.angle model.pdb "chain A and (resseq 1 and name CA or resseq 2 and name CA)"     "chain B and (resseq 1 and name CA or resseq 2 and name CA)"
  phenix.angle model.pdb "chain A" "chain B"

Feedback:
  PAfonine@lbl.gov
  phenixbb@phenix-online.orgc      	   C   sÖ  |  j  d d ƒ j d d ƒ }  |  j d d ƒ j ƒ  j d d ƒ } | j ƒ  | j ƒ  } | j | d k  d ƒ } |  j ƒ  j	 |  j
 ƒ  ƒ } |  j ƒ  } d	 } xs t | ƒ D]e \ } } xV t | ƒ D]H \ } }	 | | k  rÃ |  j ƒ  j | |	 ƒ }
 | |
 k  r|
 } qqÃ qÃ Wqª W| d
 d } t j d | d |  j ƒ  d | d | ƒ } t j | ƒ } | j ƒ  \ } } } | | k o‘| k o‘d k n s¥t d ƒ ‚ n  | j d ƒ } t j | d | d | d f ƒ S(   Nt   valuei   i   t   d_mini   t   resolution_factorg      Ð?i    iÿÿÿÿg       @t   map_datat	   unit_cellt   radiust	   site_fracs@   Eigen-values: broken condition e1>=e2>=e3>0. Try different axes.i   (   t   set_occupanciest	   set_b_isot   structure_factorst   f_calct   fft_mapt   apply_sigma_scalingt   real_map_unpaddedt   set_selectedR
   t   fractionalizet   center_of_masst
   sites_fract	   enumeratet   distanceR   t   sphericity_tensorR   R   t   valuesR   t   vectorsR   t   col(   t   xrsR   R	   t   center_of_mass_fracR   t   diametert   it   sfit   jt   sfjt   distR   t   stt   est   l1t   l2t   l3t   axis(    (    sF   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/angle.pyt   compute   s6    $
		'c         C   s4  d  g  } } t |  ƒ d k r. t d ƒ ‚ n  xK |  D]C } t j j | ƒ rk t j j d | ƒ rk | } q5 | j	 | ƒ q5 W| d  k r— t d ƒ ‚ n  t j j
 d | ƒ j ƒ  } | j ƒ  } t t | j ƒ  ƒ ƒ d k r1t | j ƒ  ƒ d } | j ƒ  r1| j d d ƒ } | j | ƒ } | j ƒ  } q1n  t | ƒ d	 k rRt d
 ƒ ‚ n  y | j d | d ƒ } Wn% t k
 r“t d | d ƒ ‚ n Xy | j d | d ƒ }	 Wn% t k
 rÕt d | d ƒ ‚ n XxK t | |	 g | ƒ D]4 \ } }
 | j t ƒ d	 k  rìt d |
 ƒ ‚ qìqìW| | | |	 f S(   Ni   sG   Three arguments expected: PDB file, two atom selections to define axes.t	   file_names   PDB file must be provided.i   i    t   strings4   pepnames and (name ca or name n or name c or name o)i   s8   Two atom selections to define two axes must be provided.s   Invalid atom selection: %ss1   Atom selection '%s' selects less than two points.(   t   Nonet   lenR   t   ost   patht   isfilet   iotbxt   pdbt   is_pdb_filet   appendt   inputt   construct_hierarchyt   atom_selection_cachet   listt   chainst
   is_proteint	   selectiont   selectt	   Exceptiont   zipt   countt   True(   t   argst   pdb_file_namet   line_selectionst   argt   pht   asct   chaint   selt   sel1t   sel2t   ls(    (    sF   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/angle.pyt   process_args:   sD    '			"c         C   s  | j  t ƒ d k s t ‚ |  j ƒ  } | j ƒ  } | | d | | d } } | d | d | d | d | d | d g } t j | d d | d d | d d ƒ } t | ƒ d k  rÓ t d ƒ ‚ n  t	 j
 | d | | d | | d | f ƒ S(   Ni   i    i   g•Ö&è.>s"   Two points defining axis coincide.(   RB   RC   t   AssertionErrort
   sites_cartt
   iselectiont   matht   sqrtt   absR   R   R   (   R   R>   RQ   t   iselt   s1t   s2t   at   norm(    (    sF   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/angle.pyt   axis_from_two_pointsa   s    3/c         C   sö  t  |  ƒ d k sT t  |  ƒ d k rŠ d |  k sT d |  k sT d |  k sT d |  k rŠ | d d IJ| t IJ| d d IJt j d ƒ n  t d	 |  ƒ \ } } } } | | B} | j ƒ  } | j | ƒ } | j | ƒ } | j | ƒ } | j d
 d ƒ } | j t	 ƒ d k r*t
 d | j | ƒ ƒ } n t d | d | ƒ } | j t	 ƒ d k rot
 d | j | ƒ ƒ }	 n t d | d | ƒ }	 | d | d | d | d f IJ| d |	 d |	 d |	 d f IJ| j |	 ƒ d t j }
 | d |
 IJd  S(   Ni    i   s   -hs   --hs   -helps   --helpt   -iO   RD   t   buffer_sizei   i   R   R>   s   Axis 1: %6.4f %6.4f %6.4fs   Axis 2: %6.4f %6.4f %6.4fg     €f@s   Angle : %6.4f(   R0   t   legendt   syst   exitRO   t   extract_xray_structureR?   t1   orthorhombic_unit_cell_around_centered_scatterersRB   RC   R,   R[   t   angleRS   t   pi(   RD   t   logRH   RI   RL   RM   t   sel12R   t   a1t   a2Rc   (    (    sF   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/angle.pyt   runl   s.    $0

##t   __main__RD   i   (   t
   __future__R    R_   R1   t	   iotbx.pdbR4   t   libtbx.utilsR   t   cctbxR   R   t   scitbx.linalgR   RS   t   scitbxR   R^   R,   RO   R[   t   stdoutRi   t   __name__t   argv(    (    (    sF   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/command_line/angle.pyt   <module>   s   		'	