ó
šxTc           @   s  d  d l  m 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	 Z
 d Z d Z d	 Z d
 Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z i e d 6e d 6e d 6e d 6e d 6Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z i e d 6e d  6Z d! „  Z  d" „  Z! d# „  Z" d$ „  Z# i e  e" f d% 6e! e# f d& 6Z$ d' „  Z% d( „  Z& d) „  Z' d* „  Z( d+ „  Z) i d, „  d- 6d. „  d/ 6d0 „  d1 6d2 „  d3 6d4 „  d5 6Z* d6 „  Z+ d7 „  Z, d8 „  Z- d9 „  Z. i e+ d: 6e, d; 6Z/ e j0 j1 d< i e j2 d= e d> d ƒ d? 6e j2 d= e$ d> d% ƒ d@ 6e j2 d= e d> d  ƒ dA 6e j2 d= e* d> d- ƒ dB 6e j2 d= e/ d> d: ƒ dC 6dD e3 ƒZ4 e4 Z5 dE „  Z6 e j7 j8 dF „ Z9 dG e j: f dH „  ƒ  YZ; dI „  Z< d S(J   iÿÿÿÿ(   t   division(   t   with_statement(   t	   tbx_utils(   t   output(   t   runtime_utilsNt	   ensemblers   0.2.0i   i   c         C   s.  d d l  m } g  } x� |  D]‡ } | j d d | j ƒ | j ƒ  xS | j ƒ  D]E } | j j d | j ƒ s‰ | j d d | ƒ qQ n  | j	 | ƒ qQ W| j
 ƒ  q W| j d t j d d ƒ ƒ xc t | d	 d
 ƒD]O \ } } d | | f } | j d  k	 r| d | j 7} n  | j d | ƒ q× W| S(   Niÿÿÿÿ(   t   mmtt   msgs   Processing %s...t   chains   %s: not protein. Discardedt   texts   Chains found:t   starti   s   %d: %ss   , identity wrt target: %.1f(   t   phaserR   t   infot   namet   indentt   get_chain_infost   PROTEINt   recognize_chain_typeR   t   appendt   dedentR   t   headingt	   enumeratet   identityt   None(   t   pdbst   loggerR   t   datat   fR   t   indext   message(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   find_chains   s&    
	c         C   s×   | j  d d ƒ | j ƒ  i  } t |  ƒ } xw t |  ƒ D]i \ } } | j  d | ƒ xI | j j ƒ  D]8 } | j | j ƒ  | j f d  g | ƒ } | | | <qf Wq9 W| j
 ƒ  g  t | ƒ D] }	 | |	 ^ q½ }
 |
 S(   NR   s.   ( resseq, icode ) will be used to map residuess   Mapping %s...(   R   R   t   lenR   R   t   residue_groupst
   setdefaultt   resseq_as_intt   icodeR   R   t   sorted(   t   infost
   alignmentsR   t
   equiv_witht   countR   R   t   rgt   arrayt   residt   mapping(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   map_by_resid3   s    

#c            sU  | j  d d ƒ |  s t ‚ t d „  | Dƒ ƒ s8 t ‚ | sJ t d ‚ n  g  | D]D } d j g  | j j d D] } | | j j k rn | ^ qn ƒ ^ qQ ‰ t ‡ f d †  ˆ d Dƒ ƒ sÇ t d	 ‚ n  | j  d d
 ƒ | j  d ˆ d ƒ d d l m	 } d d l m
 } d d l m } t t | j j | j j ƒ ƒ } g  ‰  d }	 x¼|  D]´}
 | j  d d |
 ƒ | j ƒ  |
 j j ƒ  } x~| D]_} | j d | j d | d | j j d | d |	 ƒ \ } } | d k  rÚq‰n  | j j d } | j j | } t | ƒ t | ƒ k s(t d | | f ƒ ‚ | j  d d | j ƒ | j  d d ƒ | j  d | j d | | g d d d g ƒ ƒ t d | d | d | d |	 ƒ ˆ  j g  t | | ƒ D]$ \ } } | | j j k r²| ^ q²ƒ | j ƒ  Pq‰W| j ƒ  t d  |
 ‚ qOWt |  ƒ t ˆ  ƒ k s%t ‚ t ‡  f d! †  ˆ  d Dƒ ƒ sKt ‚ t ˆ  Œ  S("   NR   s'   Alignments will be used to map residuesc         s   s   |  ] } | j  j Vq d  S(   N(   t   objectR&   (   t   .0t   alf(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pys	   <genexpr>R   s    s   No alignments givent    i    c         3   s   |  ] } | ˆ  d  k Vq d S(   i    N(    (   R/   t   ali(   t
   references(    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pys	   <genexpr>_   s    i   s4   Unsuitable alignment set: different master sequencess   Master sequence:iÿÿÿÿ(   R   (   t   rsam(   t   bioinformaticsi   s   Mapping %s...t	   alignmentt   residuest   consecutivityt   one_letter_fort
   min_lengths   len( %s ) != len( %s )s   Matching sequence found in %ss   Mapping to master:R&   t   namest   MASTERt   CURRENTt   presentR,   R   s   No matching alignment for %sc         3   s+   |  ]! } t  | ƒ t  ˆ  d  ƒ k Vq d S(   i    N(   R   (   R/   t   t(   R,   (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pys	   <genexpr>¢   s    (   R   t   AssertionErrort   allt   RuntimeErrort   joinR.   R&   t   gapR   R   R4   t   iotbxR5   t   dictt   zipR   t   three_letter_codest   one_letter_codesR   R   R    t   map_to_alignmentR8   R   R   t   clustal_alignmentt   log_residue_discardR   R   (   R%   R&   R   R0   t   cR   R4   R5   R9   R:   R   t   rgsR   t   rmapt   mastert   seqR)   (    (   R,   R3   s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   map_by_alignmentsN   sl    N 
		.		;

&c         C   sð  | j  d d ƒ |  s t ‚ | j  d d |  d ƒ |  d j } | j ƒ  } | g } d „  } d d  l } | j ƒ  x%|  d D]} | j  d d | ƒ | j j ƒ  }	 y7 | j d	 | d
 | j ƒ }
 | j d |
 d | ƒ } Wn  t k
 r} t d | ‚ n Xd  g t
 | ƒ } xs | j D]h \ } } | d  k s | d  k rJq n  | t
 | ƒ k  sbt ‚ | t
 |	 ƒ k  szt ‚ |	 | | | <q W| j | ƒ q€ W| j ƒ  t g  | d D]" } t
 | ƒ t
 | d ƒ k ^ qµƒ sæt ‚ t | Œ  S(   NR   s    SSM will be used to map residuess   Reference: %si    c         S   sJ   t  g  t |  j ƒ  ƒ D]- \ } } |  j | j ƒ  | j f | f ^ q ƒ S(   N(   RF   R   R    t   idR"   R#   (   R   t   iR)   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   <lambda>±   s   iÿÿÿÿi   s   Mapping %s...t	   referencet   movingt   matcht   indexers   SSM error: %s(   R   R@   R   R    t   ccp4io_adaptbxR   t   SecondaryStructureMatchingt   SSMAlignmentRB   R   R   t   pairsR   R   RA   RG   (   R%   R&   R   RV   t   reference_rgsR,   RY   RZ   R   RN   t   ssmR6   t   et   mt   curt   refR?   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt
   map_by_ssm§   s<    		
	
?c         C   sg   | j  d d ƒ | s" t d ‚ n  t | ƒ d k rG | j d d ƒ n  t d |  d | d j d	 | ƒ S(
   NR   s1   A multiple alignment will be used to map residuess   No alignments giveni   s7   Several alignment files specified; using first one onlyR%   R6   i    R   (   R   RB   R   t   warningt   chain_mapping_via_alignmentR.   (   R%   R&   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   map_by_multiple_alignmentÜ   s    	
c         C   sX  | j  d d ƒ g  } d d l m } d d l m } d d l m } t t | j j	 | j j
 ƒ ƒ } xv t |  d d ƒD]b \ } }	 | j d	 d
 | d | j d |	 j j ƒ  d | d | j j ƒ ƒ }
 | j t |
 ƒ ƒ qz Wd d l m } | d d j | ƒ ƒ } | j  d d | ƒ | j  d d ƒ t d |  d | ƒ t d |  d | d | ƒ S(   NR   s*   phenix.muscle will be used to map residuesiÿÿÿÿ(   R   (   R4   (   R5   R
   i   R   s   Chain_%dt   sequenceRN   R9   t   unknown(   t   get_muscle_alignmentt   fasta_sequencess   
s   Alignment:
%ss   Chain assignment:R%   R   R6   (   R   R   R   R4   RE   R5   RF   RG   R   RH   RI   R   Rh   t   one_letter_sequenceR   R    t   unknown_one_letterR   t   strt	   mmtbx.msaRj   RC   t   print_chain_infosRf   (   R%   R&   R   t	   sequencesR   R4   R5   R9   RT   R   RQ   Rj   R6   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   map_by_muscleð   s0    	
	c         C   s|  d d l  m } d d l  m } |  s, t ‚ t t | j j | j j ƒ ƒ } g  } d } | j	 ƒ  xÃ |  D]» } | j
 d d | ƒ | j j ƒ  }	 | j d | d |	 d	 | j j d
 | d | ƒ \ }
 } |
 d k  rå t d | ‚ n  | j
 d d |
 ƒ t d |	 d | d | d | ƒ | j | ƒ qj W| j ƒ  t g  | d D]" } t | ƒ t | d ƒ k ^ qAƒ srt ‚ t | Œ  S(   Niÿÿÿÿ(   R   (   R4   i   R   s   Mapping %s...R6   R7   R8   R9   R:   i    s   No matching alignment for %ss!   Matching sequence found: index %dR>   R,   R   i   (   R   R   R4   R@   RF   RG   R   RH   RI   R   R   R   R    RJ   R8   RB   RL   R   R   RA   R   (   R%   R6   R   R   R4   R9   R,   R:   R   RN   R   RO   R?   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRf     s:    
	
