ó
Ñ%�Tc           @   s§  d  Z  d d l m Z d d l m Z m Z m Z m Z m Z m	 Z	 m
 Z
 m Z d d l m Z d d l m Z d d l m Z d d l m Z y d d l m Z Wn! e k
 rÇ d d	 l m Z n Xd d
 l m Z d d l m Z d d l m Z d d l m Z m Z d Z  d Z! d Z" e# d j$ d ƒ ƒ Z% e# d j$ d ƒ ƒ Z& e# d d d d g ƒ Z' d Z( d f  d „  ƒ  YZ) d „  Z* e* ƒ  Z+ d e, f d „  ƒ  YZ- d S(   s]   The pseudoMolecule class for storing atomic coordinate data and updating Coot as appropriate.iÿÿÿÿ(   t   deepcopy(   t   new_generic_object_numbert   set_display_generic_objectt   to_generic_object_add_linet   graphics_drawt   close_generic_objectt   close_moleculet&   get_molecule_bonds_colour_map_rotationt&   set_molecule_bonds_colour_map_rotation(   t   add_molecule_py(   t   clear_and_update_molecule_py(   t   residue_info_py(   t   svn_revision(   t   python_representation_kk(   t   python_representation(   t   Chain(   t
   Nucleotide(   t   dist(   t	   BOND_LISTt   BOND_DIST_CUTOFFt   oranges   RCrane-molecule-%ig      4@s'   C2' O2' C3' O3' C4' O4' C5' O5' OP1 OP2t    s,   N6 O6 N2 N7 N3 C5 C4 N1 C8 C6 O4 O2 N9 N4 C2t   Pt   OP1t   OP2t   OP3g      @t   PseudoMoleculec           B   sE  e  Z d  Z e dO dO dO dO d „ 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 d „  Z e d „ Z e d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z e d „ Z dO dO d „ Z  d „  Z! d „  Z" d „  Z# d „  Z$ d  „  Z% d! „  Z& d" „  Z' d# „  Z( d$ „  Z) dO dO d% „ Z* d& „  Z+ d' „  Z, d( „  Z- d) „  Z. d* „  Z/ d+ „  Z0 e1 d, „ Z2 e1 d- „ Z3 d. d/ „ Z4 d. d0 „ Z5 d1 „  Z6 d2 „  Z7 d3 „  Z8 d4 „  Z9 d5 „  Z: d6 „  Z; d7 „  Z< e d8 „ Z= d9 „  Z> i  Z? e@ eA d: jB d; ƒ eC d< ƒ ƒ ƒ e? d= <e@ eA d> jB d; ƒ eC d< ƒ ƒ ƒ e? d? <e@ eA d@ jB d; ƒ eC d< ƒ ƒ ƒ e? dA <e@ eA dB jB d; ƒ eC d< ƒ ƒ ƒ e? dC <e dD „ ZD dE „  ZE dF „  ZF dG „  Z dH „  ZG dI „  ZH dJ „  ZI dK „  ZJ dL „  ZK dM „  ZL dN „  ZM RS(P   sh   A class for storing atomic coordinate data and update a Coot molecule and drawing objects as appropriatec         C   sØ  | r( t  d ƒ |  _ t |  j d ƒ n  d g  g g g |  _ | |  _ d |  _ i  |  _ d |  _ d |  _	 d |  _
 d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ | d k	 rh| |  _ t | ƒ |  _ |  j ƒ  |  j ƒ  | d k	 r[| |  _ y4 g  |  j d D] } | d ^ qj | ƒ |  _ Wq[t k
 rWt d t | ƒ d ƒ ‚ q[Xn  |  j ƒ  nl | rÔ| |  j d d d <|  j ƒ  |  j d k r¾t |  j t t j ƒ  ƒ |  _ qÔt |  j |  j ƒ n  d S(   sø  Initialize a new pseudoMolecule object.
        
        OPTIONAL ARGUMENTS:
            batons             - Whether or not to create a generic display object for drawing batons between phosphates and bases.  Defaults to True
            initialResList     - A list of nucleotide coordinates to store in the pseudoMolecule object.  Defaults to None.
                                 Formatted as a list of dictionaries, where each dictionary contains atomName: [x, y, z]
            moleculeNumber     - If given, this Coot molecule will be updated/overwritten.  Otherwise a new Coot molecule will be created.
            createFromMolecule - create the PseudoMolecule object using the specified existing Coot molecule
                                 This differs from moleculeNumber in that moleculeNumber will overwrite an existing molecule.  CreateFromMolecule will
                                 use the coordinates of the existing molecule.
            chain              - the chain contains nucleotides to be accessed/modified via this object.
                                 Only relevant when createFromMolecule is defined.
                                 If not given, the first chain in the molecule will be used
        RETURNS:
            an initialized pseudoMolecule object
        EXCEPTIONS:
            raises PseudoMoleculeError if the specified chain doesn't exist
            or if molecule createFromMolecule contains anisotropic temperature records and we're using Coot older than rev 3631
        s   Accepted Batonsi   t   Ai    s   Chain s
    not foundN(   R   t   _PseudoMolecule__batonObjectR   t   _PseudoMolecule__moleculet   _PseudoMolecule__moleculeNumbert   Nonet    _PseudoMolecule__extraBondObjectt   _PseudoMolecule__resNumDictt'   _PseudoMolecule__extraBondStartingIndext%   _PseudoMolecule__extraBondEndingIndext!   _PseudoMolecule__savedCoordinatest   _PseudoMolecule__savedBfacst   chaint   _PseudoMolecule__chainIndext   resInsertionPointt   origResInsertionPointt#   _PseudoMolecule__savedMoleculeStateR   t   _PseudoMolecule__checkAnisot   _PseudoMolecule__fixTerAtomst   indext
   ValueErrort   PseudoMoleculeErrort   strt%   _PseudoMolecule__initializeResNumDictt   add_moleculet   MOLECULE_NAMEt   moleculeNameCountt   nextt   clear_and_update_molecule(   t   selft   batonst   initialResListt   moleculeNumbert   createFromMoleculeR&   t	   chainList(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   __init__6   sD    													

	4!
"c         C   sb  |  j  d |  j d } |  j d	 k r6 t | ƒ } n |  j d } |  j d 7_ d	 } t | ƒ d k rs d } n | | d d d } |  j d	 k r´ t | ƒ |  j t | ƒ <n
 |  j ƒ  | d d d d g d t d g | d d !g g g } | j	 | | ƒ | |  j  d |  j d <|  j
 d	 k rKt |  j  t t j ƒ  ƒ |  _
 n t |  j
 |  j  ƒ d	 S(
   s‹  Add a new phosphate atom to the pseudoMolecule object.
        
        ARGUMENTS:
            coords - the coordinates of the phosphate to add
        RETURNS:
            None
        EFFECTS:
            The phosphate will be added to the Coot molecule.
            If this is the first phosphate to be added, a new Coot molecule object will be
                created and displayed.
        i    i   t    t   Gs    P  g      ð?s    Pi   N(   R   R'   R(   R   t   lenR!   R0   R1   t   DEFAULT_B_FACTORt   insertR   R2   R3   R4   R5   R6   (   R7   t   coordst   resListR(   t
   nextResNumt   newRes(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   addPhosƒ   s$    	
4"c         C   sc   |  j  d |  j d |  j d j d d d g d t d g | d d !g ƒ t |  j |  j  ƒ d S(	   s0  Add a new 5' phosphate atom to the pseudoMolecule object.
        
        ARGUMENTS:
            coords - the coordinates of the phosphate to add
        RETURNS:
            None
        NOTE:
            This function should only be used during an extendChain, not when tracing a new molecule
        i    i   i   s    P  R>   g      ð?s    PN(   R   R'   R(   RB   RA   R6   R   (   R7   RC   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt	   addPhos5p¹   s    Lc         C   sÉ  |  j  d |  j d } |  j d k r6 t | ƒ } n |  j d 7_ |  j } | | | d d <d d g d t d g | d d d	 !g g } xd | D]\ } | d k r« q“ n  | j | j d
 ƒ d g d t d | d d !g | | d d	 !g ƒ q“ W| | d d	 j | ƒ d } t | ƒ d k r-d } n+ | | d d d } | d k rXd } n  | d | d d g d t d g | d d	 !g g g }	 | j	 | |	 ƒ | |  j  d |  j d <|  j d k rÙ| |  j
 t | ƒ <n
 |  j ƒ  |  j d k rt |  j  t t j ƒ  ƒ |  _ n t |  j |  j  ƒ |  j | d ƒ }
 | d } t |  j t d |
 d |
 d |
 d | d | d | d ƒ	 t |  j t d | d | d | d | d | d | d ƒ	 t ƒ  d S(   sh  Add a base and the 3' phosphate (i.e. the next phosphate) to the pseudoMolecule object
        
        ARGUMENTS:
            baseType    - the type of base (i.e. "A", "G", "C", or "U")
            baseCoords  - coordinates of the base in the format atomName: [x, y, z]
                          Note that the C1' coordinates MUST be included
            phosCoords  - the coordinates of the 3' phosphate
        RETURNS:
            None
        EFFECTS:
            The base and phosphate will be added to the Coot molecule and batons will be drawn connecting
            the phosphates and the C1' atom.
        i    i   i   s    C1'R>   g      ð?s    Cs   C1'i   i   s    %ss    P  s    Pi   N(   R   R'   R(   R   R@   RA   t   appendt   centert   extendRB   R!   R0   R1   R   R2   R3   R4   R5   R6   t   getPhosCoordsFromIndexR   R   t
   BATONCOLORR   (   R7   t   baseTypet
   baseCoordst
   phosCoordsRD   R(   t   baseAtomListt   curAtomRE   RF   t   prevPhosCoordst   c1coords(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   addBaseAndPhosÈ   s@    	, H	 	4
"
==c         C   sÇ  |  j  d |  j d } |  j d k r6 d } d } nB | |  j d d } | d k r` d } n  |  j d 7_ |  j } d d g d t d g | d d !g d	 d g d t d
 g | d d d !g g } xd | D]\ } | d k rå qÍ n  | j | j d ƒ d g d t d | d d !g | | d d !g ƒ qÍ W| d | | g }	 |  j d k rrx! | D] }
 |
 d c d 7<qUWn  | j | |	 ƒ | |  j  d |  j d <|  j d k r×| d d } t	 | ƒ d |  j
 t | ƒ <n
 |  j ƒ  |  j d k rt |  j  t t j ƒ  ƒ |  _ n t |  j |  j  ƒ |  j | d ƒ } | d } t |  j t d | d | d | d | d | d | d ƒ	 t |  j t d | d | d | d | d | d | d ƒ	 t ƒ  d S(   sG  Add a 5' base and phosphate to the pseudoMolecule object
        
        ARGUMENTS:
            baseType    - the type of base (i.e. "A", "G", "C", or "U")
            baseCoords  - coordinates of the base in the format atomName: [x, y, z]
                          Note that the C1' coordinates MUST be included
            phosCoords  - the coordinates of the phosphate
        RETURNS:
            None
        EFFECTS:
            The base and phosphate will be added to the Coot molecule and batons will be drawn connecting
            the phosphates and the C1' atom.
        i    i   iÿÿÿÿs    P  R>   g      ð?s    Pi   s    C1's    Cs   C1'i   s    %si   i   N(   R   R'   R(   R   R)   RA   RI   RJ   RB   R@   R!   R0   R1   R   R2   R3   R4   R5   R6   RL   R   R   RM   R   (   R7   RN   RO   RP   RD   R(   t	   newResNumt   atomListRR   RF   t   curRest   new5pResNumRS   RT   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   addBaseAndPhos5p  sB    			", H 
"
==c         C   s„   t  | t ƒ r$ | d k  r$ | } n |  j | ƒ } xJ |  j d |  j d | d D]( } | d d j ƒ  d k rT | d SqT Wd S(   s/  Get the coordinates of a specified phosphate.
        
        ARGUMENTS:
            resNum - the residue number
        RETURNS:
            the coordinates of the phoshate from residue resNum 
        NOTE:
            Negative integers can be used to refer to phosphates at the end of the chain (i.e. resNum = -1 will return
            the coordinates of the last phosphate).  If you want to refer to a nucleotide with an actual negative residue
            number (very uncommon, but they do exist), then pass the number as a string (i.e. "-1")
        i    i   i   R   i   N(   t
   isinstancet   intt   resIndexR   R'   t   stripR   (   R7   t   resNumR]   RR   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   getPhosCoordsk  s    	'c         C   sQ   xJ |  j  d |  j d t d D]( } | d d j ƒ  d k r! | d Sq! Wd S(   sÎ   Get the coordinates of a specified phosphate.
        
        ARGUMENTS:
            resIndex - the residue index
        RETURNS:
            the coordinates of the phoshate from residue resIndex
        i    i   i   R   i   N(   R   R'   R]   R^   R   (   R7   R_   RR   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyRL   …  s    	'c         C   sQ   xJ |  j  d |  j d | d D]( } | d d j ƒ  d k r! | d Sq! Wd S(   sˆ  Get the coordinates of a specified C1' atom (NOT the entire sugar).
        
        ARGUMENTS:
            resIndex - the residue index
        RETURNS:
            the coordinates of the C1' from the specified residue
        NOTE:
            Negative numbers can be used to refer to C1' atoms at the end of the chain (i.e. resNum = -1 will return the coordinates of the last C1')
        i    i   i   s   C1'i   N(   R   R'   R^   (   R7   R]   RR   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   getSugarCoordsFromIndex–  s    'c         C   sQ   xJ |  j  d |  j d | d D]( } | d d j ƒ  | k r! | d Sq! Wd S(   sû   Get the coordinates of a specified atom
        
        ARGUMENTS:
            atomName - the name of the atom to get coordinates for
            resIndex - the residue index
        RETURNS:
            the coordinates of the specified atom
        i    i   i   i   N(   R   R'   R^   R   (   R7   t   atomNameR]   RR   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   getAtomCoordsFromIndex¬  s    
'c         C   s   t  |  j ƒ d S(   sò   close the Coot generic object for the batons connecting the phosphate and C1' atoms.
        
        ARGUMENTS:
            None
        RETURNS:
            None
        EFFECTS:
            The batons generic object will be closed
        N(   R   R   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   closeBatonObject½  s    c         C   s   t  |  j d |  j d ƒ S(   s«   Get the number of nucleotides in the molecule.
        
        ARGUMENTS:
            None
        RETURNS:
            the number of nucleotides in the molecule
        i    i   (   R@   R   R'   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt	   getNumNtsÊ  s    	c         C   s-  |  j  ƒ  d k r d
 S|  j d	 k rF t |  j d |  j d ƒ } n	 |  j } | d } |  j d |  j d | } |  j d |  j d | } | d } t ƒ  } x> | d d D]. } | d d j ƒ  } | d }	 |	 | | <q³ W| d d d | d <|  j d |  j d | =|  j d |  j d | d d d !|  j d |  j d | d <|  j d	 k r‘|  j t	 |  j d |  j d d d ƒ =n |  j
 ƒ  |  j d 8_ t |  j ƒ t d ƒ |  _ t |  j d ƒ |  j d	 k rt t |  j d |  j d ƒ d ƒ }
 n t |  j |  j ƒ }
 |  j d |  j d d d d d } x¹ |
 D]± } |  j | ƒ } |  j | ƒ } |  j | d ƒ } t |  j t d | d | d | d | d | d | d ƒ	 t |  j t d | d | d | d | d | d | d ƒ	 qTWt ƒ  t |  j |  j ƒ | | f S(   s  Remove and return the last nucleotide of the chain
        
        ARGUMENTS:
            None
        RETURNS:
            nucType - the type of base (i.e. "A", "G", "C", or "U")
            coords  - the coordinates of the removed nucleotide in the format atomName: [x, y, z]
        EFFECTS:
            The last nucleotide of the chain will be removed from the Coot molecule, as will the batons
            connecting the phosphates and the C1' atom of that nucleotide
        NOTE:
            This function assumes that the phosphate is the first atom of the penultimate nucleotide.  This
            is always true for molecules built using the addPhos() and addBaseAndPhos() functions, but may
            not be true for arbitrary molecules.  As a result, this function should *not* be called for
            pseudoMolecule objects created via the createFromMolecule argument.
        i   i    i   i   R   iÿÿÿÿs   Accepted Batonsi   N(   NN(   Re   R   R(   R@   R   R'   t   dictR^   R!   R0   R1   R   R   R   R   t   xrangeR)   RL   Ra   R   RM   R   R6   R   (   R7   t   lastPhosNtIndext   lastFullNtIndext
   lastPhosNtt
   lastFullNtt   nucTypeRC   t   curAtomDataRb   t	   curCoordst
   nucsToDrawRS   t   iRP   t   c1Coordst   nextPhosCoords(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   removeLastBaseAndPhosÕ  sJ    !	

	
A-
+(=Ac         C   s¤  |  j  ƒ  d k r d	 S|  j d k	 r7 |  j d 8_ n  |  j d |  j d j d ƒ } | d } t ƒ  } x: | d D]. } | d d j ƒ  } | d } | | | <qv W|  j d k r|  j	 t
 |  j d |  j d d d ƒ =x= |  j d |  j d D] } | d c d 8<qú Wn
 |  j ƒ  t |  j ƒ t d ƒ |  _ t |  j d ƒ |  j d k r‡t t |  j d |  j d ƒ d ƒ } n t |  j |  j ƒ } |  j d |  j d d d d d }	 x¹ | D]± }
 |  j |
 ƒ } |  j |
 ƒ } |  j |
 d ƒ } t |  j t d | d | d | d | d | d | d ƒ	 t |  j t d | d | d | d | d | d | d ƒ	 qËWt ƒ  t |  j |  j ƒ | | f S(
   s  Remove and return the first nucleotide of the chain
        
        ARGUMENTS:
            None
        RETURNS:
            nucType - the type of base (i.e. "A", "G", "C", or "U")
            coords  - the coordinates of the removed nucleotide in the format atomName: [x, y, z]
        EFFECTS:
            The first nucleotide of the chain will be removed from the Coot molecule, as will the batons
            connecting the phosphates and the C1' atom of that nucleotide
        NOTE:
            removeLastBaseAndPhos is used for Previous Nt when tracing 5'->3'.  This function provides
            the equivalent functionality when tracing 3'->5'.
            This function should *not* be called for pseudoMolecule objects created via the createFromMolecule argument.
        i   i    i   i   iÿÿÿÿs   Accepted Batonsi   N(   NN(   Re   R   R)   R   R'   t   popRf   R^   R(   R!   R0   R1   R   R   R   R   Rg   R@   RL   Ra   R   RM   R   R6   R   (   R7   t   firstNtRl   RC   Rm   Rb   Rn   RX   Ro   RS   Rp   RP   Rq   Rr   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   removeFirstBaseAndPhos/  s@    !
	
*
+(=Ac   
      C   sÀ   t  ƒ  } x° |  j d |  j d D]– } | d } t | d ƒ t | d ƒ j ƒ  } i  } x: | d D]. } | d d j ƒ  } | d } | | | <qg Wt | | | ƒ }	 | j |	 ƒ q" W| S(   sé   Return a chain object containing all coordinates
        
        ARGUMENTS:
            None
        RETURNS:
            a list of coordinates for each nucleotide, where the coordinates are formatted as atomName: [x, y, z]
        i    i   i   i   (   R   R   R'   R0   R^   R   t   addNuc(
   R7   t   chainObjRX   t   resNameR_   t   atomDictRR   Rb   t
   atomCoordst   nucObj(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   createChainObject  s    		
$
c         C   s1   |  j  | ƒ } |  j  | ƒ } |  j | | | ƒ S(   s×  Create a chain object containing coordinates for some nucleotides
        
        ARGUMENTS:
            startRes - the starting residue
            endRes   - the ending residue
        OPTIONAL ARGUMENTS:
            addFlankingAtoms - if True, add the 5' and 3' atoms that will move during minimization
                               Note that these atoms are only added if the 5' and 3' nucleotides are connected
                               to startRes and endRes, respectively.
                               In particular, the 3' phosphate, non-bridging oxygens, O5', and C5' will be added
                               and the 5' O3', and C3'.
                               (The 3' C5' and 5' C3' don't actually move during the minimization, but the C5'-O5' and
                               C3'-O3' bond can move due to movement in the O5' and O3' atoms, so we include the carbons
                               in the chain object so that the bonds can be drawn.)
                               Defaults to False
        RETURNS:
            a list of coordinates for each nucleotide, where the coordinates are formatted as atomName: [x, y, z]
            if addFlankingAtoms is True, then the following are also returned:
                resNum5p - the number of the 5' nucleotide, or None if the 5' nucleotide is not connected (or non-existant)
                resNum3p - the number of the 3' nucleotide, or None if the 3' nucleotide is not connected (or non-existant)
        (   R]   t!   createPartialChainObjectFromIndex(   R7   t   startRest   endRest   addFlankingAtomst
   startIndext   endIndex(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   createPartialChainObject›  s    c         C   sÍ  | | k r | | } } n  t  ƒ  } d } d } | r|  j | ƒ r|  j d |  j d | d } | d } t | d ƒ t | d ƒ j ƒ  } i  }	 xO | d D]C }
 |
 d d j ƒ  } | t d d g ƒ k r¥ |
 d |	 | <q¥ q¥ Wt | |	 | ƒ } | j	 | ƒ n  x» |  j d |  j d | | d !D]– } | d } t | d ƒ t | d ƒ j ƒ  } i  }	 x: | d D]. }
 |
 d d j ƒ  } |
 d } | |	 | <qwWt | |	 | ƒ } | j	 | ƒ q2W| r²|  j
 | ƒ r²|  j d |  j d | d } | d } t | d ƒ t | d ƒ j ƒ  } i  }	 xX | d D]L }
 |
 d d j ƒ  } | t d d d	 d
 d g ƒ k r@|
 d |	 | <q@q@Wt | |	 | ƒ } | j	 | ƒ n  | rÅ| | | f S| Sd S(   sç  Create a chain object containing coordinates for some nucleotides
        
        ARGUMENTS:
            startIndex - the starting residue index
            endIndex   - the ending residue index
        OPTIONAL ARGUMENTS:
            addFlankingAtoms - if True, add the 5' and 3' atoms that will move during minimization
                               Note that these atoms are only added if the 5' and 3' nucleotides are connected
                               to startRes and endRes, respectively.
                               In particular, the 3' phosphate, non-bridging oxygens, O5', and C5' will be added
                               and the 5' O3', and C3'.
                               (The 3' C5' and 5' C3' don't actually move during the minimization, but the C5'-O5' and
                               C3'-O3' bond can move due to movement in the O5' and O3' atoms, so we include the carbons
                               in the chain object so that the bonds can be drawn.)
                               Defaults to False
        RETURNS:
            a list of coordinates for each nucleotide, where the coordinates are formatted as atomName: [x, y, z]
            if addFlankingAtoms is True, then the following are also returned:
                resNum5p - the number of the 5' nucleotide, or None if the 5' nucleotide is not connected (or non-existant)
                resNum3p - the number of the 3' nucleotide, or None if the 3' nucleotide is not connected (or non-existant)
        i    i   i   i   s   O3's   C3'R   s   O5's   C5'R   R   N(   R   R   t   connectedToPrevFromIndexR   R'   R0   R^   t	   frozensetR   Rw   t   connectedToNextFromIndex(   R7   R‚   Rƒ   R�   Rx   t   resNum5pt   resNum3pRX   Ry   Rz   RR   Rb   R|   R_   R{   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR~   ¹  sP    	 
$*
$
 
$!c      	   C   s¤   g  } xN | j  ƒ  D]@ \ } } | j d | d g d t d | d d !g | g ƒ q W|  j | ƒ } |  j d |  j d | d j | ƒ t |  j |  j ƒ d S(	   s¥  Add sugar atoms to an already existing residue
        
        ARGUMENTS:
            resNum      - the residue to add the coordinates to (using Coot numbering)
            sugarCoords - the sugar coordinates in the form atomName: [x, y, z]
        RETURNS:
            None
        EFFECTS:
            The new sugar atoms will be drawn, but the batons connecting the phosphate and C1' atom will NOT be removed
        s   %4sR>   g      ð?s    %si    i   i   N(	   t	   iteritemsRI   RA   R]   R   R'   RK   R6   R   (   R7   R_   t   sugarCoordsRW   Rb   RC   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   addSugar  s    8'c         C   s…   |  j  | ƒ } x\ |  j d |  j d | d D]: } | d d j ƒ  } | j | ƒ r0 | | | d <q0 q0 Wt |  j |  j ƒ d S(   sf  Replace the sugar atoms in an already existing residue
        
        ARGUMENTS:
            resNum      - the residue to change the coordinates to (using Coot numbering)
            sugarCoords - the sugar coordinates in the form atomName: [x, y, z]
        RETURNS:
            None
        EFFECTS:
            The new sugar atoms will be drawn
        i    i   i   i   N(   R]   R   R'   R^   t   has_keyR6   R   (   R7   R_   R‹   R]   t   atomRb   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   replaceSugar%  s    'c         C   s#   |  j  | ƒ } |  j | | ƒ d S(   s•  Add non-bridging phosphoryl oxygens to an already existing residue
        
        ARGUMENTS:
            resNum        - the residue to add the coordinates to using Coot numbering
            phosOxyCoords - the non-bridging oxygen coordinates in the form atomName: [x, y, z]
        RETURNS:
            None
        EFFECTS:
            The new oxygen atoms will be added to the Coot molecule
        N(   R]   t   addPhosOxyFromIndex(   R7   R_   t   phosOxyCoordsR]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt
   addPhosOxy;  s    c         C   s±   g  } xj | j  ƒ  D]\ \ } } | d k s7 | d k r d | } n q | j | d g d t d d g | g ƒ q W|  j d |  j d | d	 j | ƒ t |  j |  j ƒ d
 S(   s€  Add non-bridging phosphoryl oxygens to an already existing residue
        
        ARGUMENTS:
            resIndex      - the residue to add the coordinates to
            phosOxyCoords - the non-bridging oxygen coordinates in the form atomName: [x, y, z]
        RETURNS:
            None
        EFFECTS:
            The new oxygen atoms will be added to the Coot molecule
        R   R   R   R>   g      ð?s    Oi    i   i   N(   RŠ   RI   RA   R   R'   RK   R6   R   (   R7   R]   R‘   RW   Rb   RC   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR�   K  s    ,'c         C   s   i  } xr |  j  d |  j d | d d D]L } | d d } | d k sW | d k r+ | j ƒ  } n q+ | d | | <q+ W| S(   sˆ  Get the non-bridging phosphoryl oxygen coordinates for the specified residue.
        
        ARGUMENTS:
            resNum - the residue number
        RETURNS:
            the non-bridging oxygen coordinates of the specified residue as a dictionary in the form atomName: [x, y, z]
        NOTE:
            Negative numbers can be used to refer to residues at the end of the chain
        i    i   i   iþÿÿÿs    OP1s    OP2i   (   R   R'   R^   (   R7   R_   R‘   RR   Rb   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt
   getPhosOxye  s    +c         C   s   |  j  S(   s«   Get the Coot molecule number used to display atoms from this object.
        
        ARGUMENTS:
            None
        RETURNS:
            the molecule number
        (   R   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   molNum~  s    	c         C   sÜ   |  j  | ƒ } |  j  | ƒ } g  } x± t | | d ƒ D]œ } |  j | ƒ \ } } t |  j |  j | | ƒ }	 |	 |  j d |  j d | d <i  }
 x0 |	 D]( } | d d j ƒ  } | d |
 | <q› W| j	 |
 ƒ q8 W| S(   s>  Update the Python representation of the specified residues.
        ARGUMENTS:
            startingResNum - the first residue to update, using Coot numbering
            endingResNum   - the last residue to update, using Coot numbering
        RETURNS:
            newCoordDicts - a list of dictionaries containing the updated atom coordinates
        EFFECTS:
            updates the Python representation of the specified residues
        NOTE:
            This function must be run whenever atom coordinates are changed in Coot (such as after a minimization run)
        i   i    i   i   (
   R]   Rg   R_   t   residue_infoR   R&   R   R'   R^   RI   (   R7   t   startingResNumt   endingResNumt   startingResIndext   endingResIndext   newCoordDictst   curResIndext	   curResNumt
   curInsCodet	   newCoordst
   curResDictRR   Rb   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt	   updateResŠ  s     c         C   s   t  |  j ƒ d S(   s�   Delete the Coot molecule associated with this object.
        
        ARGUMENTS:
            None
        RETURNS:
            None
        N(   R   R   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   deleteMolecule¶  s    	c         C   sE   |  j  | ƒ } |  j  | ƒ } t |  j d |  j d | | d !ƒ S(   s¾  Retrieve the Coot structure for the specified nucleotides.
        
        ARGUMENTS:
            startingRes - the first residue to retrieve the structure for
            endingRes   - the last residue to retrieve the structure for
        RETURNS:
            a copy of the Coot representation of residues startingRes-endingRes
        NOTE
            This function is used to cache structure so that it can easily be restored later.
        i    i   (   R]   R    R   R'   (   R7   t   startingRest	   endingRest   startingIndext   endingIndex(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   getCootNucsÂ  s    c         C   sg   |  j  | ƒ } |  j  | ƒ } t | ƒ |  j d |  j d | | d +| rc t |  j |  j ƒ n  d S(   sj  Set the structure for the given nucleotides given a Coot-formatted list (typically something that had previously been returned by getCootNucs)
        
        ARGUMENTS:
            startingRes - the first residue to set the structure for
            endingRes   - the last residue to set the structure for
            cootNucs    - a list of the nucleotides to restore, formatted in the Coot internal representation format (typically returned from the getCootNucs function)
        OPTIONAL ARGUMENTS:
            updateMol   - whether to update the Coot molecule via clear_and_update_molecule
                          defaults to True
                          ONLY use this if you know the Coot molecule will be updated at a later time
        RETURNS:
            None
        EFFECTS:
            sets the coordinates of the specified nucleotides to cootNucs
        i    i   N(   R]   R    R   R'   R6   R   (   R7   R¢   R£   t   cootNucst	   updateMolR¤   R¥   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   setCootNucsÓ  s
    )c         C   s5  |  j  | ƒ } |  j  | ƒ } | d k	 r@ | | j  | ƒ } n d } |  j d |  j d } xût | | d ƒ D]æ}	 |	 | }
 x– t t | |	 d ƒ d d d ƒ D]p } | |	 d | d d j ƒ  } | |	 d | d d j ƒ  } | d k s| t k r§ | |	 d | =q§ q§ W| d k	 rC|	 | k rC|	 d k rC|
 d k rC| |
 d k	 rCxj t t | |	 d ƒ ƒ D]N } | |	 d | d d j ƒ  d k rv| |
 d | |	 d | d <PqvqvWxú t t | |	 d d ƒ ƒ D]U } | |	 d d | d d j ƒ  d k rç| |
 d | |	 d d | d <qçqçWn‚ | d k	 rÅxs t t | |	 d ƒ ƒ D]T } | |	 d | d d j ƒ  d k rj| j |
 j	 d | |	 d | d <PqjqjWn  | d k	 rr x„ t t | |	 d ƒ ƒ D]e } | |	 d | d d j ƒ  } | t
 k s*| d	 k rì| j |
 j	 | | |	 d | d <qìqìWqr qr W| d }	 |  j | ƒ rt | |	 d ƒ d
 k r|  j |	 ƒ rx| t t | |	 d ƒ d d d ƒ D]S } | |	 d | d d j ƒ  } | t d d d g ƒ k rÄ| |	 d | =qÄqÄWn  t |  j |  j ƒ d S(   su  Reset the specified nucleotides to the condition they were in immediately before their minimization
        
        ARGUMENTS:
            startingRes          - the first residue to reset
            endingRes            - the last residue to reset
        OPTIONAL ARGUMENTS
            origCoords           - a list of the orginal phosphate and base coordinates for all nucleotides
                                   if not provided, then the phosphate and base coordinates will not be reset
                                   but all other atoms will still be deleted
                                   must be given if intermediateAtomLocs is given
            intermediateAtomLocs - a list of P, O5', and C5' coodinates as they were immediately after the
                                   minimization of the previous nucleotide, but before the minimization of
                                   that nucleotide
                                   if not provided, then these atom coordinates will not be reset
        RETURNS:
            None
        EFFECTS:
            Resets the coordinates of the specified nucleotides
        i    i   i   iÿÿÿÿi   t   HR   s   O3's   C1'i   R   R   R   N(   R]   R   R   R'   Rg   R@   R^   t&   ATOMS_TO_ERASE_FOR_REBUILDING_MOLECULEt   nucleotidest   atomst
   BASE_ATOMSR‡   R†   R6   R   (   R7   R¢   R£   t
   origCoordst   intermediateAtomLocsR¤   R¥   t   origCoordsOffsetRD   R›   t   origCoordsCurResIndext   curAtomIndext   curAtomNamet   curAtomType(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt	   resetNucsì  sL    
+  @!&%*,!&$! 2
9+ c         C   sb  |  j  ƒ  |  j d |  j d |  j |  j !} g  } d } x„| d  D]x} t g  | d D] } | d d | d f ^ qZ ƒ } xª t D]¢ \ } } }	 | j | ƒ rˆ | j | ƒ rˆ t	 | | | | ƒ |	 k rˆ | j
 t d | | d | | d | | d | | d | | d | | d g ƒ qˆ qˆ W| d k	 rŸt	 | | d ƒ t k rŸ| j
 t d | d | d | d | d d | d d | d d g ƒ n  | d } | d j ƒ  }
 |
 d	 k sÑ|
 d
 k rIt	 | d | d ƒ t k r¾| j
 t d | d d | d d | d d | d d | d d | d d g ƒ q¾qF t	 | d | d ƒ t k rF | j
 t d | d d | d d | d d | d d | d d | d d g ƒ qF qF W| d } t g  | d D] } | d d | d f ^ qÚƒ } x“ t d d !D]„ \ } } }	 t	 | | | | ƒ |	 k r| j
 t d | | d | | d | | d | | d | | d | | d g ƒ qqW| d k	 rt	 | | d ƒ t k r| j
 t d | d | d | d | d d | d d | d d g ƒ n  t | ƒ rWt d ƒ |  _ t |  j d ƒ x! | D] } t |  j | Œ q:Wn  t ƒ  d S(   sõ  Draw any bonds that are too long for Coot to render
        
        ARGUMENTS:
            None
        RETURNS:
            None
        EFFECTS:
            Draws bonds into drawing object self.__extraBondObject
        NOTE:
            If the extra bond starting and ending residues have been set via a setExtraBondRange() call, then this
            function will only draw extra bonds for the specified residues.  Otherwise extra bonds will be drawn for
            the entire molecule
        i    i   iÿÿÿÿi   i   i   s    P  s    O3'R   R?   s    C1's    N9 s    N1 s   Extra bondsN(   t   clearExtraBondsR   R'   R"   R#   R   Rf   R   R�   R   RI   RM   R   R^   R@   R   R    R   R   R   (   R7   RD   t   lineListt   prevO3RX   RR   t   curResCoordst   atom1t   atom2t
   distCutoffRy   t   curLine(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   drawExtraBondsN  s>    
%5;\%L
[\
5\%Lc         C   s,   |  j  d k	 r t |  j  ƒ n  d |  _  d S(   sÝ   Clears any extra bonds drawn by drawExtraBonds
        
        ARGUMENTS:
            None
        RETURNS:
            None
        EFFECTS:
            Clears all bonds in drawing object self.__extraBondObject
        N(   R    R   R   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR·   ’  s    c         C   s8   |  j  | ƒ } |  j  | ƒ d } | |  _ | |  _ d S(   sS  Set the nucleotides that will have extra bonds drawn during any subsequent drawExtraBonds() call
        
        ARGUMENTS
            startingResNum - the residue number of the first residue to draw bonds for
            endingResNum   - the residue number of the lsat residue to draw bonds for
        RETURNS:
            None
        i   N(   R]   R"   R#   (   R7   R–   R—   R¤   R¥   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   setExtraBondRange¢  s    	c         C   s   d |  _ d |  _ d S(   s©   Make any subsequent drawExtraBonds() call draw extra bonds for the entire molecule
        
        ARGUMENTS
            None
        RETURNS:
            None
        N(   R   R"   R#   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   clearExtraBondRange´  s    		c         C   s   |  j  t | ƒ S(   s  Find the index (i.e. position in the chain) of a given residue number
        
        ARGUMENTS:
            resNum - the residue number to find (which may include an insertion code)
        RETURNS:
            the index of the specified residue number in this chain
        (   R!   R0   (   R7   R_   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR]   Á  s    	c         C   s.   |  j  d |  j d | } | d | d f S(   s   Given a residue index, retrieves the residue number and insertion code
        
        ARGUMENTS:
            resIndex - the residue index
        RETURNS:
            the residue number (without the insertion code)
            the insertion code
        i    i   (   R   R'   (   R7   R]   t   res(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR_   Í  s    
c         C   s>   |  j  d |  j d | } t | d ƒ t | d ƒ j ƒ  S(   sÿ   Given a residue index, retrieves the full residue number (i.e. including insertion code)
        
        ARGUMENTS:
            resIndex - the residue index
        RETURNS:
            the residue number as a string including the insertion code
        i    i   (   R   R'   R0   R^   (   R7   R]   RÂ   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt
   resNumFullÛ  s    	c         C   s{   g  |  j  d |  j d D]$ } t | d ƒ t | d ƒ ^ q } t g  t | ƒ D] \ } } | | f ^ qS ƒ |  _ d S(   s·   initialize the resNum lookup dictionary if this object was created with an initial residue list
        
        ARGUMENTS:
            None
        RETURNS:
            None
        i    i   N(   R   R'   R0   Rf   t	   enumerateR!   (   R7   RÂ   t
   resNumListR]   R_   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   __initializeResNumDictè  s    	Cc   
      C   sÆ   |  j  | ƒ } |  j  | ƒ } i  } x‰ t | | d ƒ D]t } |  j | ƒ } i  | | <xR |  j d |  j d | d D]0 } | d d j ƒ  }	 | d d | | |	 <qx Wq8 W| | | g |  _ d S(   s  Save the B-factors for the specified nucleotides.
        
        ARGUMENTS:
            startingRes - the first residue to save the B-factors for
            endingRes   - the last residue to save the B-factors for
        RETURNS:
            None
        i   i    i   N(   R]   Rg   RÃ   R   R'   R^   R%   (
   R7   R¢   R£   R¤   R¥   t   bfacsR›   R_   RR   Rb   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt	   saveBfacsö  s    

'c   
      C   s  | r |  j  | ƒ } n |  j d } | r= |  j  | ƒ } n |  j d } |  j d } x• t | | d ƒ D]€ } |  j | ƒ } xh |  j d |  j d | d D]F } | d d j ƒ  }	 | | j |	 ƒ r¡ | | |	 | d d <q¡ q¡ Wqk Wt |  j	 |  j ƒ d S(   s"  Restore the B-factors saved using saveBfacs()
        
        OPTIONAL ARGUMENTS:
            startingRes - the first residue to restore the B-factors for
                          if not given, B-factors will be restored starting from the first residue saved
            endingRes   - the last residue to restore the B-factors for
                          if not given, B-factors will be restored to the last residue saved
        RETURNS:
            None
        NOTE:
            This function will *not* clear the saved B-factors.
        i    i   i   i   N(
   R]   R%   Rg   RÃ   R   R'   R^   R�   R6   R   (
   R7   R¢   R£   R¤   R¥   RÇ   R›   R_   RR   Rb   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   restoreSavedBfacs  s    '!c         C   s   |  j  d k	 S(   s¾   Does this object have B-factors saved using saveBfacs()?
        
        ARGUMENTS:
            None
        RETURNS:
            True if there are saved B-factors, False otherwise
        N(   R%   R   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   hasSavedBfacs<  s    	c         C   s   d |  _ d S(   s�   Clear coordinates saved using saveBfacs()
        
        ARGUMENTS:
            None
        RETURNS:
            None
        N(   R   R%   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   clearSavedBfacsH  s    	c         C   s"   | | |  j  | | ƒ g |  _ d S(   s  Save coordinates of the specified residues so they can be restored later
        
        ARGUMENTS:
            startingRes - the first residue to save the structure of
            endingRes   - the last residue to save the structure of
        RESTURNS:
            None
        N(   R¦   R$   (   R7   R–   R—   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   saveCoordinatesT  s    
c         C   s2   |  j  \ } } } |  j | | | ƒ d |  _  d S(   s  Restore coordinates saved using saveCoordinates
        
        ARGUMENTS:
            None
        RETURNS:
            None
        EFFECTS:
            Will clear the saved coordinates after restoring them (i.e. subsequent calls to hasSavedCoordinates will return False)
        N(   R$   R©   R   (   R7   R–   R—   R§   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   restoreSavedCoordinatesa  s    c         C   s   |  j  d k	 S(   sÈ   Does this object have coordinates saved using saveCoordinates()?
        
        ARGUMENTS:
            None
        RETURNS:
            True if there are saved coordinates, False otherwise
        N(   R$   R   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   hasSavedCoordinatesq  s    	c         C   s   d |  _ d S(   s‡   Clear coordinates saved using saveCoordinates()
        
        ARGUMENTS:
            None
        RETURNS:
            None
        N(   R   R$   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   clearSavedCoordinates}  s    	c         C   s  | d |  j  ƒ  k r t SxT |  j d |  j d | d D]. } | d d j ƒ  d k r; | d } Pq; q; Wt SxX |  j d |  j d | d d D]. } | d d j ƒ  d k r– | d } Pq– q– Wt S|  j d |  j d | d d d k rú t St | | ƒ | k rt St Sd S(	   s�  Determine if a nucleotide is connected to the next nucleotide
        
        ARGUMENTS:
            resIndex - the residue index
        OPTIONAL ARGUMENTS:
            distanceCutoff - how long can the O3'-P bond be before the nucleotides are considered not connected
        RETURNS:
            True if the residue is connected to the next one
            False otherwise
        i   i    i   s   O3'i   R   R>   N(   Re   t   FalseR   R'   R^   R   t   True(   R7   R]   t   distanceCutoffRR   t   o3CoordsRP   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR‡   ‰  s"    '
+
*c         C   s(   | d k r t  S|  j | d | ƒ Sd S(   s‰  Determine if a nucleotide is connected to the previous nucleotide
        
        ARGUMENTS:
            resIndex - the residue index
        OPTIONAL ARGUMENTS:
            distanceCutoff - how long can the O3'-P bond be before the nucleotides are considered not connected
        RETURNS:
            True if the residue is connected to the previous one
            False otherwise
        i    i   N(   RÐ   R‡   (   R7   R]   RÒ   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR…   µ  s    g      @c         C   s#   |  j  | ƒ } |  j | | ƒ d S(   s€  Determine if a nucleotide is connected to the next nucleotide
        
        ARGUMENTS:
            resNum - the residue number
        OPTIONAL ARGUMENTS:
            distanceCutoff - how long can the O3'-P bond be before the nucleotides are considered not connected
        RETURNS:
            True if the residue is connected to the next one
            False otherwise
        N(   R]   R‡   (   R7   R_   RÒ   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   connectedToNextÇ  s    c         C   s#   |  j  | ƒ } |  j | | ƒ d S(   s„  Determine if a nucleotide is connected to the next nucleotide
        
        ARGUMENTS:
            resNum - the residue number
        OPTIONAL ARGUMENTS:
            distanceCutoff - how long can the O3'-P bond be before the nucleotides are considered not connected
        RETURNS:
            True if the residue is connected to the previous one
            False otherwise
        N(   R]   R…   (   R7   R_   RÒ   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   connectedToPrev×  s    c         C   så   |  j  d |  j d | d } | d k s8 | d k rA d } n% | d k sY | d k rb d	 } n d
 Sg  |  j  d |  j d | d D] } | d d j ƒ  ^ q‡ } t | ƒ } x+ d d | f D] } | | k rÃ | SqÃ Wd Sd S(   s*  Make sure that the specified nucleotide contains phosphate and glycosidic bond coordinates
        
        ARGUMENTS:
            resIndex - the residue index
        RETURNS:
            None if the nucleotide contains the required atoms
            atom name of a missing atom otherwise
        i    i   i   t   Ct   Ut   N1R?   R   t   N9s   N1/9i   R   s   C1'N(   R   R'   R^   R†   R   (   R7   R]   t   resTypet   baseNRŽ   RW   t   atomSetRR   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   checkPhosAndGlycosidicFromIndexç  s    
 		Ac         C   sQ   xJ |  j  d |  j d | d D]$ } | d d j ƒ  d k r! t Sq! Wt Sd S(   sº  Find out if a given residue using PDB2-style naming
        
        ARGUMENTS:
            resIndex - the residue index to check
        RETURNS:
            True if this residue uses PDB2-style naming
            False otherwise
        NOTES:
            Currently, this function simply checks for a C1* atom.  If it exists, then the residue
            is assumed to use PDB2 naming.  Otherwise, the residue is assumed to be okay
        i    i   i   s   C1*N(   R   R'   R^   RÑ   RÐ   (   R7   R]   RR   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   checkPDB2FromIndex  s    'c         C   s$   t  |  j d |  j d | d ƒ S(   sú   Return the number of atoms within a given residue (useful for deciding if a residue is just a phosphate)
        ARGUMENTS
            resIndex - the residue index to check
        RETURNS:
            the number of atoms in residue resIndex
        i    i   i   (   R@   R   R'   (   R7   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   numAtomsFromIndex  s    c         C   s   |  j  | ƒ } |  j | ƒ S(   s<  Calculate all torsions for the specified suite.
        
        ARGUMENTS:
            resNum - the suite number to calculate torsions for
        RETURNS
            a list containing the seven suite torsions
            note that missing suite atoms will result in None entries for the undefined torsions
        (   R]   t   calcSuiteTorsionsFromIndex(   R7   R_   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   calcSuiteTorsions$  s    
c         C   sª   | d k s |  j  | ƒ r  d S|  j | d | ƒ } | j d j ƒ  | j d j ƒ  | j d j ƒ  | j d j ƒ  | j d j ƒ  | j d j	 ƒ  | j d j ƒ  g S(   s=  Calculate all torsions for the specified suite.
        
        ARGUMENTS:
            resIndex - the suite index to calculate torsions for
        RETURNS
            a list containing the seven suite torsions
            note that missing suite atoms will result in None entries for the undefined torsions
        i    i   N(
   R…   R   R~   t   nucst   deltat   epsilont   zetat   alphat   betat   gamma(   R7   R]   Rx   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyRà   2  s    c         C   s´   x­ |  j  d D]ž } x• | d D]‰ } | d d } | d d d k r | d d d k r | d d d k r | d d d k r | d d d k r | d j ƒ  q q Wq Wd S(	   sL  Work around a bug in Coot's python_representation function where any TER lines in the PDB file get converted to an unnamed atom with no occupancy at coordinates (0,0,0)
        
        ARGUMENTS:
            None
        RETURNS:
            None
        EFFECTS:
            Removes any "blank" atoms from self.__molecule
        i    i   i   iÿÿÿÿR>   g        i   N(   R   Rt   (   R7   t   curChainRX   t	   finalAtom(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   __fixTerAtomsK  s
    dc         C   s   t  ƒ  d k r d Sxe |  j d D]V } xM | d D]A } x8 | d D], } t | d d t ƒ rC t d ƒ ‚ qC qC Wq2 Wq! Wd S(   s¾  Make sure that we're not going to have any problems with anisotropic temperature records
        
        ARGUMENTS:
            None
        RETURNS:
            None
        EXCEPTIONS:
            raises a PseudoMoleculeError if Coot is older than revision 3631 and self.__molecule contains
            anisotropic temperature records, since clear_and_update_molecule() won't be able to handle
            reading the molecule back in
        i/  Ni    i   i   s¢   This molecule contains anisotropic temperature records.  RCrane requires Coot 0.7-pre r3631 or newer to rotamerize molecules with anisotropic temperature records.(   R   R   R[   t   listR/   (   R7   Ré   RX   RR   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   __checkAnisoh  s    c         C   su   |  j  | ƒ } g  |  j d |  j d | d D] } | d d ^ q0 } | rm g  | D] } | j ƒ  ^ qW S| Sd S(   sz  Get a list of all the atom names in a specific residue
        
        ARGUMENTS:
            resNum    - the residue number to get atom names from
        OPTIONAL ARGUMENTS:
            strip     - whether to remove leading and trailing spaces from the atom names
                        defaults to True
        RETURNS:
            atomNames - a list of atom names
        i    i   i   N(   R]   R   R'   R^   (   R7   R_   R^   R]   RR   t	   atomNames(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   getAtomNames€  s
    ;c         C   s$   t  |  j d |  j d | d ƒ S(   s×   Get the residue type (i.e. A, G, C, or U) of the specified residue
        
        ARGUMENTS:
            resIndex - the residue index
        RETURNS:
            the residue type of the specified residue
        i    i   i   (   R0   R   R'   (   R7   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   resTypeFromIndex˜  s    	sK   P OP1 OP2 O5' C5' C4' O4' C3' O3' C2' O2' C1' N9 C8 N7 C5 C6 N6 N1 C2 N3 C4R   i(   R   sN   P OP1 OP2 O5' C5' C4' O4' C3' O3' C2' O2' C1' N9 C8 N7 C5 C6 O6 N1 C2 N2 N3 C4R?   sE   P OP1 OP2 O5' C5' C4' O4' C3' O3' C2' O2' C1' N1 C2 O2 N3 C4 N4 C5 C6RÖ   sE   P OP1 OP2 O5' C5' C4' O4' C3' O3' C2' O2' C1' N1 C2 O2 N3 C4 O4 C5 C6R×   c            s  d } d } ˆ j d k	 r? ˆ j d k	 r? ˆ j } ˆ j } n  xG ˆ j d ˆ j d | | !D]& ‰  ˆ  d j d ‡  ‡ f d †  ƒ q_ Wxo ˆ j d ˆ j d | | !D]N ‰  ˆ  d d d d } | d k r© x# ˆ  d D] } | | d d <qÜ Wq© q© Wt ˆ j ˆ j ƒ d S(   sM  Perform a final cleanup on the coot molecule, consisting of:
            Reordering the newly created atoms so that they follow the standard ordering for RNA residues
            Restoring the segid for all newly created atoms (if requested)
        
        ARGUMENTS:
            None
        OPTIONAL ARGUMENTS:
            fixSegids - whether to properly set segid (segment ID, such as used in CNS) for all newly created atoms
                Defaults to False
                Note that this is only required when doing a rotamerize, not when creating a new trace,
                since new molecules created by RCrane always have a blank segid
        RETURNS:
            None
        NOTE:
            If the extra bond range has been set via setExtraBondRange, then only nucleotides in that range will
            be cleaned up.
        i    i   i   t   keyc            s'   ˆ j  t ˆ  d ƒ |  d d j ƒ  S(   Ni   i    (   t"   _PseudoMolecule__reorderAtomsOrderR0   R^   (   t   x(   RX   R7   (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   <lambda>Ç  s    R>   N(   R   R"   R#   R   R'   t   sortR6   R   (   R7   t	   fixSegidsR‚   Rƒ   t   desiredSegidRR   (    (   RX   R7   s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   finalMoleculeCleanup¬  s    	&$&c         C   s�   |  j  d |  j d | d } t | ƒ d k r6 t SxP |  j  d |  j d | d D]* } | d d j ƒ  } | t k rW t SqW Wt Sd S(   sK  Determine if the specified residue contains no more than a phosphate group (i.e. P, OP1, OP2, and/or OP3)
        
        ARGUMENTS:
            resIndex - the residue index
        RETURNS:
            True if the specified residue is only a phosphate group (or a subset of a phosphate group)
            False otherwise
        i    i   i   i   N(   R   R'   R@   RÐ   R^   t   PHOS_GROUP_ATOMSRÑ   (   R7   R]   RW   RR   Rb   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   isOnlyPhosGroupFromIndexØ  s    
 'c         C   s   |  j  | ƒ } |  j | ƒ S(   sJ  Determine if the specified residue contains no more than a phosphate group (i.e. P, OP1, OP2, and/or OP3)
        
        ARGUMENTS:
            resNum - the residue number
        RETURNS:
            True if the specified residue is only a phosphate group (or a subset of a phosphate group)
            False otherwise
        (   R]   Rú   (   R7   R_   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   isOnlyPhosGroupõ  s    
c         C   sQ   xJ |  j  d |  j d | d D]( } | d d j ƒ  d k r! | d Sq! Wd S(   sÓ   Get the coordinates of a specified phosphate.
        
        ARGUMENTS:
            resIndex - the residue index
        RETURNS:
            the coordinates of the phoshate from the specified residue
        i    i   i   R   i   N(   R   R'   R^   R   (   R7   R]   RR   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyRL     s    	'c         C   s   | |  _  | |  _ d S(   s€  Set the residue insertion point (i.e. where in the chain new nucleotides should be added).
        This is only necessary when doing an extend chain.
        
        ARGUMENTS:
            resIndex - the residue index to use as the residue insertion point
        RETURNS:
            None
        NOTE:
            This sets both resInsertionPoint and origResInsertionPoint
        N(   R(   R)   (   R7   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   setResInsertionPoint  s    	c         C   s%   t  |  j d |  j d ƒ |  _ d S(   s©   Store the state of the entire molecule (can be restored via restoreMoleculeState)
        
        ARGUMENTS:
            None
        RETURNS:
            None
        i    i   N(   R    R   R'   R*   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   saveMoleculeState$  s    c         C   sI   |  j  d k	 rA |  j  |  j d |  j d <t |  j |  j ƒ t St Sd S(   s¦   Restore the molecule state that was previously saved using saveMoleculeState()
        
        ARGUMENTS:
            None
        RETURNS:
            None
        i    i   N(   R*   R   R   R'   R6   R   RÑ   RÐ   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   restoreMoleculeState3  s
    	c         C   s   |  j  d k r t St Sd S(   së   Determine if this object has a saved molecule state (stored via saveMoleculeState())
        
        ARGUMENTS:
            None
        RETURNS:
            True if there is a saved molecule state
            False otherwise
        N(   R*   R   RÐ   RÑ   (   R7   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   hasSavedMoleculeStateD  s    
c         C   sŠ   |  j  d |  j d | d } g  | D]& } | d d j ƒ  d k r' | ^ q' } | |  j  d |  j d | d <t |  j |  j  ƒ d S(   sÉ   Delete non-bridging oxygens from the specified residue
        
        ARGUMENTS:
            resIndex - the residue index to clear non-bridging oxygens from
        RETURNS:
            None
        i    i   i   R   N(   R   R'   R^   R6   R   (   R7   R]   RW   RR   t   newAtomList(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   clearNonBridgingOxysFromIndexT  s    	 3 c         C   s:   |  j  d |  j d | =|  j ƒ  t |  j |  j  ƒ d S(   sÒ   Delete an entire residue
        
        ARGUMENTS:
            resIndex - the index number of the residue to delete
        RETURNS:
            None
        NOTES:
            No redraw will be done
        i    i   N(   R   R'   R1   R6   R   (   R7   R]   (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   deleteResFromIndexc  s    
c         C   sX   |  j  d |  j d | d } | |  j  d |  j d | d d d +|  j | ƒ d S(   s½  Merge the atom lists of two residues
        
        ARGUMENTS:
            phosGroupIndex - the first residue to merge.  Presumably, this contains only a phosphate group
            res2Index      - the second residue to merge
        RETURNS:
            None
        NOTES:
            The atoms from phosGroup will be put before the atoms of res2, but the residue information
            (i.e. residue type) from res2 will be kept.
        i    i   i   N(   R   R'   R  (   R7   t   phosGroupIndext	   res2Indext   phosGroupAtoms(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   mergeRess  s     'N(N   t   __name__t
   __module__t   __doc__RÑ   R   R=   RG   RH   RU   RZ   R`   RL   Ra   Rc   Rd   Re   Rs   Rv   R}   RÐ   R„   R~   RŒ   R�   R’   R�   R“   R”   R    R¡   R¦   R©   R¶   R¿   R·   RÀ   RÁ   R]   R_   RÃ   R1   RÈ   RÉ   RÊ   RË   RÌ   RÍ   RÎ   RÏ   t   CONNECTED_DISTANCE_CUTOFFR‡   R…   RÔ   RÕ   RÝ   RÞ   Rß   Rá   Rà   R,   R+   Rï   Rð   Rò   Rf   t   zipt   splitt   rangeRø   Rú   Rû   Rü   Rý   Rþ   Rÿ   R  R  R  (    (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR   3   s’   M	6		T	O							Z	P	T							,		b	D								-						,								((((,									c          c   s&   d }  x t  r! |  V|  d 7}  q	 Wd S(   s7   Create a generator that starts at 1 and increments by 1i   N(   RÑ   (   t   num(    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   incGeneratorŠ  s    	R/   c           B   s   e  Z RS(    (   R  R  (    (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyR/   “  s   N(.   R	  t   copyR    t   cootR   R   R   R   R   R   R   R   R	   R2   R
   R6   R   R•   R   t   coot_utils_adapterR   R   t   ImportErrorR&   R   t
   nucleotideR   t	   strucCalcR   t
   bondLengthR   R   RM   R3   RA   R†   R  R«   R®   Rù   R
  R   R  R4   t	   ExceptionR/   (    (    (    s\   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/coot/rcrane/pseudoMolecule.pyt   <module>   s@   :ÿ ÿ ÿ ÿ ÿ ÿ ÿ ^		