B
    bP                 @   s6  d Z ddlZddlZddlm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 ed	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*d'd+d,d-d.d/d0d1dd2d3d4d5d6d7dd8d9d:d;d<d=d(d>d?d@dAdBd@ddCZdDdE ZdOdGdHZdIdJ ZdKdL ZG dMdN dNeZdS )Pa\	  Use the DSSP program to calculate secondary structure and accessibility.

You need to have a working version of DSSP (and a license, free for academic
use) in order to use this. For DSSP, see http://swift.cmbi.ru.nl/gv/dssp/.

The following Accessible surface area (ASA) values can be used, defaulting
to the Sander and Rost values:

    Miller
        Miller et al. 1987 https://doi.org/10.1016/0022-2836(87)90038-6
    Sander
        Sander and Rost 1994 https://doi.org/10.1002/prot.340200303
    Wilke
        Tien et al. 2013 https://doi.org/10.1371/journal.pone.0080635

The DSSP codes for secondary structure used here are:

    =====     ====
    Code      Structure
    =====     ====
     H        Alpha helix (4-12)
     B        Isolated beta-bridge residue
     E        Strand
     G        3-10 helix
     I        Pi helix
     T        Turn
     S        Bend
     \-       None
    =====     ====

Usage
-----
The DSSP class can be used to run DSSP on a PDB or mmCIF file, and provides a
handle to the DSSP secondary structure and accessibility.

**Note** that DSSP can only handle one model, and will only run
calculations on the first model in the provided PDB file.

Examples
--------
Typical use::

    from Bio.PDB import PDBParser
    from Bio.PDB.DSSP import DSSP
    p = PDBParser()
    structure = p.get_structure("1MOT", "/local-pdb/1mot.pdb")
    model = structure[0]
    dssp = DSSP(model, "/local-pdb/1mot.pdb")

Note that the recent DSSP executable from the DSSP-2 package was
renamed from ``dssp`` to ``mkdssp``. If using a recent DSSP release,
you may need to provide the name of your DSSP executable::

    dssp = DSSP(model, '/local-pdb/1mot.pdb', dssp='mkdssp')

DSSP data is accessed by a tuple - (chain id, residue id)::

    a_key = list(dssp.keys())[2]
    dssp[a_key]

The dssp data returned for a single residue is a tuple in the form:

    ============ ===
    Tuple Index  Value
    ============ ===
    0            DSSP index
    1            Amino acid
    2            Secondary structure
    3            Relative ASA
    4            Phi
    5            Psi
    6            NH-->O_1_relidx
    7            NH-->O_1_energy
    8            O-->NH_1_relidx
    9            O-->NH_1_energy
    10           NH-->O_2_relidx
    11           NH-->O_2_energy
    12           O-->NH_2_relidx
    13           O-->NH_2_energy
    ============ ===

    N)StringIO)AbstractResiduePropertyMap)PDBException)	PDBParser)three_to_one)
MMCIF2Dictz[a-z]g     @\@g      n@g     c@g     b@g     a@g     g@g     f@g     @U@g     @h@g     f@g     f@g     `j@g     i@g     @k@g     a@g     ^@g     @b@g     0p@g     l@g      d@)ZALAZARGZASNZASPZCYSZGLNZGLUZGLYZHISZILEZLEUZLYSZMETZPHEZPROZSERZTHRZTRPZTYRZVALg      `@g      q@g     `h@g      h@g     d@g      l@g     k@g      Z@g      l@g     h@g      i@g     m@g      n@g     c@g     `c@g     e@g     q@g     pp@g     e@g     Z@g      o@g     c@g     `d@g     `@g     h@g      U@g      g@g      e@g     d@g     i@g     g@g      a@g     @`@g     a@g     `l@g     k@)ZMillerZWilkeSanderc             C   s0   | dkrdS | dkrdS | dkr$dS ds,t dS )zBSecondary structure symbol to index.

    H=0
    E=1
    C=2
    Hr   E   C   N)AssertionError)ss r   +lib/python3.7/site-packages/Bio/PDB/DSSP.pyss_to_index   s    r   dsspc          	   C   s   yt j|| gdt jt jd}W n8 tk