?c         C   s{   t  g  | D] } | r
 | ^ q
 ƒ } g  |  D] } | | k r, | ^ q, } | rw | j d d t | ƒ d | f ƒ n  d  S(   NR   s,   %s residues in short (%s) segments discardeds   <%s residues(   t   setR   R   (   R>   R,   R   R:   t   rt   substrahendR)   t   unaccounted(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRL   E  s    %%		R+   R&   t   multiple_alignmentt   muscleR_   c         C   sj   | j  d t j ƒ  ƒ x7 t |  d d ƒD]# \ } } | j  d | | f ƒ q) W| j  d t j ƒ  ƒ d  S(   NR   R
   i   s   %d - %s(   R   R   t   blankR   (   R%   R   R   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRp   \  s    c         C   sV  d d l  m } t |  ƒ } d | k s. t ‚ | j d g | d ƒ } | j d g | d ƒ } xÂ | D]º } t | ƒ | k s‡ t ‚ x™ t | ƒ D]‹ \ } }	 x| t | ƒ D]n \ }
 } |	 r­ | r­ | | | |
 c d 7<|	 j ƒ  d | j ƒ  d k r| | | |
 c d 7<qq­ q­ Wq” Wqi Wx‰ t | ƒ D]{ \ } } | d k r4t | | ƒ } | | | } | j d d |  | |  | f ƒ | | d k s¢t ‚ d | | <q4q4W| j ƒ  | j ƒ  } | j	 d d ƒ t
 d	 |  d
 | ƒ g  t | ƒ D] } | | | | | | !^ qù} | j	 d t j d d g g  t | ƒ D] } d | d ^ qCd d g d g | d g  t | d d ƒD] \ } } | g t | ƒ ^ q…ƒ ƒ | j	 d t j ƒ  ƒ g  | D]! } | j | ƒ d | d ^ qË} | j	 d d ƒ | j	 d t j ƒ  ƒ x7 t |  | ƒ D]& \ } } | j	 d d | | f ƒ q(W| S(   Niÿÿÿÿ(   t   flexi   i    i   R   s   No overlap between %s and %ss   Pairwise sequence identities:R%   R   t   captionss       s   %4dt   formatss   %ds   %4.2ft   linesR
   g      ð?s   Averaged identities:s	   %s: %5.2f(   t   scitbx.array_familyRz   R   R@   t   intR   t   unique_resnamesRe   t	   as_doubleR   Rp   t   rangeR   t   format_tablet   listR   Ry   t   sumRG   (   R%   R,   R   Rz   R(   t   overlapst   matchest   post   i_leftt   rg_leftt   i_rightt   rg_rightR   t   dt   leftt   rightt
   identitiest   i_rowt   reformattedRT   t   slt   averagedR   t   aver(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt0   calculate_and_print_sequence_identity_statisticsf  sP     *	/		.<.c            s†   g  |  j  d ƒ D] } | j ƒ  j ƒ  ^ q ‰  d ˆ  k rV | j d d ƒ d „  } n, | j d d d j ˆ  ƒ ƒ ‡  f d †  } | S(	   Nt   ,RA   R   s   All atoms will be selectedc         S   s   t  S(   N(   t   True(   t   atom(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRU   ®  s    s(   The following atoms will be selected: %ss   , c            s   |  j  j ƒ  ˆ  k S(   N(   R   t   strip(   R™   (   t   tokens(    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRU   ´  s    (   t   splitRš   t   upperR   RC   (   t	   selectionR   RM   t   selector(    (   R›   s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   get_atom_selector¨  s    .	c         C   s  |  s t  ‚ t |  d ƒ } t g  |  d D] } t | ƒ | k ^ q* ƒ sQ t  ‚ g  } x!t |  ƒ D]\ } } | j d d | ƒ i  } xÀ t | ƒ D]² \ }	 }
 |
 s¯ q— n  t ƒ  } xŽ g  |
 j ƒ  D] } | d | ƒ rÈ | ^ qÈ D]^ } | j | k r%| j d d |
 j ƒ  | j f ƒ qç n  | | j	 | j d  g | ƒ |	 <qç Wq— W| j g  t | ƒ D] } | | ^ q`ƒ qd W| S(   Ni    i   R   s   Mapping position %s...R™   s   Resid %s: multiple atoms %s(   R@   R   RA   R   t   debugRs   t   atomsR   R+   R!   R   t   extendR$   (   R,   RŸ   R   R(   R?   t   atom_mappingt   positiont   equivalentst   atoms_namedR   R)   t   knownt   at   n(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   to_atom_mapping¹  s&    5	5	(.c         C   sn  t  | ƒ } t  |  ƒ } d | k  s* t ‚ d g | } d g | } x¦ | D]ž } t  | ƒ | k si t ‚ | j d  ƒ } | | k  sŠ t ‚ | | d k }	 xL t | ƒ D]> \ }
 } | r§ | |
 c d 7<|	 rå | |
 c d 7<qå q§ q§ WqK Wg  t | | ƒ D] \ } } | | | ^ qý } xJ t |  | | | ƒ D]3 \ } } } } | j d | | | d | f ƒ q3W| S(   Ni    i   s)   %s: %s sites, %s singles (%.2f%% overlap)id   (   R   R@   R(   R   R   RG   R   (   R%   R,   R   t   lengthR(   t   sitest   singlesRˆ   t   missingt	   is_singleR   t   sitet   singleR†   R   t   overlap(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt&   calculate_and_print_overlap_statisticsÙ  s0    0(c         C   s   d d l  m } | j ƒ  S(   Niÿÿÿÿ(   t   multiple_superposition(   R   Rµ   t   UnitWeightScheme(   t   paramsRµ   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   setup_unit_weighting_schemeÿ  s    c         C   s&   d d l  m } | j d |  j j ƒ S(   Niÿÿÿÿ(   Rµ   t   critical_value_square(   R   Rµ   t   RobustResistantWeightSchemet   robust_resistantt   critical(   R·   Rµ   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt'   setup_robust_resistant_weighting_scheme  s    	t   unitR»   c         C   sG   | j  d d ƒ g  } x* |  D]" } d  | k r | j | ƒ q q W| S(   NR   s6   Accepting positions that contain atoms for every chain(   R   R   R   (   R,   R   t	   positionst   group(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   intersect_selection  s    c         C   sj   | j  d d t ƒ g  } xI |  D]A } t t g  | D] } | r4 | ^ q4 ƒ k r! | j | ƒ q! q! W| S(   NR   s2   Accepting positions that contain at least %s atoms(   R   t   MIN_MODEL_COUNTR   R   (   R,   R   R¿   RÀ   R©   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   overlap_selection  s    	+c         C   s~   | j  d d ƒ d d l m } d d l m } | j d g  t |  Œ  D]+ } | j g  | D] } | j ^ qY ƒ ^ qF d | ƒ S(   NR   s    Setting up Diamond superpositioniÿÿÿÿ(   Rz   (   Rµ   t	   site_setst   weights(	   R   R~   Rz   R   Rµ   t   DiamondAlgorithmRG   t   vec3_doublet   xyz(   R­   RÅ   R   Rz   Rµ   Ra   R©   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   diamond_superposition-  s    	>c         C   sË   | j  d d ƒ d d l m } d d l m } | j d g  t |  Œ  D]7 } | j g  | D] } | rn | j n d
 ^ qY ƒ ^ qF d g  t |  Œ  D]. } | j	 g  | D] } t	 | ƒ ^ q£ ƒ ^ q� d	 | ƒ S(   NR   s&   Setting up Wang-Snoeyink superpositioniÿÿÿÿ(   Rz   (   Rµ   RÄ   i    t
   selectionsRÅ   (   i    i    i    (
   R   R~   Rz   R   Rµ   t   WangSnoeyinkAlgorithmRG   RÇ   RÈ   t   bool(   R­   RÅ   R   Rz   Rµ   Ra   R©   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   wang_snoeyink_superposition<  s    	GAt   gaplesst   gappedc         C   sÕ  d d  l  } d d l m }	 d d l m }
 |  j } x™t rÐ| j d d ƒ y" |
 j d |  d | ƒ \ } } WnW |
 j	 k
 rÉ } | j
 d d | j d	 ƒ | j
 d d
 ƒ | j d d !\ } } n X| j d d | | f ƒ |  j ƒ  } d } x„ t r|| j d | ƒ } y |  j d | ƒ WnP t k
 rw| j
 d d ƒ | | k  r]t d ‚ n  | | 9} | | } qù n XPqù W| j |	 j | | ƒ ƒ } | j d d | ƒ | | k r½Pn  | } |  j ƒ  q8 Wd  S(   Niÿÿÿÿ(   Rz   (   Rµ   R   s   Superposing...t   superpositiont   convergences   Superposition: %si    s   Continuing...i   i   s!   Residual: %s, %d iteration cyclesg      ð?t   squaresRÅ   s-   Excessive weight shift, damping weight changes!   Weight damping recovery exhausteds   Weight change: %s(   t   mathR~   Rz   R   Rµ   t
   site_countR˜   R   t   iteratet   NoConvergenceExceptionRe   t   argst'   distance_squares_from_average_structuret   for_difference_squarest   prepare_new_weightsRB   t   sqrtt   mean_sqt   set_new_weights(   RÐ   t   superposition_convergencet	   weightingRÅ   t   weight_convergencet   incremental_damping_factort   max_damping_factorR   RÓ   Rz   Rµ   R(   t   roundst   residualR`   t   diff_sqt   total_damping_factort   new_weightst   displacement(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt    iterative_weighted_superpositionU  sH    					

c         C   s—   |  j  ƒ  } |  j ƒ  } | j d d ƒ t d | d | ƒ | j d t j d d d d g d	 d
 d d g d t t t | ƒ ƒ | | ƒ ƒ ƒ | | f S(   NR   s   Rmsds per chain:R%   R   R{   t   Indexs   Weighted rmsds   Unweighted rmsdR|   s   %ds   %.3fR}   (	   t   weighted_rmsdst   unweighted_rmsdsR   Rp   R   Rƒ   RG   R‚   R   (   RÐ   R%   R   t   wrmsdst   unwrmsds(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   calculate_rmsds–  s    		"c            sy  | j  } g  t | ƒ D] } d g | ^ q ‰  xh t | ƒ D]Z } xQ t | d | ƒ D]< } | j d | d | ƒ ˆ  | | <ˆ  | | ˆ  | | <qV Wq< W| j d d ƒ t d |  d | ƒ | j d t j d	 d
 g g  t | ƒ D] } d | d ^ qâ d d g d g | d g  t ˆ  d d ƒD] \ } } | g | ^ q$ƒ ƒ | j d t j	 d ƒ ƒ d d l
 m }	 |	 j d t | ƒ d ‡  f d †  ƒ }
 |
 j | ƒ } | j d d t | ƒ ƒ t d |  d | ƒ d  g | } x’ t | d d ƒD]~ \ } } | j d | d j g  t | ƒ D] } d | d ^ qƒ f ƒ x. | D]& } | | d  k sct ‚ | | | <qGWqóW| S(   Ng        i   RŽ   R�   R   s   Pairwise rms valuesR%   R   R{   s       s   %4dR|   s   %ds   %4.2fR}   R
   s   Hierarchical clusteringiÿÿÿÿ(   t   clusterR   t   distance_functionc            s   ˆ  |  | S(   N(    (   t   xt   y(   t	   distances(    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRU   Å  s    s     %s clusters have been founds       Cluster %s: %ss   , (   t	   set_countR‚   t   rmsd_betweenR   Rp   R   Rƒ   R   R   R   t   libtbxRð   t   HierarchicalClusteringt   getlevelR   R   RC   R$   R@   (   R%   RÐ   R¼   R   R(   RT   t   lRt   t   lineRð   t   clt   levelst   resultsR   t   clustt   s(    (   Rô   s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   cluster_analysis©  s>    	& 		.6	5c         C   sj  t  | ƒ t  | ƒ k s t ‚ g  |  D] } t ƒ  ^ q% } | j d d ƒ x¼ t t | | ƒ ƒ D]¥ \ } \ } }	 | j d | |	 f ƒ |	 | k r` | j d ƒ t  | ƒ t  | ƒ k sÀ t ‚ xB t | | ƒ D]. \ }
 } |
 rÐ | j |
 j ƒ  j ƒ  ƒ qÐ qÐ Wq` q` Wd d l m	 } g  t |  | ƒ D]= \ } } | j
 g  | j j ƒ  D] } | | k ^ qKƒ ^ q)S(   NR   s.   Checking deviations of superposed positions...s   Site %d: %.3fs   Accepting this positioniÿÿÿÿ(   Rz   (   R   R@   Rs   R¡   R   RG   t   addt   parentR~   Rz   RÌ   R   R    (   R%   R­   t
   deviationst	   thresholdR   RT   t   keepsR   t   equivsR�   R©   t   kRz   R   t   keepR)   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   calculate_trimming_masksÜ  s    ('c   	      C   sü   t  |  ƒ t  | ƒ k s t ‚ d d l m } xÇ t |  | ƒ D]¶ \ } } | j } t  | j ƒ  ƒ t  | ƒ k sw t ‚ | j d d | | j | j	 ƒ  ƒ f ƒ xP t | j ƒ  | ƒ D]9 \ } } | s· | j
 d | j ƒ  ƒ | j | ƒ q· q· Wq> Wd  S(   Niÿÿÿÿ(   Rz   R   s   %s: removing %s residuess   Removing %s(   R   R@   R~   Rz   RG   t   ensembler_trimming_maskR    R   R…   t   as_intR¡   R+   t   remove_residue_group(	   R%   t   chainsR   Rz   R   R   t   maskR)   t	   to_remain(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   trim_chainsö  s    	$	"c         C   s   |  j  S(   N(   t   ensembler_input_index(   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRU     s    t   inputc         C   s   |  j  S(   N(   t   ensembler_identity(   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRU     s    R   c         C   s   |  j  S(   N(   t   ensembler_overlap(   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRU     s    R³   c         C   s   |  j  S(   N(   t   ensembler_wrmsd(   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRU     s    t   wrmsdc         C   s   |  j  S(   N(   t   ensembler_unwrmsd(   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyRU     s    t   unwrmsdc         C   s  | j  d t j d d ƒ ƒ | j  d t j ƒ  ƒ d d  l } d d  l } | j j j ƒ  } g  } g  } | j	 ƒ  xt
 t | | ƒ d d ƒD]î \ }	 \ }
 } | j j j ƒ  } t |	 ƒ | _ | j | ƒ d | _ | j | ƒ | j  d d |	 |
 f ƒ |
 j d  k	 r.t j d	 | j d
 |
 j ƒ } n d  } | j | ƒ | j d |	 | j j |
 j j ƒ |
 j j |
 j j f ƒ qŽ W| j ƒ  d |  } | j  d t j ƒ  ƒ | j  d d | ƒ t d | d | d | d | d | ƒ | j  d t j d d ƒ ƒ | g S(   NR   R	   s   Writing merged output fileiÿÿÿÿR
   i   t   As   Model %s is %st   midR   s-   REMARK MODEL %s: PDB %s, MODEL '%s', CHAIN %ss   %s_merged.pdbs   File name: %st	   file_namet   roott   seqidst   identifiersR   s   Output file written(   R   R   R   Ry   t	   iotbx.pdbt   os.patht   pdbt	   hierarchyR  R   R   RG   t   modelRn   RS   t   append_modelt   append_chainR   R   R   t    get_phaser_model_identity_remarkR   t   patht   basenameR   R   R   t   write_output_filet   section_close(   R  R%   R  R   RE   t   ost   pdb_roott   sequence_identity_remarkst   identifier_remarksR   R   R   R$  t   remarkt   output_file_name(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   write_merged_output  sN    
.				

c         C   s¾  | j  d t j d d ƒ ƒ i  } xN t | | ƒ D]= \ } } | j | j j | j j f g  ƒ j	 | | f ƒ q2 Wg  } d d  l
 } d d  l }	 x t | ƒ D]ò\ }
 } d |  |	 j j |	 j j |
 ƒ d ƒ | rß d | n d f } i  } xi | |
 | f D]W \ } } | j | j j g  ƒ } | j	 | | f ƒ | j  d	 | | j j | f ƒ q W| j j j ƒ  } g  } g  } xâ t t | ƒ ƒ D]Î \ } } | j j j ƒ  } | | _ | j | ƒ x— | | D]‹ \ } } | j | ƒ | j d  k	 rt j d
 | d | j ƒ } n d  } | j	 | ƒ | j	 d | |	 j j | j j ƒ | | j f ƒ qËWqŒWt d | d | d | d | d | ƒ | j	 | ƒ qž W| j  d t j d d t | ƒ ƒ ƒ | S(   NR   R	   s   Writing separate output filesiÿÿÿÿs   %s_%s%s.pdbi    s   _%sR1   s   %s (model '%s') contains %sR  R   s-   REMARK MODEL %s: PDB %s, MODEL '%s', CHAIN %sR  R  R  R  R   s   %d output files written(   R   R   R   RG   R!   R"  R   R   RS   R   R   R!  R$   R(  R)  t   splitextR$  R#  R  R   R%  R&  R   R   R   R'  R*  R+  R   (   R  R%   R  R   t   output_data_forR   R   t   output_filesRE   R,  t   infilet   cidR1  t
   model_withR   R-  R.  R/  R   R  R$  R0  (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   write_separate_outputQ  sp    $							c         C   sT  | j  d t j d d ƒ ƒ | j  d t j ƒ  ƒ g  } d d  l } d d  l } | j ƒ  xÃt t | | ƒ d d ƒD]¦\ } \ } }	 | j	 j
 j ƒ  }
 | j	 j
 j ƒ  } |
 j | ƒ d |	 _ | j |	 ƒ | j  d d | | f ƒ | j d  k	 rt j d	 | j d
 | j ƒ } n d  } d | | j j | j	 j ƒ | j j | j j f } d |  | j j | j j | j	 j ƒ d ƒ d | j j r£d | j j j ƒ  n d | j j rÂd | j j n d f f } t d | d |
 d | g d | g d | ƒ | j  d d | ƒ | j | ƒ qv W| j ƒ  | j  d t j d d t | ƒ ƒ ƒ | S(   NR   R	   s5   Writing separate output file for each chain and modeliÿÿÿÿR
   i   R  s   Model %s is %sR  R   s-   REMARK MODEL %s: PDB %s, MODEL '%s', CHAIN %ss   %s_%s%s.pdbi    s   %s%ss   _model%sR1   s   _chain%sR  R  R  R  R   s   File name: %ss   %d output files written(   R   R   R   Ry   R   R!  R   R   RG   R"  R#  R  R$  R%  RS   R&  R   R   R   R'  R(  R)  R   R   R3  Rš   R*  R   R   R+  R   (   R  R%   R  R   t
   file_namesRE   R,  R   R   R   R-  R$  t	   seqremarkt   identremarkR1  (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt)   write_chain_and_model_sorted_output_files­  sT    	
.				%%*		
	c         C   s¤   t  |  d ƒ �� } d  | k r; | j d d j | ƒ ƒ n. | j d  ƒ t | ƒ k ri | j d d ƒ n  | j d d j | ƒ ƒ | j d | j ƒ  ƒ Wd  QXd  S(   Nt   ws   %s
s   
R   s1   Inconsistent sequence identity remarks, discarded(   t   openR   t   writeRC   R(   R   Re   t   as_pdb_string(   R  R  R  R  R   t   fout(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyR*  ï  s    	
t   mergedt   separatesá  
    input
        .help = "Input files"
    {
        model = None
            .help = "Input model file"
            .type = path
            .optional = True
            .multiple = True
            
        alignment = None
            .help = "Input alignment file"
            .type = path
            .optional = True
            .multiple = True
    }
    
    output
        .help = "Output file(s)"
    {
        location = ""
            .type = path
            .short_caption = Output directory
            .style = hidden

        gui_output_dir = None
            .type = path
            .short_caption = Output directory
            .help = Sets base output directory for Phenix GUI - not used when               run from the command line.
            .style = output_dir bold

        root = ensemble
            .help = "Output file root"
            .type = str
            .optional = False
            .short_caption = Output file root
            
        style = %(style)s
            .help = "Output options for ensemble"
            .type = choice
            .optional = False
            .short_caption = Output ensemble as
            
        sort = %(sort)s
            .help = "Sort ensemble components"
            .type = choice
            .optional = False
            .short_caption = Sort models by
        include scope libtbx.phil.interface.tracking_params
    }
    
    configuration
        .help = "General parameters for ensemble generation"
        .short_caption = Ensemble generation settings
        .style = menu_item
    {   
        superposition 
            .help = "Superposition setup"
        {
            method = %(superposition)s
                .help = "Superposition algorithm"
                .type = choice
                .optional = False
                .short_caption = Superposition algorithm
                
            convergence = 1.0E-4
                .help = "Convergence criterion for superposition"
                .type = float
                .optional = False
                .short_caption = Superposition RMS covergence threshold
        }
        
        mapping = %(mapping)s
            .help = "Residue correspondence mapping"
            .type = choice
            .optional = False
            .short_caption = Residue mapping
            
        atoms = CA
            .help = "Include atom in superpositions"
            .type = str
            .optional = False
            .short_caption = Atoms to include in superposition
            
        clustering = 0.5
            .help = "Cutoff distance for cluster analysis"
            .type = float
            .optional = False
            .short_caption = Cutoff distance for cluster analysis
            
        weighting
            .help = "Parameters for weighting scheme"
            .style = box
        {
            scheme = %(weighting)s
                .help = "Weighting scheme"
                .type = choice
                .optional = False
                .short_caption = Weighting scheme
                
            convergence = 1.0E-3
                .help = "Convergence criterion for weight iteration"
                .type = float
                .optional = False
                .short_caption = Convergence criterion for weight iteration
                
            incremental_damping_factor = 1.5
                .help = "Damping factor in recovery cycle"
                .type = float
                .optional = False
                
            max_damping_factor = 3.34
                .help = "Quit recovery if cumulative damping factor is above"
                .type = float
                .optional = False
                
            robust_resistant
                .help = "Setting for robust-resistance scheme"
            {                    
                critical = 9
                    .help = "tolerance"
                    .type = float
                    .optional = False
                    .short_caption = Robust resistant rms weighting term
            }
        }
        
        trim = False
            .help = "Trim differing loops"
            .type = bool
            .optional = False
             .short_caption = Trim residues deviating more than threshold
        
        trimming
            .help = "Trimming parameters"
        {
            threshold = 3.0
                .help = "Max position RMSD for inclusion"
                .type = float
                .optional = False
                .short_caption = Trimming threshold
        }
    }
    t   possiblet   defaultR,   RÐ   Rß   t   sortt   stylet   process_includesc   "      C   sí  t  | j j } t | j j j \ } } t | j j j } t	 | j
 j } | j d t
 j d d ƒ ƒ t d |  d | ƒ }	 x) t |	 d d ƒD] \ }
 } |
 | _ q� Wt |	 ƒ t k  rË t d t ‚ n  | j d t
 j d d	 ƒ ƒ | d
 |	 d | d | ƒ } | j d d t | ƒ ƒ | j d t
 j d d ƒ ƒ t d
 |	 d | d | ƒ } t | ƒ t |	 ƒ k sqt ‚ x& t |	 | ƒ D] \ } } | | _ q�W| j d t
 j d d ƒ ƒ t d | j j d | ƒ } t d | d | d | ƒ } | j d d t | ƒ ƒ | j d t
 j d d ƒ ƒ t d
 |	 d | d | ƒ } t | ƒ t |	 ƒ k s[t ‚ x& t |	 | ƒ D] \ } } | | _ qkW| j d t
 j d d ƒ ƒ | d | d | ƒ } t | ƒ t k  r×t d t ‚ n  | j d d t | ƒ ƒ d d l m  } | j! d g t | ƒ ƒ } | d | d | d | ƒ } | j d d | j j j ƒ | d | j j ƒ } | j d d ƒ t" d | d | j j j# d  | d | d! | j j j# d" | j j j$ d# | j j j% d | ƒ | j d d$ ƒ | j d d% | j& ƒ  ƒ | j d t
 j d d& ƒ ƒ | j d t
 j d d' ƒ ƒ | j' ƒ  \ } } t |	 ƒ t | ƒ k sgt ‚ t |	 ƒ t | ƒ k s…t ‚ xƒ t |	 | | ƒ D]o \ } } } | j d d( | ƒ | j d d) d* d+ | j( ƒ | j d d, dD | j( ƒ | | _) | | _* q˜W| j d t
 j d d/ ƒ ƒ t+ d | d
 |	 d | ƒ \ } } t | ƒ t |	 ƒ k sft ‚ t | ƒ t |	 ƒ k s„t ‚ x5 t |	 | | ƒ D]! \ } } } | | _, | | _- q—W| j d t
 j d d0 ƒ ƒ t. d | d
 |	 d1 | j j/ d | ƒ } t | ƒ t |	 ƒ k st ‚ x& t |	 | ƒ D] \ } } | | _0 q-W| j j1 rþ| j d t
 j d d2 ƒ ƒ | j d d3 ƒ t2 d
 |	 d | d4 | j3 ƒ  d5 | j j4 j5 d | ƒ } t |	 ƒ t | ƒ k sÒt ‚ x) t |	 | ƒ D] \ } }  |  | _6 qâWn  | j d t
 j d d6 ƒ ƒ | j d d7 | j
 j ƒ |	 j d8 | ƒ t7 d
 |	 d | ƒ | j d t8 j9 d9 d: d; d< d= d> d? g d@ dA dA dB dB dB dB g dC g  t |	 d d ƒD]3 \ }! } |! | j | j | j | j, | j- g ^ q¬ƒ ƒ |	 S(E   NR   R	   s   Chain selectionR   R   R
   i   s%   Less than %s chains for superpositions   Residue mappingR%   R&   s%   Residue mapping: %s aligned positionss   Sequence identity statistics:R,   s   Atom mappingRž   RŸ   s"   Atom mapping: %s aligned positionss   Overlap statistics:t   Superpositions$   Less than %s sites for superpositions*   Site selection: %s sites for superpositioniÿÿÿÿ(   Rz   R­   RÅ   s   Weighting scheme: %sR·   s)   Iterating weighting with superposition...RÐ   RÞ   Rß   Rà   Rá   Râ   s   Superposition completes   Rmsd between all chains: %.3fs   Superposition resultst   Transformationss   %s:s     Rotation:
    s   %7.3fi	   s     Translation: s   %9.4fi   t   Rmsdss   Cluster analysisR¼   s   Chain trimmings   Calculating data...R  R  t   Summarys   Sort order: %st   keyR{   Rê   s   Input indext   Identityt   Overlaps   Weighted rmsdss   Unweighted rmsdsR|   s   %ds   %.3fR}   s   %9.4f%9.4f%9.4f(:   t   MAPPING_PROCEDURE_FORt   configurationR,   t   SUPERPOSITION_PROCEDURES_FORRÐ   t   methodt   WEIGHTING_SCHEME_SETUP_FORRß   t   schemet
   SORTING_ONR   RG  R   t   subtitleR   R   R  R   RÂ   RB   t
   underlinedR–   R@   RG   R  R    R¢   R«   R´   R  t   MIN_SITE_COUNTR~   Rz   t   doubleRé   RÑ   Rá   Râ   t   rmsdt   transformationst   elemst   ensembler_rotationt   ensembler_translationRï   R  R  R  t
   clusteringt   ensembler_clustert   trimR
  RØ   t   trimmingR  R  Rp   R   Rƒ   ("   R   R&   R·   R   t   matching_methodt   site_selection_methodt   setup_superposition_methodt   setup_weighting_methodt   sorting_methodR%   R   R   R,   R�   t   valueRŸ   R†   R­   Rz   RÅ   RÐ   Rß   t	   rotationst   translationst   rott   traRí   Rî   R  R  t   clusterst   trimming_masksR  RT   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   process°  sö    							"	"						Mc      	   C   s¿  t  j d | d | ƒ } | j d t  j d d t t f ƒ ƒ t j d t ƒ } d d l	 m
 } | j d	 t j d
 | j ƒ  d d ƒ ƒ | j d	 t j d
 d d g d d ƒ ƒ x |  D] } | j d | ƒ q· Wd d l m } y | j ƒ  } Wn t k
 r}	 | |	 ‚ n X| j d t  j d d ƒ ƒ | j d | j ƒ  ƒ y | j ƒ  }
 Wn t k
 rp}	 | |	 ‚ n X|
 j j s‰| d ‚ n  | j d t  j d d ƒ ƒ | j ƒ  | j d d j d „  t |
 j j d d ƒDƒ ƒ ƒ | j ƒ  t j d |
 j j d t j ƒ } | j d t  j d d t | ƒ ƒ ƒ |
 j j  rê| j d t  j d d ƒ ƒ | j ƒ  | j d d j d „  t |
 j j  ƒ Dƒ ƒ ƒ | j ƒ  t j d |
 j j  d t j! ƒ } | j d t  j d d t | ƒ ƒ ƒ n g  } y% t d | d | d  |
 d! | ƒ } Wn t k
 r3}	 | |	 ‚ n X| j d t  j" d d" ƒ ƒ g  | D] } | j# j$ ƒ  ^ qW} xS t% | | ƒ D]B \ } } | j& j' | j( ƒ  j) ƒ  | j* } | j( ƒ  j+ | ƒ q‚W|
 j, j- r2t. d# „  | Dƒ ƒ sðt/ ‚ | j d d$ ƒ | j d t  j0 ƒ  ƒ t1 d% | d& | d! | ƒ n  d d  l2 } yJ t3 |
 j  j4 d' | j5 j |
 j  j6 |
 j  j7 ƒ d% | d& | d! | ƒ } Wn t8 k
 r¦}	 | |	 ‚ n X| j d d( t ƒ | S()   Nt   streamt   levelR   R	   s   %s version %st   master_philiÿÿÿÿ(   R5   t   handlert
   extensionst   templates   input.alignment=%ss   .pdbs   .ents   input.model=%st   accumulator(   t   Sorrys   All configuration options:s   No input pdb filess   Reading pdb files:s   
c         s   s%   |  ] \ } } d  | | f Vq d S(   s   %d. %sN(    (   R/   RT   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pys	   <genexpr>©  s    R
   i   R:  t   object_types   %d files reads   Reading alignment files:c         s   s%   |  ] \ } } d  | | f Vq d S(   s   %d. %sN(    (   R/   RT   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pys	   <genexpr>º  s    R   R&   R·   R   s   Prepare outputc         s   s   |  ] } t  | d  ƒ Vq d S(   R  N(   t   hasattr(   R/   R   (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pys	   <genexpr>ß  s    s   Chain trimmingR%   R  R  s   %s finished(9   R   t   SingleStreamR   t   bannert   PROGRAMt   VERSIONR   t   PhilAccumulatort   PHIL_MASTERRE   R5   t   register_file_handlert   ExtensionFileHandlert   known_alignment_formatsRq  t   libtbx.utilsRy  t   mergeRB   RY  t   as_strt   extractR  R$  R   RC   R   R   t   read_in_filest	   PDBObjectR+  R   R6   t   AlignmentObjectRX  R   t   detached_copyRG   R_  R^  R¢   t   extract_xyzR`  t   set_xyzRR  Rc  RA   R@   Ry   R  R!  t   WRITE_OUTPUT_ASRH  R(  t   locationR  t   IOError(   R×   t   outt	   verbosityR   Rx  R5   t   argumentRy  t   merged_philR`   R·   R   R&   R%   R   R  R   R­   R,  R:  (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   runs  s¤    			
		

	&
		
	 
		 "
!t   launcherc           B   s   e  Z d  „  Z RS(   c         C   s	  t  j |  j ƒ t  j |  j ƒ d d  l } d d l m } t j d t	 ƒ } y; t
 d g  |  j D] } | d | ƒ ^ qa d | j ƒ } Wn t k
 r¡ } ‚  nd X| d  k sÀ t | ƒ d k rÏ | d ƒ ‚ n6 t | t ƒ rg  | D] } t  j j | ƒ ^ qå S| Sd  S(	   Niÿÿÿÿ(   Ry  Rt  R×   R”  R’  i    s,   Empty result set; no output file(s) written.(   R,  t   makedirst
   output_dirt   chdirt   sysR…  Ry  R   t   PhilArgumentFactoryR�  R–  R×   t   stdoutt	   ExceptionR   R   t
   isinstanceR„   R(  t   abspath(   t   selfR›  Ry  t   factoryt   argR5  R`   t   fn(    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyR–  ù  s     %#(   t   __name__t
   __module__R–  (    (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyR—  ø  s   c         C   s¤   g  } t  |  t ƒ rR t j j |  ƒ rš t j j |  ƒ } | j | d f ƒ qš nH t  |  t ƒ rš x6 |  D]+ } t j j | ƒ } | j | d f ƒ qh Wn  | g  f S(   Ns   Multi-model PDB files   Individual model(   RŸ  Rn   R,  R(  t   isfileR   R   R„   (   t   resultt   filest   pdb_outR  (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt
   finish_job  s    (=   t
   __future__R    R   R   R   R   R÷   R   t   libtbx.philR!  R,  R~  R  RZ  RÂ   R   R-   RR   Rd   Rg   Rr   Rf   RL   RQ  Rp   R–   R    R«   R´   R¸   R½   RU  RÁ   RÃ   RÉ   RÍ   RS  Ré   Rï   R  R
  R  RW  R2  R9  R=  R*  R�  t   philt   parset   choice_stringR˜   R�  t   master_paramsRq  R|  t   INFOR–  t   target_with_save_resultR—  R«  (    (    (    s>   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/py2/phaser/ensembler.pyt   <module>   s¤   	!		Y	5		&	/	
	
	B		 	&		
					A		3		



	<	\	B	
	‘	
	
	
	
			Ã…