o
    RŀgN                     @   s   d 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lmZ dd	lmZ ed
Ze	Zdd Zdd ZdddZdd Zdd ZG dd deZdS )a	  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 https://swift.cmbi.umcn.nl/gv/dssp/.

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

    Ahmad
        Ahmad et al. 2003 https://doi.org/10.1002/prot.10328
    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)protein_letters_3to1)residue_sasa_scales)AbstractResiduePropertyMap)
MMCIF2Dict)PDBException)	PDBParserz[a-z]c                 C   s   t tt| dS )z2Parse semantic version scheme for easy comparison..)tuplemapintsplit)version_string r   @/var/www/html/myenv/lib/python3.10/site-packages/Bio/PDB/DSSP.pyversionr      r   c                 C   s(   | dkrdS | dkrdS | dkrdS J )zBSecondary structure symbol to index.

    H=0
    E=1
    C=2
    Hr   E   C   r   )ssr   r   r   ss_to_indexw   s   r   dssp3.9.9c           	   	   C   s   zt |t dk r|| g}n|d| g}tj|dtjtjd}W n+ tyJ   |dkr+ t |t dk r8d| g}ndd| g}tj|dtjtjd}Y nw | \}}| rbt| | sbt	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)

    dssp_version : string
        Version of DSSP executable

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

    Examples
    --------
    How dssp_dict_from_pdb_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, ' ')])

    4.0.0z--output-format=dsspT)universal_newlinesstdoutstderrmkdsspz DSSP failed to produce an output)r   
subprocessPopenPIPEFileNotFoundErrorcommunicatestripwarningswarn	Exception_make_dssp_dictr   )	in_fileDSSPdssp_versionDSSP_cmdpouterrout_dictkeysr   r   r   dssp_dict_from_pdb_file   s<   $






r4   c                 C   s4   t | }t|W  d   S 1 sw   Y  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   
$r8   c                 C   s  i }d}g }| D ]n}|  }t|dk rq|d dkrd}q|s"q|d dkr)qt|dd }t|dd	 }|d	 }|d
 }	|d }
|d }|dkrOd}zZt|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 n tyV } z|d dkrG|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 Y d}~nd}~ww d||f}|
|||||||||||||f||	|f< ||	|f q||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   RESIDUE	    N   
            -&   -   .   2   8   9   =   C   D   H   N   O   S   "   g   m   s   )r   lenr   float
ValueErrorfindappend)r7   r   startr3   linesl
dssp_indexresseqicode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   Sander c           -      C   s  t | | _ |dkrtj|d dd }| }|dkrd}|dv s'J d|dks/|dkr~ztj|d	gd
d}td|	d}t
|||\}}	W n< ty}   |dkrYd}n|dkr`d}n tj|d	gd
d}td|	d}t
|||\}}	Y nw |dkrt|\}}	i }
g }dd }|dkrt|tdk rt|}i }t|d D ]\}}||vr|d | ||< qg }|	D ]}|\}}|dkrt|tdk r|| }|||f || }z|| }W n, ty   ||}|D ]}|jd dvr	||j|kr	|} nqt|dY nw | dkrD| D ]}|j|  d  }|tdv r8||  nq|| d  nA| dkrdd | D }|dr||}|D ]$}|jd dvr||j|kr| d  tdv r|} nq`|| \}}}}} }!}"}#}$}%}&}'}(})||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'< | }*z	|| j |*  }+W n ty   d(}+Y nw |+d)krd)}+|+|jd*< t|*d+}*|*d,krt !|rd,}|*|kr*|jd d-ks#|d+kr*t"d.| |!|||+|| |"|#|$|%|&|'|(|)f},|,|
||f< ||, q|dkrVt|tdk rV|}	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), Wilke: Tien et al. 2013, or Ahmad et al.
            (2003) as string Sander/Wilke/Miller/Ahmad. Defaults to Sander.
        file_type: string
            File type switch: either PDB, MMCIF or DSSP. Inferred from the
            file extension by default.

        ro   r   NCIFMMCIF)PDBrq   r,   z$File type must be PDB, mmCIF or DSSPrr   z	--versionT)textz\s*([\d.]+)r   r    r,   c                 S   s   | d  | d  S )z;Serialize a residue's resseq and icode for easy comparison.r   r   r   )rm   r   r   r   
resid2code  r   z!DSSP.__init__.<locals>.resid2coder   z_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>SS_DSSPEXP_DSSP_ASAPHI_DSSPPSI_DSSP
DSSP_INDEXNH_O_1_RELIDX_DSSPNH_O_1_ENERGY_DSSPO_NH_1_RELIDX_DSSPO_NH_1_ENERGY_DSSPNH_O_2_RELIDX_DSSPNH_O_2_ENERGY_DSSPO_NH_2_RELIDX_DSSPO_NH_2_ENERGY_DSSPNAg      ?EXP_DSSP_RASAXr   r;   zStructure/DSSP mismatch at )%residue_max_accospathsplitextupperr!   check_outputresearchgroupr4   r$   r8   r   r   	enumeraterW   KeyErroridis_disordereddisordered_get_id_list
child_dictget_listrv   r
   disordered_selectget_unpacked_list
isdisjointxtraget_resnamer   get	_dssp_cysmatchr   r   __init__)-selfmodelr+   r   	acc_array	file_typer   r-   	dssp_dict	dssp_keysdssp_map	dssp_listrt   
mmcif_dictmmcif_chain_dicticdssp_mapped_keyskeychain_idrm   chainresres_seq_icoderrkaltlocaltlocsr_   r   rh   ri   rj   r[   r`   ra   rb   rc   rd   re   rf   rg   resnamerel_acc	dssp_valsr   r   r   r   Z  s&  




	
















$zDSSP.__init__N)r   rn   ro   )__name__
__module____qualname____doc__r   r   r   r   r   r,   ?  s    r,   )r   r   )r   r   r   r!   r'   ior   Bio.Data.PDBDatar   r   Bio.PDB.AbstractPropertyMapr   Bio.PDB.MMCIF2Dictr   Bio.PDB.PDBExceptionsr   Bio.PDB.PDBParserr   compiler   r   r   r   r4   r8   r*   r,   r   r   r   r   <module>   s(   U

H`