B
    b^U              !   @   s   d Z ddlZddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	dd
dddddddddddddddddddddddd d!d"d#d$d% Zd6d'd(Zd)d* Zd7d,d-Zd.d/ Zd0d1 Zd2d3 ZG d4d5 d5e
ZdS )8a  Calculation of residue depth using command line tool MSMS.

This module uses Michel Sanner's MSMS program for the surface calculation.
See: http://mgltools.scripps.edu/packages/MSMS

Residue depth is the average distance of the atoms of a residue from
the solvent accessible surface.

Residue Depth::

    from Bio.PDB.ResidueDepth import ResidueDepth
    from Bio.PDB.PDBParser import PDBParser
    parser = PDBParser()
    structure = parser.get_structure("1a8o", "Tests/PDB/1A8O.pdb")
    model = structure[0]
    rd = ResidueDepth(model)
    print(rd['A',(' ', 152, ' ')])

Direct MSMS interface, typical use::

    from Bio.PDB.ResidueDepth import get_surface
    surface = get_surface(model)

The surface is a Numeric array with all the surface vertices.

Distance to surface::

    from Bio.PDB.ResidueDepth import min_dist
    coord = (1.113, 35.393,  9.268)
    dist = min_dist(coord, surface)

where coord is the coord of an atom within the volume bound by
the surface (ie. atom depth).

To calculate the residue depth (average atom depth of the atoms
in a residue)::

    from Bio.PDB.ResidueDepth import residue_depth
    chain = model['A']
    res152 = chain[152]
    rd = residue_depth(res152, surface)

    N)	PDBParser)	Selection)AbstractPropertyMap)is_aa)BiopythonWarning)g=
ףp=?gffffff?gffffff?)gQ?gffffff?g?)gffffff?gp=
ף?g333333?)gffffff?gp=
ף?g?)gffffff?gp=
ף?g       @)gp=
ף?gףp=
?g       @)gq=
ףp?gףp=
?gףp=
?)gffffff?gףp=
?g(\?)gp=
ף?g?g?)gp=
ף?g?g?)gffffff?gp=
ף?gp=
ף?)gGz?g333333?g333333?)gffffff?g        g      ?)g      @g      @g      @)gףp=
?gQ?gQ?)g      ?gffffff?gffffff?)gQ?gffffff?gffffff?)g333333?g?g?)g(\?gףp=
?gףp=
?)g{Gz?g{Gz?g{Gz?)gGz?g333333?g        )g(\?gףp=
?gףp=
?)g(\?g?g?)gQ?gףp=
?gףp=
?)g(\?g      ?g      ?)gQ?g333333@g333333@)g      @g      @g      @)gffffff?gffffff?gffffff?)gffffff?g?g?)                         	   
                                                                  &   unitedc             C   s  |dkrd}n|dkrd}nt d| | jj}| jjd }| j}| j}|dksX|dkrdtd	 | S |d
