
:>"^W,  ã               @   sÄ   d  Z  d d l m Z d d l Z d d l m Z d d l m Z d d l m	 Z	 m
 Z
 d d l m Z Gd d	 „  d	 e ƒ Z Gd
 d „  d e ƒ Z Gd d „  d e ƒ Z Gd d „  d e ƒ Z d S)z9Half-sphere exposure and coordination number calculation.é    )Úprint_functionN)Úpi)ÚAbstractPropertyMap)ÚCaPPBuilderÚis_aa)Úrotaxisc               @   s=   e  Z d  Z d Z d d d „ Z d d „  Z d d „  Z d S)	Ú_AbstractHSExposurezçAbstract class to calculate Half-Sphere Exposure (HSE).

    The HSE can be calculated based on the CA-CB vector, or the pseudo CB-CA
    vector based on three consecutive CA atoms. This is done by two separate
    subclasses.
    Nc             C   s¥  | d k s t  ‚ g  |  _ t ƒ  } | j | ƒ } i  }	 g  }
 g  } xC| D];} x2t d t | ƒ ƒ D]} | d k rƒ d } n | | d } | | } | t | ƒ d k rº d } n | | d } |  j | | | ƒ } | d k rì qh | \ } } d } d } | d j ƒ  } xÙ | D]Ñ } xÈ t d t | ƒ ƒ D]± } | | k rbt | | ƒ | k rbq7| | } t	 | ƒ s7| j
 d ƒ rŒq7| d j ƒ  } | | } | j ƒ  | k  r7| j | ƒ t d k  rÞ| d 7} q7| d 7} q7WqW| j ƒ  } | j ƒ  j ƒ  } | | | f |	 | | f <|
 j | | | | f f ƒ | j | | f ƒ | | j | <| | j | <| rh | | j | <qh WqL Wt j |  |	 | |
 ƒ d S)aÃ  Initialize.

        :param model: model
        :type model: L{Model}

        :param radius: HSE radius
        :type radius: float

        :param offset: number of flanking residues that are ignored in the
                       calculation of the number of neighbors
        :type offset: int

        :param hse_up_key: key used to store HSEup in the entity.xtra attribute
        :type hse_up_key: string

        :param hse_down_key: key used to store HSEdown in the entity.xtra attribute
        :type hse_down_key: string

        :param angle_key: key used to store the angle between CA-CB and CA-pCB in
                          the entity.xtra attribute
        :type angle_key: string
        r   Né   ÚCAé   )ÚAssertionErrorÚ
ca_cb_listr   Úbuild_peptidesÚrangeÚlenÚ_get_cbÚ
get_vectorÚabsr   Úhas_idZnormÚangler   Úget_idÚ
get_parentÚappendÚxtrar   Ú__init__)ÚselfÚmodelÚradiusÚoffsetZ
hse_up_keyZhse_down_keyZ	angle_keyÚppbÚpplZhse_mapZhse_listZhse_keysÚpp1ÚiÚr1Úr2Úr3ÚresultZpcbr   Zhse_uZhse_dÚca2Úpp2ÚjÚroZcaoÚdÚres_idÚchain_id© r.   ú7/tmp/pip-build-ww9dw3qa/biopython/Bio/PDB/HSExposure.pyr      s\    			
	"

z_AbstractHSExposure.__init__c             C   s   t  S)N)ÚNotImplemented)r   r#   r$   r%   r.   r.   r/   r   k   s    z_AbstractHSExposure._get_cbc             C   s¬   y4 | d j  ƒ  } | d j  ƒ  } | d j  ƒ  } Wn t k
 rL d SYn X| | } | | } t t d d | ƒ } | j | ƒ } | | } |  j j | | f ƒ | S)zÈReturn a pseudo CB vector for a Gly residue (PRIVATE).

        The pseudoCB vector is centered at the origin.

        CB coord=N coord rotated over -120 degrees
        along the CA-C axis.
        ÚNÚCr
   Ng      ^@g     €f@)r   Ú	Exceptionr   r   Zleft_multiplyr   r   )r   ZresidueZn_vZc_vZca_vZrotZcb_at_origin_vZcb_vr.   r.   r/   Ú_get_gly_cb_vectorn   s    	