rV   |dkr8 t jd| gdt jt jd}Y nX | \}}| rt| | stdt	t
|\}}||fS )a  Create a DSSP dictionary from a PDB file.

    Parameters
    ----------
    in_file : string
        pdb file

    DSSP : string
        DSSP executable (argument to subprocess)

    Returns
    -------
    (out_dict, keys) : tuple
        a dictionary that maps (chainid, resid) to
        amino acid type, secondary structure code and
        accessibility.

    Examples
    --------
    How dssp_dict_frompdb_file could be used::

        from Bio.PDB.DSSP import dssp_dict_from_pdb_file
        dssp_tuple = dssp_dict_from_pdb_file("/local-pdb/1fat.pdb")
        dssp_dict = dssp_tuple[0]
        print(dssp_dict['A',(' ', 1, ' ')])

    T)Zuniversal_newlinesstdoutstderrmkdsspz DSSP failed to produce an output)
subprocessPopenPIPEFileNotFoundErrorZcommunicatestripwarningswarn	Exception_make_dssp_dictr   )in_fileDSSPpouterrZout_dictkeysr   r   r   dssp_dict_from_pdb_file   s*    !
r&   c          	   C   s   t | 
}t|S Q R X dS )zDSSP dictionary mapping identifiers to properties.

    Return a DSSP dictionary that maps (chainid, resid) to
    aa, ss and accessibility, from a DSSP file.

    Parameters
    ----------
    filename : string
        the DSSP output file

    N)openr   )filenamehandler   r   r   make_dssp_dict  s    
r*   c             C   s   i }d}g }x| D ]}|  }t|dk r0q|d dkrBd}q|sHq|d dkrVqt|dd }t|dd	 }|d	 }|d
 }	|d }
|d }|dkrd}yt|dd }t|dd }t|dd }t|dd }t|dd }t|dd }t|dd }t|dd }t|dd }t|dd }t|dd }W nZ tk
r } z8|d dkr|dd d}t|d| d|  }t|d| d|  }t|d| d|  }t|d| d|  }t|d| d|  }t|d| d|  }t|d| d|  }t|d| d|  }t|d| d|  }t|d| d|  }t|d| d|  }n
t|dW dd}~X Y nX d||f}|
|||||||||||||f||	|f< ||	|f qW ||fS )a  Return a DSSP dictionary, used by mask_dssp_dict (PRIVATE).

    DSSP dictionary maps (chainid, resid) to an amino acid,
    secondary structure symbol, solvent accessibility value, and hydrogen bond
    information (relative dssp indices and hydrogen bond energies) from an open
    DSSP file object.

    Parameters
    ----------
    handle : file
        the open DSSP output file handle

    r   r   r   ZRESIDUE	    N   
            -&   -   .   2   8   9   =   C   D   H   N   O   S   "   g   m   s   )splitlenintfloat
ValueErrorfindappend)r)   r   startr%   lZsl
dssp_indexZresseqZicodeZchainidaar   NH_O_1_relidxNH_O_1_energyO_NH_1_relidxO_NH_1_energyNH_O_2_relidxNH_O_2_energyO_NH_2_relidxO_NH_2_energyaccphipsiexcshiftres_idr   r   r   r     s    
r   c               @   s   e Zd ZdZdddZdS )	r!   ac  Run DSSP and parse secondary structure and accessibility.

    Run DSSP on a PDB/mmCIF file, and provide a handle to the
    DSSP secondary structure and accessibility.

    **Note** that DSSP can only handle one model.

    Examples
    --------
    How DSSP could be used::

        from Bio.PDB import PDBParser
        from Bio.PDB.DSSP import DSSP
        p = PDBParser()
        structure = p.get_structure("1MOT", "/local-pdb/1mot.pdb")
        model = structure[0]
        dssp = DSSP(model, "/local-pdb/1mot.pdb")
        # DSSP data is accessed by a tuple (chain_id, res_id)
        a_key = list(dssp.keys())[2]
        # (dssp index, amino acid, secondary structure, relative ASA, phi, psi,
        # NH_O_1_relidx, NH_O_1_energy, O_NH_1_relidx, O_NH_1_energy,
        # NH_O_2_relidx, NH_O_2_energy, O_NH_2_relidx, O_NH_2_energy)
        dssp[a_key]

    r   r    c       +      C   s|  t | | _ |dkr*tj|d dd }| }|dkr>d}|dksNtd|dks^|dkryt||\}}W n2 tk