kr|dkrtd | S |dkr|dkrtd | S |dkr|dkrtd | S |dkr|dkrtd | S |dk rtd | S |dkr td | S |dkrtd | S |dkr,td | S |dkrBtd | S |dkrb|dkrbtd | S |dkr|dkrtd | S |dkrtd | S |dkr|dkrtd | S |dkr|d krtd | S |dkrtd | S |d!kr|dkrtd" | S |dkr.|d#kr.td | S |d$krN|dkrNtd | S |d$krn|d%krntd | S |d$kr|d&krtd | S |d$kr|d'rtd( | S |d)kr|d*krtd | S |d)kr|d+krtd( | S |d)kr|d,rtd" | S |d-kr4|d.r4td" | S |d/krV|d*rVtd | S |d/krv|d+krvtd" | S |d/kr|d0rtd" | S |d1kr|d2krtd | S |d3kr|d4rtd | S |d5kr|d2krtd6 | S |d7kr|d8rtd" | S |d9kr<|dkr<td | S |d!kr\|d:kr\td | S |d!kr||d;kr|td( | S |d<kr|d=rtd" | S |d>kr|d?krtd@ | S |dAkr|dBkrtdC | S |dDkr|dEkrtd | S |dFkr|dGkrtd | S |dHkr>|dGkr>tdC | S |dIkr`|dJr`td | S |dKkr|dLkrtd | S |dKkr|dMkrtd | S |dKkr|dNkrtd | S |d kr|drtd | S |dOkr|dPkrtd | S |dOkr"|dQkr"tdR | S |dSkrB|dTkrBtd | S |dSkrb|dUkrbtd | S |dVkr|dWrtd@ | S |dXkr|dYkrtd | S |dZkr|d[krtd | S |dZkr|d\rtd" | S |d]kr|d^krtd | S |d_kr&|d`kr&td | S |d_krF|dMkrFtd | S |dakrf|dbkrftd@ | S |dakr|dckrtd | S |dakr|ddkrtd | S |dakr|dekrtd@ | S |dfkr|dgkrtd@ | S |dfkr|d&krtd | S |dfkr&|dhkr&td | S |dikrF|djkrFtd | S |dkkr\td | S |dlkr|dmr|dnrtdo | S |dlkr|dpr|dnrtd | S |dqkr|drkrtd | S |dskr|dtkrtdo | S |duk	r|dvk	rtd | S |duk	r8|dmk	r8tdo | S |duk	rX|dwk	rXtd@ | S |duk	rx|dxk	rxtdC | S |duk	r|dyk	rtd | S |duk	r|dzk	rtd | S |duk	r|d{k	rtd | S |d|k	r|d}k	rtdC | S |d~k
r|dk
rtd | S |d~k
r8|dk
r8td | S |d~k
rX|dk
rXtd | S |d~k
rx|dk
rxtd | S |d~k
r|dk
rtd | S |dk
r|dpk
rtd | S |dk
r|dk
rtd" | S |dk
r|dk
rtd" | S |dkr|dkrtd | S |dkr8|dkr8td | S |dkrX|dkrXtd | S |dkrx|dkrxtdC | S |dkr|dkrtd | S |dkr|dkrtd | S |dkr|dkrtd | S |dkr|dkrtd | S |dkr|dkrtd | S |dkr8|dkr8tdC | S |dkrX|dkrXtd@ | S |dkrx|dkrxtd | S |dkr|drtd | S |dkr|drtd | S |dkr|drtd" | S |dkr|dkrtd" | S |dkr|dkrtd" | S |dkr>|dkr>td | S |dkr^|dkr^td | S |dkr~|dkr~td | S |dkr|drtd | S |dkrtd | S |dkrtd | S |dkrtd | S |dmkrtd | S |dkrtd | S |dkr$td | S |dkr:td | S |dkrPtd | S |dkrftd | S |dkr|td" | S |drtd" | S |dprtd | S |drtd | S |drtd@ | S |drtd | S |drtd | S |dr$tdR | S |dkr:td | S |drRtd | S |dkrt|drttd | S |dkr|drtd | S |dkr|drtd | S |dkr|drtd | S |dkr|drtd	 | S t	
| d| dt dS dS )a&  Translate an atom object to an atomic radius defined in MSMS (PRIVATE).

    Uses information from the parent residue and the atom object to define
    the atom type.

    Returns the radius (float) according to the selected type:
     - explicit (reads hydrogens)
     - united (default)

    Zexplicitr   r'   r   z?Radius type (%r) not understood. Must be 'explicit' or 'united'r   HDr   WO CAr   CDr   ZACEr   Nr
   r   Cr   Pr   ZCBZALA>   THRILEVALr   CG>   TYRLEUASPHISLHISNTRPHIDHIPASNPHEHIEHISASXr7   GLNr	   ZCH3ZARG>   RENECZ)ZNHZRHr   r>   ZOD1ZND2ADr8   )ODZEDrB   )rH   rG   >   CYXCYMCYSZSG>   rK   METZLPZCUHr   GLU)ZOEZEE>   rC   rM   GLXZOE1NE2>   rC   rN   AE>   r9   r<   r=   r@   rA   >   CD2CE1r   >   r9   r<   r@   rA   ND1r   >   r<   r=   >   rS   RD1>   rA   r@   r=   >   rO   RE2>   r<   r9   >   r9   r<   rA   r=   )rG   rP   r3   CG1CG2>   r.   CD1ZLYS>   r5   r.   CE>   NZKZr   rL   ZSDrY   r?   )r.   rY   rF   ZPRO>   r5   r.   ZCSO>   SEGSErH   ZSERZOGr2   ZOG1r;   rX   >   CE2rQ   ZNE1>   CZ2CZ3CH2CE3r6   >   r^   rQ   rX   rR   ZOHr4   >   rW   rV   >   r.   >   FS3FS4ZFE)1234567r   Src   ZOXOZFEO>   FE1FE2ZHEM>   O1O2>   CABCHBCBCCHCCACCBBCHDCHA>   N BN AN CNBNAN DNCND>   C4CC3DC1ACGAC2BC3AC3BC1BC1DC2DC3CCGDC2CC4DC2AC4AC1CC4B>   CMDCMACMCCMBZOH2ZAZI>   N2N1N3ZMPD>   C6C5C1C2C3C4>   O7O8>   SO4SUL>   PO4r   PHOr   >   O4ro   rp   O3zPC ZP1>   r   r   >   r   r   r   r   ZBIGZBALr   >   DOTPOIr   ZFMN>   N10r   N5>   C7C8r   r   C10C5Ar   C9A>   r   rp   r   >   r   C9>   C8MC7M)r   r   r   r   r   )rp   r   r   ZO5>   OP2OP1OP3>   ALKMYRZOT1ZC01r   ZC16r   ZC14ZCUr   ZZNr   ZMNr!   r   ZMGr    ZCOr"   r]   r#   ZYBr%   r\   ZOXT)ZOTEA)r/   RK>   PBPDPCPA>   FADAMXNADAPU:z not in radii library.g{Gz?N)
ValueErrorparentresnameidnameelement_atomic_radii
startswithendswithwarningswarnr   )atomrtypeZtypekeyr   Zhet_atmZat_nameZat_elem r   3lib/python3.7/site-packages/Bio/PDB/ResidueDepth.py_get_atom_radiusn   s0   
























r   c          	   C   sf   t | N}g }xB|D ]:}| }t|dkr.qdd |dd D }|| qW W dQ R X t|S )z4Read the vertex list into a Numeric array (PRIVATE).r   c             S   s   g | ]}t |qS r   )float).0xr   r   r   
<listcomp>  s    z&_read_vertex_array.<locals>.<listcomp>r   r	   N)opensplitlenappendnumpyZarray)filenamefpZvertex_listlZslZvlr   r   r   _read_vertex_array  s    

r   msmsc             C   s   t | d}t }t|dV}xN|D ]F}|j\}}}t|dd}	||dd|dd|dd|	dd q&W W d	Q R X t }
|d
 t  }|||
f }tj	|dd |
d }t
j|std| t|}|S )zRepresent molecular surface as a vertex list array.

    Return a Numpy array that represents the vertex list of the
    molecular surface.

    Arguments:
     - MSMS - msms executable (used as argument to subprocess.call)

    r   wr'   )r   z6.3f	z1.2f
Nz# -probe_radius 1.5 -if %s -of %s > T)shellz.vertz1Failed to generate surface file using command:
%s)r   unfold_entitiestempfileZmktempr   coordr   write
subprocessZcallospathisfileRuntimeErrorr   )modelMSMS	atom_listZxyz_tmpZpdb_to_xyzrr   r   yzZradiusZsurface_tmpZmake_surfaceZsurface_filesurfacer   r   r   get_surface  s"    
8
r   c             C   s&   ||  }t || d}t t|S )z2Return minimum distance between coord and surface.r   )r   sumZsqrtmin)r   r   dZd2r   r   r   min_dist#  s    r   c             C   s@   |   }t|}d}x"|D ]}| }|t|| }qW || S )zResidue depth as average depth of all its atoms.

    Return average distance to surface for all atoms in a residue,
    ie. the residue depth.
    r   )Zget_unpacked_listr   	get_coordr   )residuer   r   lengthr   r   r   r   r   r   residue_depth*  s    
r   c             C   s(   |  dsdS | d }| }t||S )zReturn CA depth.r-   N)Zhas_idr   r   )r   r   Zcar   r   r   r   ca_depth9  s
    
r   c               @   s   e Zd ZdZdddZdS )ResidueDepthz0Calculate residue and CA depth for all residues.Nc             C   s   |dkrd}i }g }g }t |d}t||d}x|D ]z}t|sDq6t||}	t||}
| }|  }|	|
f|||f< |||	|
ff |||f |	|j	d< |
|j	d< q6W t
| ||| dS )zInitialize the class.Nr   r   )r   ZEXP_RDZ	EXP_RD_CA)r   r   r   r   r   r   Zget_idZ
get_parentr   Zxtrar   __init__)selfr   Z	msms_execZ
depth_dictZ
depth_listZ
depth_keysZresidue_listr   r   ZrdZca_rdZres_idZchain_idr   r   r   r  E  s(    



zResidueDepth.__init__)N)__name__
__module____qualname____doc__r  r   r   r   r   r  B  s   r  )r'   )r   )r  r   r   r   r   r   ZBio.PDBr   r   ZBio.PDB.AbstractPropertyMapr   ZBio.PDB.Polypeptider   ZBior   r   r   r   r   r   r   r   r  r   r   r   r   <module>3   sh   
   
%	