ó
¼xTc           @   s  d  d l  m Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l	 Z d  d l
 Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l m Z d Z i d d 6d d 6d	 d
 6Z d d d
 g Z d e f d     YZ d e f d     YZ d e f d     YZ d e d  Z d e j j  f d     YZ! d   Z" d   Z# e$ d k re d e j% d  n  d S(   i’’’’(   t   divisionN(   t   Sorrysā  
input {
  pdb_file_name_fixed = None
    .type = path
    .short_caption = Fixed model
    .help = Name of PDB file with model to fit to
    .style = bold file_type:pdb input_file
  pdb_file_name_moving = None
    .type = path
    .short_caption = Moving model
    .help = Name of PDB file with model that will be fit to pdb_file_name_fixed
    .style = bold file_type:pdb input_file
}

output {
  file_name = None
    .help = Name of PDB file with model that best fits to pdb_file_name_fixed
    .short_caption = Output model
    .type = path
    .style = bold new_file file_type:pdb
  include scope libtbx.phil.interface.tracking_params
}

selection_fixed = None
  .type = str
  .short_caption = Selection for fixed model
  .input_size = 400
  .help = Selection of the target atoms to fit to (optional)
selection_moving = None
  .type = str
  .short_caption = Selection for moving model
  .input_size = 400
  .help = Selection of the atoms that will be fit to selection_fixed (optional)
selection_fixed_preset = * ca backbone all
  .type = choice
  .help = Selection preset for fixed model.
selection_moving_preset = * ca backbone all
  .type = choice
  .help = Selection preset for moving model.
selection_fixed_chain = None
  .type = str
  .help = Selection chain for fixed model.
selection_moving_chain = None
  .type = str
  .help = Selection chain for moving model.