z&_AbstractHSExposure._get_gly_cb_vector)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r4   r.   r.   r.   r/   r      s   Or   c               @   sC   e  Z d  Z d Z d d d d „ Z d d „  Z d d	 d
 „ Z d S)ÚHSExposureCAzmClass to calculate HSE based on the approximate CA-CB vectors.

    Uses three consecutive CA positions.
    é   r   c             C   s#   t  j |  | | | d d d ƒ d S)ay  Initialse class.

        :param model: the model that contains the residues
        :type model: L{Model}

        :param radius: radius of the sphere (centred at the CA atom)
        :type radius: float

        :param offset: number of flanking residues that are ignored
                       in the calculation of the number of neighbors
        :type offset: int
        ZEXP_HSE_A_UZEXP_HSE_A_DZEXP_CB_PCB_ANGLEN)r   r   )r   r   r   r   r.   r.   r/   r      s    zHSExposureCA.__init__c             C   s\  | d k s | d k r d Sy4 | d j  ƒ  } | d j  ƒ  } | d j  ƒ  } Wn t k
 rh d SYn X| | } | | } | j ƒ  | j ƒ  | | }	 |	 j ƒ  |  j j | |	 | f ƒ | j d ƒ r| d j  ƒ  }
 |
 | } | j ƒ  | j |	 ƒ } nN | j ƒ  d k rL|  j | ƒ } | d k r:d } qR| j |	 ƒ } n d } |	 | f S)ap  Calculate approx CA-CB direction (PRIVATE).

        Calculate the approximate CA-CB direction for a central
        CA atom based on the two flanking CA positions, and the angle
        with the real CA-CB vector.

        The CA-CB vector is centered at the origin.

        :param r1, r2, r3: three consecutive residues
        :type r1, r2, r3: L{Residue}
        Nr
   ÚCBÚGLY)	r   r3   Ú	normalizer   r   r   r   Úget_resnamer4   )r   r#   r$   r%   Úca1r'   Zca3Zd1Zd3ÚbÚcbZcb_car   r.   r.   r/   r   ¦   s6    	







	zHSExposureCA._get_cbz	hs_exp.pyc             C   s  |  j  s t j d t ƒ d St | d ƒ Þ } | j d ƒ | j d ƒ | j d ƒ | j d ƒ | j d d ƒ xu |  j  D]j \ } } | j ƒ  \ } } } | j d
 | | | f ƒ | j ƒ  \ } } } | j d
 | | | f ƒ q~ W| j d ƒ | j d ƒ Wd QRXd S)zòWrite PyMol script for visualization.

        Write a PyMol script that visualizes the pseudo CB-CA directions
        at the CA coordinates.

        :param filename: the name of the pymol script file
        :type filename: string
        zNothing to draw.NÚwzfrom pymol.cgo import *
zfrom pymol import cmd
zobj=[
zBEGIN, LINES,
zCOLOR, %.2f, %.2f, %.2f,
ç      ð?zVERTEX, %.2f, %.2f, %.2f,
zEND]
zcmd.load_cgo(obj, 'HS')
)rC   rC   rC   )r   ÚwarningsÚwarnÚRuntimeWarningÚopenÚwriteZ	get_array)r   ÚfilenameÚfpÚcarA   ÚxÚyÚzr.   r.   r/   Úpcb_vectors_pymolÔ   s     		zHSExposureCA.pcb_vectors_pymolN)r5   r6   r7   r8   r   r   rO   r.   r.   r.   r/   r9   ‰   s   .r9   c               @   s4   e  Z d  Z d Z d d d d „ Z d d „  Z d S)	ÚHSExposureCBz7Class to calculate HSE based on the real CA-CB vectors.r:   r   c             C   s    t  j |  | | | d d ƒ d S)az  Initialize class.

        :param model: the model that contains the residues
        :type model: L{Model}

        :param radius: radius of the sphere (centred at the CA atom)
        :type radius: float

        :param offset: number of flanking residues that are ignored
                       in the calculation of the number of neighbors
        :type offset: int
        ZEXP_HSE_B_UZEXP_HSE_B_DN)r   r   )r   r   r   r   r.   r.   r/   r   ò   s    zHSExposureCB.__init__c             C   su   | j  ƒ  d k r% |  j | ƒ d f S| j d ƒ rq | j d ƒ rq | d j ƒ  } | d j ƒ  } | | d f Sd S)z˜Calculate CB-CA vector (PRIVATE).

        :param r1, r2, r3: three consecutive residues (only r2 is used)
        :type r1, r2, r3: L{Residue}
        r<   g        r;   r
   N)r>   r4   r   r   )r   r#   r$   r%   ZvcbZvcar.   r.   r/   r     s    zHSExposureCB._get_cbN)r5   r6   r7   r8   r   r   r.   r.   r.   r/   rP   ï   s   rP   c               @   s(   e  Z d  Z d Z d d d d „ Z d S)Ú
ExposureCNz:Residue exposure as number of CA atoms around its CA atom.g      (@r   c             C   sÌ  | d k s t  ‚ t ƒ  } | j | ƒ } i  } g  } g  } xs| D]k}	 xbt d t |	 ƒ ƒ D]K}
 d } |	 |
 } t | ƒ s_ | j d ƒ r• q_ | d } x§ | D]Ÿ } x– t d t | ƒ ƒ D] } |	 | k rí t |
 | ƒ | k rí qÂ | | } t | ƒ sÂ | j d ƒ rqÂ | d } | | } | | k  rÂ | d 7} qÂ Wq¦ W| j ƒ  } | j	 ƒ  j ƒ  } | | | | f <| j
 | | f ƒ | j
 | | f ƒ | | j d <q_ WqC Wt j |  | | | ƒ d S)aV  Initialize.

        A residue's exposure is defined as the number of CA atoms around
        that residues CA atom. A dictionary is returned that uses a L{Residue}
        object as key, and the residue exposure as corresponding value.

        :param model: the model that contains the residues
        :type model: L{Model}

        :param radius: radius of the sphere (centred at the CA atom)
        :type radius: float

        :param offset: number of flanking residues that are ignored in
                       the calculation of the number of neighbors
        :type offset: int

        r   r
   r	   ZEXP_CNN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r    Zfs_mapZfs_listZfs_keysr!   r"   Úfsr#   r?   r(   r)   r$   r'   r+   r,   r-   r.   r.   r/   r     s>    	

"


zExposureCN.__init__N)r5   r6   r7   r8   r   r.   r.   r.   r/   rQ     s   rQ   )r8   Ú
__future__r   rD   Úmathr   ZBio.PDB.AbstractPropertyMapr   ZBio.PDB.Polypeptider   r   ZBio.PDB.vectorsr   r   r9   rP   rQ   r.   r.   r.   r/   Ú<module>   s   uf$