ó
Ÿ™xTc        	   @   sò  d  d l  m Z d  d l Z d  d l m Z d  d l Z d  d l m Z d  d l m	 Z	 d  d l
 Z d  d l m Z d  d l Z d  d l Z d d d „ Z d d d „ Z d	 „  Z d
 „  Z d d d „ Z e d „ Z e e d „ Z d d d „ Z d d d „ Z d d d d d d „ Z d d d d d d d d d „ Z d d e e d „ Z e d d „ Z g  d „ Z d „  Z  d „  Z! d „  Z" d „  Z# d „  Z$ d „  Z% d „  Z& d „  Z' d „  Z( d d d d  d! „ Z) d" „  Z* d# „  Z+ d$ „  Z, d S(%   iÿÿÿÿ(   t   divisionN(   t   flex(   t   monomer_library(   t   matrix(   t   xrayc         C   s�   g  } | r" |  r" |  j  ƒ  } n  | r‚ xW | D]L } xC | j D]8 } | j t t d | j j ƒ ƒ t | j j ƒ ƒ q? Wq/ Wn  t j	 | ƒ S(   s
  
  Concatenate rotation angles, corresponding to the rotation
  matrices and scaled translation vectors to a single long flex.double object

  Args:
    transforms_obj : (mmtbx.refinement.minimization_ncs_constraints
      ncs_group_object) containing information on Rotation matrices (lists of
      objects matrix.rec) and Translation vectors (lists of objects matrix.rec)
    ncs_restraints_group_list : a list of ncs_restraint_group objects

  Returns:
    flex.double : [(alpha_1,beta_1,gamma_1,Tx_1,Ty_1,Tz_1)...]
  t   rotation(
   t   get_ncs_restraints_group_listt   copiest   extendt   listt   rotation_to_anglest   rt   elemst   tR   t   double(   t   transforms_objt   ncs_restraints_group_listt   xt   grt   tr(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   concatenate_rot_tran   s    c         C   s€   g  } g  } | r( |  r( |  j  ƒ  } n  | rv xE | D]: } x1 | j D]& } | j | j ƒ | j | j ƒ qE Wq5 Wn  | | f S(   s½   
  Get rotations and translations vectors from ncs_restraints_group_list or
  transforms_obj

  Returns:
    r (list): list of rotation matrices
    t (list): list of translation vectors
  (   R   R   t   appendR   R   (   R   R   R   R   t   nrgR   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt    get_rotation_translation_as_list&   s    
c         C   sŒ   t  |  j ƒ t  | ƒ k s! t ‚ t  | ƒ t  | ƒ k s? t ‚ xF t |  j | | ƒ D]/ \ } } } | |  j | _ | |  j | _ qU W|  S(   sV    Update transforms_obj with the rotation matrices (rm) and translation
  vectors (tv) (   t   lent   transform_ordert   AssertionErrort   zipt   ncs_transformR   R   (   R   t   rmt   tvR   R   R   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   update_transforms;   s    !%c         C   s~   t  | ƒ t  | ƒ k s t ‚ g  } xS |  D]K } x5 | j D]* } | j d ƒ | _ | j d ƒ | _ q; W| j | ƒ q+ W| S(   sa    Update ncs_restraints_group_list with the rotation matrices (rm) and
  translation vectors (tv) i    (   R   R   R   t   popR   R   R   (   R   R   R   t   new_listR   R   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt    update_ncs_restraints_group_listE   s    c         C   s7  t  | ƒ t  | ƒ k s t ‚ | r4 | j ƒ  } n  | r3d } xÒ | D]Ê } g  } x² | j D]§ } |  | d | d d !\ } } }	 t j j d | d | d |	 d t ƒ }
 t j	 |  | d d | d d !d
 ƒ } |
 j
 ƒ  | _ | | _ | j | ƒ | d 7} q] W| | _ qG W| r,| j | ƒ | S| Sn  d	 S(   sx  
  Convert the refinable parameters, rotations angles and
  scaled translations, back to rotation matrices and translation vectors and
  updates the transforms_obj (ncs_restraints_group_list)

  Args:
    x : a flex.double of the form (theta_1,psi_1,phi_1,tx_1,ty_1,tz_1,..
      theta_n,psi_n,phi_n,tx_n/s,ty_n/s,tz_n/s). where n is the number of
      transformations.
    transforms_obj : (ncs_group_object) containing information on Rotation
      matrices, Translation vectors and NCS
  ncs_restraints_group_list : a list of ncs_restraint_group objects

  Returns:
    The same type of input object with converted transforms
  i    i   i   t   thet   psit   phit   degi   N(   i   i   (   t   boolR   R   R   t   scitbxt
   rigid_bodyt
   rb_mat_xyzt   FalseR   t   rect   rot_matR   R   R   t&   update_using_ncs_restraints_group_list(   R   R   R   t   iR   R   R   R#   R$   R%   t   rott   tran(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   update_rot_tranQ   s,    ")	c      	   C   sŠ  t  |  t t j ƒ  ƒ ƒ s- t j |  ƒ }  n  |  j d ƒ \	 } } } } } } } }	 }
 | d	 k rÏ t j | ƒ } t j | t j | ƒ |
 t j | ƒ ƒ } t j | t j | ƒ | t j | ƒ ƒ } nv | d k rt j	 d } t j | | ƒ } d } nB | d k r9t j	 d } t j | | ƒ } d } n t
 d ƒ ‚ t j | | | f ƒ } | r†d | t j	 } | j d ƒ } n  | S(
   sO  
  Get the rotation angles around the axis x,y,z for rotation r
  Such that r = Rx*Ry*Rz
  Those angles are the Tait-Bryan angles form of Euler angles

  Note that typically there are two solutions, and this function will return
  only one. In the case that cos(beta) == 0 there are infinite number of
  solutions, the function returns the one where gamma = 0

  Args:
    r : (flex.double) of the form (Rxx,Rxy,Rxz,Ryx,Ryy,Ryz,Rzx,Rzy,Rzz)
    deg : When False use radians, when True use degrees

  Returns:
    angles (flex.double): (alpha, beta, gamma) rotation angles around the x,y,z
  i   i   iÿÿÿÿi   i    s   Can't calculate rotation anglesi´   i   (   i   iÿÿÿÿ(   t
   isinstancet   typeR   R   t   roundt   matht   asint   atan2t   cost   pit   ArithmeticError(   R   R&   t   Rxxt   Rxyt   Rxzt   Ryxt   Ryyt   Ryzt   Rzxt   Rzyt   Rzzt   betat   alphat   gammat   angles(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyR
   z   s*    *-0		c   	   	   C   sŸ   t  |  ƒ d k s t ‚ |  \ } } } t j j d | d | d | d | ƒ } | j ƒ  } | ri d } n d } | r… | j | ƒ j St j	 | j | ƒ ƒ Sd S(	   ss  
  Calculate rotation matrix R, such that R = Rx(alpha)*Ry(beta)*Rz(gamma)

  Args:
    angles_xyz : (flex.double) (alpha,beta,gamma)
    deg : (bool) When False use radians, when True degrees
    rotation_is_tuple : (bool) when False, return flxe.double object,
      when True return tuple

  Returns:
  R : (tuple or flex.double) the components of a rotation matrix
  i   R#   R$   R%   R&   i   i   N(
   R   R   R(   R)   R*   R-   R5   R   R   R   (	   t
   angles_xyzR&   t   rotation_is_tupleRF   RE   RG   R0   t   RR/   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   angles_to_rotation¬   s    ' 	gìQ¸…ë¡?g      à?c         C   sù   t  j ƒ  } xæ t d t |  ƒ d ƒ D]Ì } | j t j |  | d | ƒ ƒ | j t j |  | d | ƒ ƒ | j t j |  | d | ƒ ƒ | j t j |  | d | ƒ ƒ | j t j |  | d | ƒ ƒ | j t j |  | d | ƒ ƒ q% W| S(   sö  
  Shake rotation matrices and translation vectors of a rotation matrices and
  translation vectors from the MTRIX records in a PDB file.

  Args:
    x (flex.double): [(alpha_1,beta_1,gamma_1,Tx_1/s,Ty_1/s,Tz_1/s)...]
    shake_angles_sigma (float): the sigma (in radians) of the random gaussian
      shaking of the rotation angles
    shake_translation_sigma (float): the sigma (in angstrom) of the random
      gaussian shaking of the translation

  Return:
    new_x (flex.double): The shaken x
  i    i   i   i   i   i   i   (   R   R   t   xrangeR   R   t   randomt   gauss(   R   t   shake_angles_sigmat   shake_translation_sigmat   new_xR/   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   shake_transformationsÅ   s    !!!!!%c         C   s   t  | ƒ t  | ƒ k s t ‚ | r4 | j ƒ  } n  g  } t j |  ƒ }  d } x¡| D]™} | j | j ƒ } | j ƒ  }	 t j | j ƒ  g ƒ d |	 }
 | t j t	 |
 ƒ |	 ƒ } x5| j
 D]*} |  j | j ƒ } |	 | j ƒ  k sñ t ‚ t	 | j ƒ  ƒ } | j | ƒ } t j | ƒ } | | d | d d !\ } } } t j j d | d | d | d t ƒ } | | j ƒ  j ƒ  j ƒ  } | | j ƒ  j ƒ  j ƒ  } | | j ƒ  j ƒ  j ƒ  } | j | | | g ƒ | j | ƒ | d 7} qÁ WqV Wt j | ƒ S(	   s|  
  Compute gradient in respect to the rotation angles and the translation
  vectors. R = Rx(the)Ry(psi)Rz(phi)

  Args:
    grad_wrt_xyz (flex.double): gradients with respect to xyz.
    ncs_restraints_group_list: list containing ncs_restraint_group objects
    transforms_obj (ncs_group_object): containing information in rotation
      matrices and to which chains they apply
    xyz_asu (flex.vec3): The coordinates sites cart of the complete ASU
    x (flex double): The angles, in the form
      (theta_1,psi_1,phi_1,tx_1,ty_1,tz_1,..
      theta_n,psi_n,phi_n,tx_n/s,ty_n/s,tz_n/s)

  Returns:
    g (flex.double): the gradient
  i    i   i   i   R#   R$   R%   R&   (   R'   R   R   R   t   vec3_doublet   selectt   master_iselectiont   sizet   sumR	   R   t
   iselectiont   transpose_multiplyR   t   sqrR(   R)   R*   R+   t   r_thet	   transposet   tracet   r_psit   r_phiR   R   (   t   grad_wrt_xyzt   xyz_asuR   R   R   t   gR/   R   t   xyz_ncs_transformt   xyz_lent   mu_ct   xyz_cmt   nrg_copyt   grad_ncs_wrt_xyzt
   grad_wrt_tt   mR#   R$   R%   R0   t   g_thet   g_psit   g_phi(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   compute_transform_gradà   s6     "c         C   s  |  r± t  |  d ƒ r! |  j } n | s- t ‚ t  |  d ƒ rO |  j ƒ  j | ƒ St  |  d ƒ r} |  j j j | ƒ } | j ƒ  St  |  d ƒ s’ | r|  j j ƒ  } | j | ƒ SnW | rÇ | ƒ  j | ƒ S| ré | j j | ƒ } | j ƒ  S| r| j ƒ  } | j | ƒ Sd S(   sÙ   
  Args::
    ncs_obj: an object that contains fmodel, sites_cart or xray_structure
      and an atom selection flags for a single NCS copy.

  Returns:
    (flex.vec3): coordinate sites cart of the single NCS copy
  t   extended_ncs_selectiont
   sites_cartt   fmodelt   xray_structureN(   t   hasattrRp   R   Rq   RU   Rr   Rs   (   t   ncs_objRr   Rs   Rq   Rp   t   xrs_one_ncs(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   get_ncs_sites_cart  s(    

c         C   s†  | } d }	 | rl | }
 |
 j }  |
 j } |
 j } |
 j } |
 j } |
 j } t |
 d ƒ rl |
 j }	 ql n  |	 sŠ t	 d | d | ƒ }	 n  t
 |  ƒ s¢ t d ƒ ‚ t
 | ƒ sº t d ƒ ‚ | | | g j t ƒ d k sä t d ƒ ‚ | g  k } |  j ƒ  } | r| j j d d	 ƒ nO | r.| j j ƒ  n9 | rg| rgt d | ƒ } t d
 | d d d d ƒ } n  | j d | j d t ƒ | j j ƒ  j d t ƒ | s¥| rt j d | j j ƒ  d t ƒ t j | j d t ƒ j ƒ  ƒ } | j d | j j ƒ  d t ƒ j  } nÁ | rÍd d l! } | j" j# j$ } | j% ƒ  j& } | j d | j j ƒ  d t ƒ j  } t j d | j j ƒ  d t ƒ | j d t ƒ j' ƒ  } | j( d | j d | d | j) d t d t ƒ j  } n  | r<| r<t* d | j' ƒ  d | d | j j ƒ  d
 | ƒ } t* d | j' ƒ  d | d | j j ƒ  d
 | ƒ } n  d } | j+ ƒ  } | j+ ƒ  } | d k rs| | } n  t, | d  ƒ } | S(!   sN  
  Calculates weights for refinements by slightly shaking the minimized
  parameters and taking the ratio:
  (restraint manager grad norm / parameters gradient norm)


  When calling this function during refinement macro cycle, the minimized
  object, "minimized_obj" , may contains fmodel, restraints_manager,
  refinement type info (sites, transformations, u_iso) and
  ncs_restraints_group_list.


  Args:
    fmodel : F-model object
    restraints_manager: Restraints manager object
    sites (bool): Refine by sites
    u_iso (bool): Refine using u_iso
    transformations (bool): Refine using transformations
      rotations, translations (matrix objects):
    ncs_restraints_group_list: list of ncs_restraint_group objects
    refine_selection (flex.size_t): selection of all ncs related copies and
      non ncs related parts to be included in selection (to be refined)
    minimized_obj:Minimization object containing all the other
      parameters above

  Returns:
    weight (int):

  Example:
  >>>get_weight(minimized_obj=minimized_obj)

  or

  >>>get_weight(fmodel=fmodel,
                restraints_manager=grm,
                sites=sites,
                transformations=transformations,
                u_iso=u_iso,
                ncs_restraints_group_list=ncs_restraints_group_list,
                refine_selection=refine_selection)
  Rp   R   t   refine_selections   F-model is not provideds$   F-restraints_manager is not providedi   s   Refinement type Errort   mean_distanceg333333Ó?R   RP   gìQ¸…ë¡?RQ   g      à?Rs   t   update_f_calct   statet
   scattererst   siteRq   t   compute_gradientsiÿÿÿÿNt   u_isot
   parameterst   use_u_local_onlyt   use_hdRa   Rb   g      ð?g        g    €„.A(-   t   NoneRr   t   grmt   sitest   transformationsR   R   Rt   Rp   t   get_extended_ncs_selectionR'   R   t   countt   Truet	   deep_copyRs   t   shake_sites_in_placet	   shake_adpR   RS   t   update_xray_structureR|   t   flags_set_gradsR+   R   t   set_scatterer_grad_flagsR   RT   t(   one_time_gradients_wrt_atomic_parameterst   packedt   energies_sitesRq   t	   gradientst   mmtbx.refinement.adp_refinementt
   refinementt   adp_refinementt   adp_restraints_master_paramst   extractt   isot	   as_doublet   energies_adp_isoR�   Ro   t   normt   min(   Rr   t   restraints_managerR…   R†   R   R   Rx   t   minimized_objR„   Rp   t   mot   have_transformst   fmdcR   t   gxct   gct   mmtbxt   tempt   iso_restraintst   weightt   gc_normt   gxc_norm(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt
   get_weight;  s     1						*										c         C   sA  |  | g j  d ƒ d k s! t ‚ t j j ƒ  } t j j ƒ  } | rT | j ƒ  } n d } t j j d | d | d |  d | d t	 ƒ } | j
 d t d d	 ƒ } t j j d
 | d | ƒ }	 | r9g  t | ƒ D]( }
 d |
 k rÍ |
 d d k rÍ |
 ^ qÍ } d „  } t g  | D] }
 t | |
 ƒ ƒ ^ qƒ } |	 | f S|	 Sd S(   s�     Generate restraint manager from a PDB file or a PDB string

  Args:
    return_data_num (bool): when True, return the number of restraints
  i   t   mon_lib_srvt   ener_libt	   file_namet   raw_recordst   force_symmetryt   show_energiest   plain_pairs_radiusg      @t   geometryt   normalizationt   proxiesi    t   _c         S   s   d |  d S(   NR³   t   .s   .__sizeof__()s	   geometry.(    (   R   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   <lambda>è  s    N(   Rˆ   Rƒ   R   R   t   serverR­   t
   splitlinest   pdb_interpretationt   processR‰   t   geometry_restraints_managerR+   R¥   t
   restraintst   managert   dirRX   t   eval(   t   pdb_file_namet
   pdb_stringR´   t   return_data_numR¬   R­   t	   pdb_linest   ppfR³   Rž   R   Rµ   t   len_strt   n_data(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   get_restraints_managerÊ  s.    ! 			;	+
c         C   sü   t  j d g | ƒ } | j | |  ƒ t | ƒ rJ t d | d | ƒ } n  x‚ | D]z } t  j | | j ƒ } x\ | j D]Q }	 t  j | |	 j ƒ }
 | j | ƒ } |	 j	 j
 | |	 j } | j |
 | ƒ qv WqQ W| rë t  j | ƒ j d ƒ St  j | ƒ Sd S(   sM  
  Apply transformation to ncs_coordinates,
  and round the results if round_coordinates is True

  Args:
    ncs_coordinates (flex.vec3): master ncs coordinates
    ncs_restraints_group_list: list of ncs_restraint_group objects
    total_asu_length (int): Complete ASU length
      extended_ncs_selection (flex.size_t): master ncs and non-ncs related parts
    center_of_coordinates : when not None, contains the center of coordinate of
      the master for each ncs copy

  Returns:
    (flex.vec3_double): Asymmetric or biological unit parts that are related via
      ncs operations
  i    t   shiftsR   i   N(   i    i    i    (   R   RT   t   set_selectedR'   t   shift_translation_back_to_placeRV   R   RY   RU   R   R   R   R5   (   t   ncs_coordinatesR   t   total_asu_lengthRp   t   round_coordinatest   center_of_coordinatest   asu_xyzR   t   master_ncs_selectiont   ncs_copyt   copy_selectiont   ncs_xyzt	   new_sites(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   apply_transformsî  s     c         C   sâ   t  | ƒ } t  ƒ  } t  ƒ  } xZ |  D]R } | j } | j t  | ƒ ƒ x- | j D]" } | j } | j t  | ƒ ƒ qQ Wq% W| rË | | B} d }	 t | | ƒ s® t |	 ƒ ‚ | | }
 t j t	 |
 ƒ ƒ St j t	 | ƒ ƒ Sd S(   s`  
  Args:
    ncs_restraints_group_list: list of ncs_restraint_group objects
    refine_selection (flex.siz_t): of all ncs related copies and
      non ncs related parts to be included in selection (to be refined)

  Returns:
    (flex.siz_t): selection of all ncs groups master ncs selection and
      non ncs related portions that are being refined
  s7   refine_selection does not contain all ncs related atomsN(
   t   setRV   t   updateR   RY   R'   R   R   t   size_tR	   (   R   Rx   t   total_master_ncs_selectiont   total_ncs_related_selectionR   RÒ   RÓ   t   asu_selectiont   all_ncst   msgRp   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyR‡     s     				

c   
      C   s§   t  ƒ  } t  ƒ  } xZ |  D]R } | j } | j t  | ƒ ƒ x- | j D]" } | j } | j t  | ƒ ƒ qE Wq W| j | ƒ t j t | ƒ ƒ } t j | | ƒ }	 |	 S(   s×   
  Args:
    ncs_restraints_group_list (list): list of ncs_restraint_group objects
    asu_size (int): the total size of the ASU

  Returns:
    selection (flex.bool): selection of all ncs related atom in the ASU
  (	   RØ   RV   RÙ   R   RY   R   RÚ   R	   R'   (
   R   t   asu_sizeRÛ   RÜ   R   RÒ   RÓ   RÝ   t   tst	   selection(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   get_ncs_related_selection8  s    					c         C   s�   t  |  ƒ r‹ t | ƒ } d } xj | D]_ } xV | j D]K } |  | } | d 7} | j j | | j | } t j | d ƒ | _ q5 Wq% Wn  | S(   sw  
  Add shifts to the translation component of ncs_restraints_group_list
  towards the center of coordinates

  Args:
    shifts (list): [mu_1, mu_1, mu_2...] where the mu stands
      for the shift of the master copy to the coordinate center mu is (dx,dy,dz)
    ncs_restraints_group_list (list): ncs_restraints_group_list

  Returns:
    ncs_restraints_group_list (list):
  i    i   (   R'   t   ncs_restraints_group_list_copyR   R   R   R   R   t   col(   RÊ   R   R!   R/   R   RÓ   t   muR   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   shift_translation_to_centerO  s    

!c         C   s•   t  |  ƒ r‹ d } t | ƒ } xp | D]_ } xV | j D]K } |  | } | d 7} | | j j | | j } t j | d ƒ | _ q5 Wq% Wn | } | S(   s‹  
  shifts to the translation component of ncs_restraints_group_list from the
  center of coordinates back to place

  Args:
    shifts (list): [mu_1, mu_1, mu_2...] where the mu stands
      for the shift of the master copy to the coordinate center mu is (dx,dy,dz)
    ncs_restraints_group_list: ncs_restraints_group_list

  Returns:
    new_list (list): list of ncs_restraints_group objects
  i    i   (   R'   Rä   R   R   R   R   R   Rå   (   RÊ   R   R/   R!   R   RÓ   Ræ   R   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyRÌ   h  s    

!c   	      C   s”   g  } |  j  ƒ  } x{ | D]s } | j } | j | ƒ } t j | j ƒ  ƒ t | ƒ } t j | j	 g ƒ } x | j
 D] } | j | ƒ qu Wq W| S(   s  
  calculate the center of coordinate for the master of each ncs copy

  Args:
    xray_structure
    ncs_restraints_group_list

  Returns:
    shifts (list): [mu_1, mu_1, mu_2...] where the mu stands
    for the shift of the master copy to the coordinate center mu is (dx,dy,dz)
  (   Rq   RV   RU   R   Rå   RX   R   R   RT   R   R   R   (	   Rs   R   RÊ   RÑ   R   RÒ   t
   master_xyzt   mu_mRÓ   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   get_ncs_gorups_centersƒ  s    	c      	   C   sŸ   d d l  m } d d l  m } g  } xr |  D]j } | | j ƒ } xE | j D]: } | d | j d | j d | j ƒ } | j j | ƒ qL W| j | ƒ q- W| S(   s³   
  Deep copy of ncs_restraints_group_list

  Args:
    ncs_restraints_group_list: list of ncs_restraint_group

  Returns:
    new_list: a deep copy of ncs_restraints_group_list
  iÿÿÿÿ(   t   ncs_restraint_group(   RÓ   t   copy_iselectionR0   R1   (	   t   iotbx.ncs.ncs_preprocessRë   RÓ   RV   R   RY   R   R   R   (   R   Rë   RÓ   R!   R   t   new_nrgt   ncst   new_ncs_copy(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyRä   š  s    
		c            s·  t  | t j ƒ r! | j ƒ  } n  t | ƒ } t |  ƒ } xw| D]o} t | j ƒ } g  t t | j ƒ ƒ D] \ } } | | f ^ qk } | j	 | ƒ ‰ ‡ f d †  | Dƒ }	 x– | j
 D]‹ }
 t |
 j ƒ } g  t t |
 j ƒ ƒ D] \ } } | | f ^ qã } | j	 | ƒ ‰  ‡  f d †  | Dƒ } |	 j | ƒ t |	 ƒ s¸ Pq¸ q¸ Wt | j |	 ƒ \ | _ } t | | ƒ } x; | j
 D]0 }
 t |
 j |	 ƒ \ |
 _ } t | | ƒ } q{Wq@ W| S(   s4  
  Modifies the selections of master and copies according the "selection"
  - Keep the order of selected atoms
  - Keep only atoms that appear in master and ALL copies
  Also modify "selection" to include ncs related atoms only if selected in
  both master and ALL ncs copies (The modified selection is not returned in
  current version)

  Args:
    ncs_restraints_group_list (list): list of ncs_restraints_group objects
    selection (flex.bool or flex.size_t): atom selection

  Returns:
    new_nrg_list (list): list of modified ncs_restraints_group objects
  c            s(   h  |  ] \ } } | ˆ  k r | ’ q S(    (    (   t   .0t   post   indx(   t   m_in_sel(    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pys	   <setcomp>Ê  s   	 c            s(   h  |  ] \ } } | ˆ  k r | ’ q S(    (    (   Rñ   Rò   Ró   (   t   copy_in_sel(    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pys	   <setcomp>Ï  s   	 (   R3   R   R'   RY   RØ   Rä   RV   t	   enumerateR	   t   intersectionR   t   intersection_updatet   selected_positionst   remove_items_from_selection(   R   Râ   t   sel_sett   new_nrg_listR   Rk   Rò   Ró   t   m_listt   common_selection_posRï   t   ct   c_listt   include_sett   not_included(    (   Rõ   Rô   sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   ncs_groups_selection²  s2     44 c         C   s›   t  |  t j ƒ s t ‚ t  | t ƒ r? t j t | ƒ ƒ } n  t  | t ƒ r` t j | ƒ } n  t j |  j ƒ  | ƒ } | } |  j | ƒ |  j | ƒ f S(   sÔ  
  Returns only the selected indices in the positions specified in "positions"
  keeping the order

  Args:
    selection (flex.size_t): Atoms selection
    positions (set or list): the allowed positions in the selections

  Returns:
    (flex.size_t, flex.size_t): (selected atoms, atoms, not selected)

  Examples::
    >>>a = flex.size_t([1,2,5,6,4])
    >>>pos = {0,3,4}
    >>>s,d = selected_positions(a,pos)
    >>>list(s)
    [1,6,4]
    >>>list(d)
    [2,5]
  (	   R3   R   RÚ   R   RØ   R	   R'   RW   RU   (   Râ   t	   positionst   includet   not_include(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyRù   Þ  s      c         C   sJ   t  |  ƒ }  t | ƒ } g  |  D] } | | k r | ^ q } t j | ƒ S(   sk  
  Remove a set of atoms from "selection"

  Args:
    selection (flex.size_t): atom selection
    remove (flex.size_t): atoms to remove from selection

  Returns:
    (flex.size_t): modified atom selection

  Examples::
    >>>a = flex.size_t([1,2,5,6,4])
    >>>r = flex.size_t([2,5])
    >>>s = remove_items_from_selection(a,r,10)
    >>>list(s)
    [1,6,4]
  (   R	   RØ   R   RÚ   (   Râ   t   removeR   t   new_selection(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyRú   ú  s    %c   	      C   sd  t  | t ƒ s t ‚ t |  ƒ t | ƒ k s3 t ‚ x*t |  | ƒ D]\ } } | d k ra qC n  | d } | j | j | j | _ | j | _ | j | j j	 ƒ  } | j | _ | j | j | j | j
 } | j | _
 xv t | j ƒ D]e \ } } | | k ró | j | j | | j | j
 | j | _
 | j | j | | j | _ qó qó WqC W|  S(   sE  
  Switch master NCS copy with one of the copies, as specified in the new_masters

  Args:
    ncs_restraints_group_list: list of ncs restraints group objects
    new_masters (list of integers): the number of the copy, in each group,
      that will become the new master

  Returns:
    Modified ncs_restraints_group_list
  i    i   (   R3   R	   R   R   R   R   RY   RV   R   R]   R   Rö   (	   R   t   new_mastersR   Rÿ   t   c_iR   R   R/   Rï   (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   change_ncs_groups_master  s     
'$-,)g      ð?c      	   C   s­   g  } t  j j j d | d | d | d | ƒ } xv |  D]n } g  } | j | j ƒ x! | j D] }	 | j |	 j ƒ q] W| j d | ƒ }
 | j |
 j	 t
 |
 ƒ ƒ ƒ q7 W| S(   ss  
  Finds the copy with best map correlation in each ncs group

  Args:
    ncs_restraints_group_list: list of ncs restraints group objects
    xray_structure (object):
    fmodel (object):
    map_data (object):
    d_min (float): min data resolution

  Returns:
    best_list (list of int): list of the copy with the best map correlation.
      (the master copy is 0)
  Rs   Rr   t   map_datat   d_mint
   selections(   R¥   t   mapst   correlationt%   from_map_and_xray_structure_or_fmodelR   RV   R   RY   t   cct   indext   max(   R   Rs   Rr   R  R  t	   best_listt   mpR   R  Rï   R  (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt)   get_list_of_best_ncs_copy_map_correlation3  s    	 c         C   s:   t  |  ƒ s6 t | j ƒ  j ƒ  ƒ } t j | ƒ }  n  |  S(   sD    populate refine_selection with all atoms if no selection is given  (   R'   t   rangeRq   RW   R   RÚ   (   Rx   Rs   t   selection_list(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   get_refine_selectionW  s    c   	      C   s„   | j  ƒ  j ƒ  } | j ƒ  j } | d | ƒ } | j | ƒ } | j ƒ  } t t | ƒ ƒ } |  | 7}  t j	 | |  ƒ } | j ƒ  S(   s÷   
  Convert iselection of NCS related atoms in the NCS copy to the ASU iselection

  Args:
    ncs_len (int)
    ncs_chain_id (str)
    iselection_ncs (flex.size_t)
    hierarchy_asu hierarchy object)

  Returns:
    iselection_asu (flex.size_t)
  s   chain (
   t   atomsRW   t   atom_selection_cacheRâ   RU   RY   R�   R	   R   R'   (	   t   iselection_ncst   ncs_chain_idt   hierarchy_asut   asu_lent
   atom_cachet   selt   hierarchy_ncst   offsett   selection_bool(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   iselection_ncs_to_asu_  s    
c         C   s?   | j  ƒ  } | j d | ƒ } t t | j ƒ  ƒ ƒ } |  | S(   sæ   
  Convert iselection of NCS related atoms in the NCS copy to the ASU iselection

  Args:
    ncs_chain_id (str)
    iselection_asu (flex.size_t)
    hierarchy_ncs (hierarchy object)

  Returns:
    iselection_ncs (flex.size_t)
  s   chain (   R  Râ   R�   R	   RY   (   t   iselection_asuR  R  R!  t   ph_ncs_selectt   chain_start(    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   iselection_asu_to_ncsv  s    (-   t
   __future__R    t   mmtbx.maps.correlationR¥   t   scitbx.array_familyR   t   mmtbx.monomer_library.serverR   R(   R   t   scitbx.rigid_bodyt   cctbxR   RN   R6   Rƒ   R   R   R   R"   R2   R+   R
   RL   RS   Ro   Rw   R«   R‰   RÉ   R×   R‡   Rã   Rç   RÌ   Rê   Rä   R  Rù   Rú   R  R  R  R&  R*  (    (    (    sA   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/mmtbx/ncs/ncs_utils.pyt   <module>   sp   	
	)22!ˆ'% 						,			$		