r   |d	krd
}n|d
krd	}n Y nX t||\}}n|dkrt|\}}i }g }	dd }
|dkr$t	|}i }x0t
|d D ] \}}||kr|d | ||< qW g }x2|D ](}|\}}|dkrZ|| }|||f || }y|| }W n^ tk
r   |
|}x>|D ],}|jd dkr|
|j|kr|}P qW t|dY nX | dkr4x| D ]6}|j|  d  }|tdkr|| P qW || d  n| dkrdd | D }|dr|
|}xN|D ]F}|jd dkrn|
|j|krn| d  tdkrn|}P qnW || \}}}}}}} }!}"}#}$}%}&}'||jd< ||jd< ||jd< ||jd< ||jd< | |jd< |!|jd< |"|jd< |#|jd< |$|jd< |%|jd < |&|jd!< |'|jd"< | }(y|| j |(  })W n tk
r   d#})Y nX |)d$krd$})|)|jd%< yt|(}(W n tk
r   d&}(Y nX |(d'krt|rd'}|(|kr|jd d(ks|d&krtd)| ||||)||| |!|"|#|$|%|&|'f}*|*|||f< |	|* q,W |dkrh|}t| |||	 dS )*a  Create a DSSP object.

        Parameters
        ----------
        model : Model
            The first model of the structure
        in_file : string
            Either a PDB file or a DSSP file.
        dssp : string
            The dssp executable (ie. the argument to subprocess)
        acc_array : string
            Accessible surface area (ASA) from either Miller et al. (1987),
            Sander & Rost (1994), or Wilke: Tien et al. 2013, as string
            Sander/Wilke/Miller. Defaults to Sander.
        file_type: string
            File type switch: either PDB, MMCIF or DSSP. Inferred from the
            file extension by default.

        r]   r   NZCIFMMCIF)PDBr^   r!   z$File type must be PDB, mmCIF or DSSPr_   r   r   r!   c             S   s   d| d | d f S )z;Serialize a residue's resseq and icode for easy comparison.z%s%sr   r   r   )r\   r   r   r   
resid2code  s    z!DSSP.__init__.<locals>.resid2codez_atom_site.label_asym_idz_atom_site.auth_asym_idr   )r,   Wr   zA1 c             S   s   h | ]}|  qS r   )
get_altloc).0ar   r   r   	<setcomp>  s    z DSSP.__init__.<locals>.<setcomp>ZSS_DSSPZEXP_DSSP_ASAZPHI_DSSPZPSI_DSSPZ
DSSP_INDEXZNH_O_1_RELIDX_DSSPZNH_O_1_ENERGY_DSSPZO_NH_1_RELIDX_DSSPZO_NH_1_ENERGY_DSSPZNH_O_2_RELIDX_DSSPZNH_O_2_ENERGY_DSSPZO_NH_2_RELIDX_DSSPZO_NH_2_ENERGY_DSSPZNAg      ?ZEXP_DSSP_RASAXr   r,   zStructure/DSSP mismatch at %s)residue_max_accospathsplitextupperr   r&   r   r*   r   	enumeraterJ   KeyErroridZis_disorderedZdisordered_get_id_listZ
child_dictZget_listrb   tupleZdisordered_selectZget_unpacked_list
isdisjointZxtraZget_resnamer   	_dssp_cysmatchr   r   __init__)+selfZmodelr    r   Z	acc_arrayZ	file_typeZ	dssp_dictZ	dssp_keysZdssp_mapZ	dssp_listr`   Z
mmcif_dictZmmcif_chain_dicticZdssp_mapped_keyskeyZchain_idr\   chainZresZres_seq_icoderZrkZaltlocZaltlocsrN   r   rW   rX   rY   rM   rO   rP   rQ   rR   rS   rT   rU   rV   ZresnameZrel_accZ	dssp_valsr   r   r   rs     s    





	
$

















$
zDSSP.__init__N)r   r   r]   )__name__
__module____qualname____doc__rs   r   r   r   r   r!   t  s   r!   )r   )r}   rerh   ior   r   r   ZBio.PDB.AbstractPropertyMapr   ZBio.PDB.PDBExceptionsr   ZBio.PDB.PDBParserr   ZBio.PDB.Polypeptider   ZBio.PDB.MMCIF2Dictr   compilerq   rg   r   r&   r*   r   r!   r   r   r   r   <module>Y   s   


=`