alignment
  .help = Set of parameters for sequence alignment. Defaults are good for most           of cases
  .short_caption = Sequence alignment
  .style = box auto_align
{
  alignment_style = local *global
    .type = choice
  gap_opening_penalty = 1
    .type = float
  gap_extension_penalty = 1
    .type = float
  similarity_matrix = blosum50  dayhoff *identity
    .type = choice
}sI   pepnames and (name ca or name n or name c) and altloc " " chain %(chain)st   backbones5   pepnames and (name ca) and altloc " " chain %(chain)st   cas   all chain %(chain)st   allt   SuperposePDBc        	   B   s  e  Z d  Z i  Z d d d d d e d d d  Z e d d d   Z d   Z	 d   Z
 d d d d  Z d d d d  Z d   Z d d	  Z d d
  Z e d  Z d   Z d   Z d d  Z e e d  Z d d  Z d   Z d   Z d   Z d   Z e d    Z RS(   sØ  Superimpose PDB files.

  Instantiate with a filename or pdb instance. You may also provide a default
  selection string, selection preset, or chain to use for atom selection.
  Otherwise, the select method will attempt to find a reasonable default.

  Use the superpose(target) method to perform superposition. This will return
  the RMSD, and the transformation used. To write output, use output(lsq,
  filename).

  The selectomatic(target) method performs a pairwise comparison of chain
  sequence alignments, and updates the selections to use the chains with the
  highest similarity.

  You can also update the selection using the select_update() method, or return
  a given selection using select().

  Multiple models are supported by creating multiple instances. The class method
  open_models() helper can be used to open a file with multiple models.

  To create a subclass with a modified fitting routine, override fit().
  c	   	      C   sĖ   | |  _  | |  _ | p' t j j |  |  _ | d k rT | d k rT t d   n  | pi t j	 j
 |  |  _ |  j j   |  _	 t |  j	 j    d k r« t d   n  |  j d | d | d |  d S(   sÕ   A filename or pdb instance is required. You may also provide arguments
    for the atom selection. The quiet option will suppress informational
    output. The desc option provides a label for the log output.
    s"   Filename or PDB instance required.i   sQ   Only one model supported; use SuperposePDB.open_models() to open multiple models.t	   selectiont   chaint   presetN(   t   _quiett   _logt   ost   patht   basenamet   desct   NoneR   t   iotbxt   pdbt   inputt	   pdb_inputt   construct_hierarchyt   lent   modelst   select_update(	   t   selft   filenameR   R   R   R   t   quiett   logR   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   __init__   s    		c   
   	   K   s  t  j j |  } t  j j |  j   j   } | j d d  } g  } t |  d k r| | j |  d | d | |   n t |  d k rü xw t |  D]Z \ } } t  j j	 j
   }	 |	 j | j    | j |  d |	 d d | | f |   q Wn t d   | S(   s:   Class method to return instances for each model in a file.R   t   movingi   R   s   %s-%ss   No models found!(   R   R   R   R   R   t   popR   t   appendt	   enumeratet	   hierarchyt   roott   append_modelt   detached_copyR   (
   t   clsR   R   t   kwargsR   R   t   rett   countt   modelt   pdb_new(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   open_models   s    "0c         C   s
   t   d S(   s   Return a transformed model.N(   t   NotImplemented(   R   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   get_transformedµ   s    c         C   s}  g  } xå |  j  j   D]Ō } |  j d d | j  \ } } } x© | j  j   D] } | j d d | j  \ } } } |  j | |  \ } } | j | |  \ }	 } |  j | |	  }
 |  j |
  } | j | | j | j |
 f  qN Wq W| st d   n  t	 |  d } |  j
 d | d | d f  |  j | d  |  j d	 | d  | j d	 | d  | d | d f S(
   s,  Perform pairwise sequence alignments and find the best aligned chain pair.

    This method performs pairwise sequence alignments between all chains in
    itself and the target. The selections are updated to the pair with the
    highest sequence similarity, with chain IDs in the return value.
    R   s   all chain %ss   No alignments?i’’’’s4   Select-o-matic: Aligning chain %s to target chain %si   i   i   R   (   R   t   chainst   selectt   idt   _extract_sequence_chaint	   _seqalignt   _seqalign_scoreR   R   t   sortedR   t   _print_seqalignR   (   R   t   targett
   alignmentst   moving_chaint   _t   moving_selectiont   target_chaint   target_selectiont
   moving_seqt
   target_seqt	   alignmentt   scoret   best(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   selectomatic¹   s$    ""'c         C   sL  | d	 k r d } n  t |  j j   d d   } | pC | d j } | rj |  j j   j d |  } n§ t j |  r· t j |  } | i | d 6} |  j j   j d |  } nZ xW t	 D]O } t | } | i | d 6} |  j j   j d |  } | j
 t  r¾ Pq¾ q¾ W|  j j   } | j   | j   j |  } | | | f S(
   sa  Update the selection.

    Specify either an explicit selection, or one of the handy preset selections
    (ca, backbone, all). Presets will use the longest chain by default, but
    this can also be specified using chain. If no selection or preset is
    specified, the various presets will be tested before falling back to all
    atom selection.
    R   t   nonet   keyc         S   s
   |  j    S(   N(   t
   atoms_size(   t   x(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   <lambda>č   s    i’’’’t   stringR   N(   Ns   NoneRC   (   R   R4   R   R.   R0   t   atom_selection_cacheR   t   PRESETSt   gett   PRESET_ORDERR(   t   Truet   atomst   reset_i_seqt   extract_xyzR/   (   R   R   R   R   R.   t   selected_atomsRN   t   selected_xyz(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR/   Ś   s(    
	

c         C   sZ   |  j  | | |  \ |  _ |  _ |  _ |  j d |  j t |  j  t |  j  f  d S(   s   select() and update state.s2   Using selection: %s, atoms total: %s, selected: %sN(   R/   R   RQ   RR   R   R   (   R   R   R   R   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR     s    'c         G   s=   |  j  r d S|  j d |  j Id j t t |   IJd S(   s   Log.Ns   %s: t    (   R	   R
   R   t   joint   mapt   str(   R   t   msg(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR     s    	t    c         C   s   | j  |  } | | j   } y- t j j |  } |  j d | | f  Wn t k
 rl |  j d  n X|  j d | | f  d S(   sB   Print statistics on the RMSD between sites_moving and sites_fixed.s#   Percentile-based spread (%s): %-.3fs:   Could not calculate percentile-based spread... Please fix!s/   RMSD between fixed and moving atoms (%s): %-.3fN(   t   rms_differencet   normst   libtbxt
   math_utilst   percentile_based_spreadR   t	   Exception(   R   t   sites_movingt   sites_fixedR   t   rmsdt   deltast   pbs(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   _print_rmsd  s    c      	   C   sl   |  j  d  |  j  d | j j d d d t d d   |  j  d  |  j  | j j d d	 d d   d
 S(   s,   Print the transformation described by a lsq.s	   Rotation:s   
t   labelt   rt   one_row_per_linet   formats   %8.5fs   Translation:t   tN(   R   Rf   t   mathematica_formRM   Ri   (   R   t   lsq(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt
   _print_lsq  s    ,c         C   s   | j    } |  j d  |  j d | j d  | j d   |  j d  | pY |  j s | j d | d d d	 d
 d d d d  n  d S(   s#   Print a sequence alignment details.s   Alignment details:s   	matches after alignment: %st   |t   *s   	sequence alignment:t   matchest
   block_sizei2   t   n_blocki   t   top_nameR   t   bottom_namet   fixedN(   Ro   R   R(   R	   t   pretty_print(   R   R?   R   Ro   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR5      s    '	c         C   sČ   t  |  t  |  k r= t d t  |  t  |  f   n  t  |  d k r^ t d   n  t  |  d k  r t d   n  t j j j d | d |  } | j   } | j |  } | | | | f S(   s   Perform a least squares fit between sites_moving and sites_fixed. Return
    the rmsd, lsq, and updated sites_moving, sites_fixed.s1   Cannot align different number of atoms: %s and %si    s#   Cannot align an empty set of atoms.i   s   Cannot align a single atom.t   reference_sitest   other_sites(   R   R   t   scitbxt   matht	   superposet   least_squares_fitt   other_sites_best_fitRY   (   R   R_   R`   Rk   t   sites_moving2Ra   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   fit0  s    %c         C   s9  |  j    \ } } | j    \ } } |  j d  |  j | |  } |  j |  |  j | | | | | |  j | j  } t | d d   d t } | s§ t d   n  | j	   \ } }	 }
 } |  j d  |  j
 |
 | d d |  j d	  |  j d
 |
 j    |  j
 |	 j   | d d |  j |	  | |	 f S(   s   Superpose to target. Return rmsd and lsq.

    This method will perform a sequence alignment first if the target is not
    sequence identical.
    s	   Let's go!RD   c         S   s   |  d S(   Ni    (    (   RF   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyRG   \  s    t   reversesA   Failed to get a good sequence alignment, or failed to fit models.s   Initial stats:R   t   starts	   Best fit:s"   Number of atoms for LS fitting: %st   final(   t   _extract_sequence_rgsR   R2   R5   t   _superpose_alignRQ   R4   RM   R   R   Rd   t   sizeR|   Rl   (   R   R6   t
   seq_movingt
   str_movingt	   seq_fixedt	   str_fixedR?   t   rmsdsRa   Rk   t
   xyz_movingt	   xyz_fixed(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyRz   D  s0    c	         c   s6  g  }	 d } x#t  |  D]\ }
 } t j j j   } t j j j   } |  j | d | } x¢ | D] \ } } } x | | j j   D]s } xj | | j j   D]U } | j | j k r¢ | | j	 r¢ | | j	 r¢ | j
 | j  | j
 | j  q¢ q¢ Wq Wqe Wy |  j | |  VWq t k
 r-} q Xq Wd S(   s   Perform a sequence alignment, try to find a sequence alignment window
    that produces the lowest lsq fit. Note that this is a generator.i   i   i    t   windowN(   i   i   i    (   R    t   cctbxt   array_familyt   flext   vec3_doublet   _seqalign_pickmatchest   rgRN   t   namet   i_seqR   t   xyzR~   R^   (   R   R?   R   R   R   R   t
   sel_movingt	   sel_fixedt   windowsR   R(   R   R   R   t   alignedt   it   jt   kt   atom1t   atom2t   e(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR   i  s     ,c   	      C   s   | | f } |  j  j |  r/ | r/ |  j  | Si d d 6d d 6d d 6d d 6} | | d	 <| | d
 <t j j |   } | j   } | r | |  j  | <n  | S(   s   Perform sequence alignment using mmtbx.alignment. Return alignment.

    Sequence alignments are cached; use cache=False to disable.
    i   t   gap_opening_penaltyi   t   gap_extension_penaltyt   blosum50t   similarity_functiont   globalt   stylet   seq_at   seq_b(   t   _seqalign_cacheRK   t   mmtbxR?   t   alignt   extract_alignment(	   R   R   R   R   t   cacheRD   t   optst	   align_objR?   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR2     s    


i    c         C   só   | j    } g  } xŚ t t j d  | j | j | | j | j  D]Ø \ } } } } }	 }
 | | } | d k  rz d } n  | | d } | t |  k r© t |  } n  | | | !} t	 d   | D  } | rC | j
 | | | f  qC qC W| S(   s   Find the indexes of aligned residues.

    Returns a list of lists with the indexes:
      [match index, sequence a index, sequence b index]
    i    i   c         s   s'   |  ] } | d  k p | d k Vq d S(   Rn   Rm   N(    (   t   .0R   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pys	   <genexpr>·  s    (   Ro   t   zipt	   itertoolsR(   t   i_seqs_at   i_seqs_bt   at   bR   R   R   (   R   R?   R   Ro   R   R   t   iat   ibt   imR“   Rµ   t   leftt   rightt   wR   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR     s(    	"
	c         C   sh   | j    } t | j  | j j d  } | j d  } | j d  } d | | t d |  } | S(   Nt   -Rm   Rn   g      Y@i   (   Ro   R   R“   R(   t   max(   R   R?   Ro   t   totalt   equalt   similarR@   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR3   ½  s    c         C   sn   g  } g  } xL |  j  j   D]; } |  j | |  j  \ } } | j |  | j |  q Wd j |  | f S(   s>   Extract the sequence and residue groups of the selected atoms.RX   (   R   R.   R1   RQ   R   t   extendRT   (   R   t   sequencet   rgsR   R“   Rµ   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR   Å  s    c         C   sg  g  } g  } d } x?| j    D]1} t } x. | j   j   D] } | | r> t } Pq> q> W| r t | j    d k rP| j   d }	 t j j	 j
 j |	 d  }
 |
 d k rź | j |
  | j t j d | d |   | d 7} qMt j j d |	 j    d k rM| j |	 j    | j t j d | d |   | d 7} qMqPq q Wd j |  | f S(	   s3   Extract the sequence and residue groups of a chain.i    i   t   XR   R   R   t   common_rna_dnaRX   (   t   residue_groupst   FalseRN   t   extract_i_seqRM   R   t   unique_resnamesR   R   t   amino_acid_codest   one_letter_given_three_letterRK   R   R[   t
   group_argst   common_residue_names_get_classt   stripRT   (   R   R   R   RĀ   RĆ   t   counterR   t   goodt   ait   resnamet   olc(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR1   Ļ  s,    
!c      	   C   s   |  j  j   } | j | j j | j   | j j  | j t j	 j
 j | j   d d d d d d g   |  j  j d | d |  j j    d S(   s6   Output PDB model to filename given transformation lsq.i’’’’t	   file_namet   crystal_symmetryg        (   R   RN   t   set_xyzRf   t   elemsRP   Ri   t   set_uijR   R   R   t   sym_mat3_doubleR   t   write_pdb_fileR   RÕ   (   R   Rk   R   t   output(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyRŪ   ė  s    '7c         C   sP   t  j j j   } x' | D] } | j | j   j    q W| j d |  d S(   s5   Merge multiple instances back into a single PDB file.RŌ   N(   R   R   R!   R"   R#   R-   R$   RŚ   (   R%   t	   instancesR   R   R   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   output_mergeö  s    N(   t   __name__t
   __module__t   __doc__RØ   R   RĒ   R   t   classmethodR+   R-   RB   R/   R   R   Rd   Rl   R5   R~   Rz   R   RM   R2   R   R3   R   R1   RŪ   RŻ   (    (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR   l   s0   		!)			% 		
		t   SuperposePDBSievec           B   s   e  Z d    Z RS(   c         C   sI   t  j j j d | d |  } | j   } | j |  } | | | | f S(   NR`   R_   (   Rx   Ry   Rz   t	   sieve_fitR|   RY   (   R   R_   R`   Rk   R}   Ra   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR~   ’  s    (   RŽ   Rß   R~   (    (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyRā   ž  s   t   SuperposePDBSCEDSc           B   s   e  Z d    Z RS(   c         C   s
   t   d  S(   N(   R,   (   R   R_   R`   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR~     s    (   RŽ   Rß   R~   (    (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyRä     s   s   phenix.superpose_pdbsc         C   s  d d  l  } t } t j j t d t } | j j d |  d | d t  }  |  j	 } d \ } } t |  j  d k r|  j d |  j d } } g  } t j j j d	 | d
 d   }	 | j |	 j d d |   | j |	 j d d |   | j d | d t  \ } }
 n  | j   } | j j | j j | j j } } } | d  k rh| d  k rht d   n  | j d |  d GHt | d | j d | j d | d | d | } t d | j d | j  d | d | d |  } x§ t! t j" | |   D] \ } } d | j# | j# f GH| j s-| j$ |  n  | j% |  \ } } | ród | | f } d | j# | f GH| j | d | qóqóWd  S(   Ni’’’’t   process_includest   argst   master_paramst    suppress_symmetry_related_errorsi   i    i   t   master_philt
   home_scopet   args   pdb_file_name_fixed=%ss   pdb_file_name_moving=%st   sourcest   track_unused_definitionss   Need two input PDB files.t   outs   
===== Init =====R   R   R   R   R   s   
===== Aligning %s to %s =====s	   %s-%s.pdbs$   
===== Writing %s output to %s =====R   (   NN(&   t   mmtbx.utilsRĒ   R   t   philt   parset   PHIL_PARAMSRM   t   utilst   process_command_line_argst   paramsR   R   t   pdb_file_namesR[   t   command_linet   argument_interpreterR   t   processt   fetcht   extractR   t   pdb_file_name_fixedt   pdb_file_name_movingRŪ   RŌ   R   t   showR   t   selection_fixedt   selection_fixed_presett   dictt   selection_movingt   selection_moving_presetR    R+   R   RB   Rz   (   Rę   t   command_nameR   R©   R   Rõ   Rt   R   Rģ   t   parameter_interpreterR9   t   peRŪ   t   moving_argsR(   Ra   Rk   R   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   run	  sR    !	!&						%	t   launcherc           B   s   e  Z d    Z RS(   c         C   s   t  d t |  j  d t j  S(   NRę   R   (   R  t   listRę   t   syst   stdout(   R   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR  F  s    (   RŽ   Rß   R  (    (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyR	  E  s   c         C   sS   |  d  k	 rI |  \ } } | d f g } d t d |  f g } | | f Sg  g  f S(   Ns   Superposed modelt   RMSDs   %.3f(   R   t   format_value(   t   resultt   output_fileRa   t   output_filest
   statistics(    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt
   finish_jobI  s    
c         C   sX   |  j  j d  k s$ |  j  j d  k r3 t d   n  |  j j d  k rT t d   n  d  S(   Ns   One or both PDB files missing.s*   Please specify a name for the output file.(   R   Rü   R   Rż   R   RŪ   RŌ   (   Rõ   (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   validate_paramsQ  s
    t   __main__Rę   i   (&   t
   __future__R    R  R   R±   t   cctbx.array_family.flexR   t	   iotbx.pdbR   t   iotbx.pdb.amino_acid_codest
   iotbx.philR[   t   libtbx.math_utilst   libtbx.philt   libtbx.runtime_utilst   mmtbx.alignmentR©   t   scitbx.mathRx   t   scitbx.math.superposet   libtbx.utilsR   Rņ   RJ   RL   t   objectR   Rā   Rä   R   R  t   runtime_utilst   target_with_save_resultR	  R  R  RŽ   t   argv(    (    (    s=   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/superpose.pyt   <module>   s>   N
’ <		