o
    Rŀg%                     @   sn   d Z ddlZddlmZ ddlmZ ddlmZ dZ	ddd	Z
G d
d dZdd Zdd ZG dd dZdS )a  Classify protein backbone structure with Kolodny et al's fragment libraries.

It can be regarded as a form of objective secondary structure classification.
Only fragments of length 5 or 7 are supported (ie. there is a 'central'
residue).

Full reference:

Kolodny R, Koehl P, Guibas L, Levitt M.
Small libraries of protein fragments model native protein structures accurately.
J Mol Biol. 2002 323(2):297-307.

The definition files of the fragments can be obtained from:

http://github.com/csblab/fragments/

You need these files to use this module.

The following example uses the library with 10 fragments of length 5.
The library files can be found in directory 'fragment_data'.

    >>> from Bio.PDB.PDBParser import PDBParser
    >>> from Bio.PDB.FragmentMapper import FragmentMapper
    >>> parser = PDBParser()
    >>> structure = parser.get_structure("1a8o", "PDB/1A8O.pdb")
    >>> model = structure[0]
    >>> fm = FragmentMapper(model, lsize=10, flength=5, fdir="PDB")
    >>> chain = model['A']
    >>> res152 = chain[152]
    >>> res157 = chain[157]
    >>> res152 in fm # is res152 mapped? (fragment of a C-alpha polypeptide)
    False
    >>> res157 in fm # is res157 mapped? (fragment of a C-alpha polypeptide)
    True

    N)PDBException)	PPBuilder)SVDSuperimposerzlib_%s_z_%s.txt.c                 C   s   |d t  | |f }t|L}g }d}|D ]<}|d dks#|d dkr$q| }|d dkr=t||}	||	 |d7 }qtdd |dd	 D }
|	d
|
 qW d   |S 1 s]w   Y  |S )a  Read a fragment spec file (PRIVATE).

    Read a fragment spec file available from
    http://github.com/csblab/fragments/
    and return a list of Fragment objects.

    :param size: number of fragments in the library
    :type size: int

    :param length: length of the fragments
    :type length: int

    :param dir: directory where the fragment spec files can be found
    :type dir: string
    /r   *
   z------c                 S   s   g | ]}t |qS  )float).0xr
   r
   J/var/www/html/myenv/lib/python3.10/site-packages/Bio/PDB/FragmentMapper.py
<listcomp>[   s    z#_read_fragments.<locals>.<listcomp>   XXXN)_FRAGMENT_FILEopensplitFragmentappendnparrayadd_residue)sizelengthdirfilenamefpflistfidlineslfcoordr
   r
   r   _read_fragments9   s(   



r%   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )r   z)Represent a polypeptide C-alpha fragment.c                 C   s.   || _ d| _g | _t|dfd| _|| _dS )zInitialize fragment object.

        :param length: length of the fragment
        :type length: int

        :param fid: id for the fragment
        :type fid: int
        r   r   dN)r   counterresname_listr   zeros	coords_car    )selfr   r    r
   r
   r   __init__d   s
   

zFragment.__init__c                 C      | j S )zcGet residue list.

        :return: the residue names
        :rtype: [string, string,...]
        )r(   r+   r
   r
   r   get_resname_listv      zFragment.get_resname_listc                 C   r-   )zcGet identifier for the fragment.

        :return: id for the fragment
        :rtype: int
        )r    r.   r
   r
   r   get_id~   r0   zFragment.get_idc                 C   r-   )zGet the CA coordinates in the fragment.

        :return: the CA coords in the fragment
        :rtype: NumPy (Nx3) array
        )r*   r.   r
   r
   r   
get_coords   r0   zFragment.get_coordsc                 C   s<   | j | jkr
td| j| || j| j < | j d | _ dS )zAdd a residue.

        :param resname: residue name (eg. GLY).
        :type resname: string

        :param ca_coord: the c-alpha coordinates of the residues
        :type ca_coord: NumPy array with length 3
        zFragment boundary exceeded.r	   N)r'   r   r   r(   r   r*   )r+   resnameca_coordr
   r
   r   r      s
   	zFragment.add_residuec                 C   r-   )zReturn length of the fragment.)r   r.   r
   r
   r   __len__   s   zFragment.__len__c                 C   s&   t  }|| j|j |  | S )zReturn rmsd between two fragments.

        :return: rmsd between fragments
        :rtype: float

        Examples
        --------
        This is an incomplete but illustrative example::

            rmsd = fragment1 - fragment2

        )r   setr*   runget_rms)r+   othersupr
   r
   r   __sub__   s   zFragment.__sub__c                 C   s   d| j | jf S )zRepresent the fragment object as a string.

        Returns <Fragment length=L id=ID> where L=length of fragment
        and ID the identifier (rank in the library).
        z<Fragment length=%i id=%i>)r   r    r.   r
   r
   r   __repr__   s   zFragment.__repr__N)__name__
__module____qualname____doc__r,   r/   r1   r2   r   r5   r;   r<   r
   r
   r
   r   r   a   s    r   c           
      C   s   g }t t| | d D ]=}t|d}t |D ],}| ||  }| }|dr-|d }ntd| r9td| }	|||	 q|	| q|S )zDice up a peptide in fragments of length "length" (PRIVATE).

    :param pp: a list of residues (part of one peptide)
    :type pp: [L{Residue}, L{Residue}, ...]

    :param length: fragment length
    :type length: int
    r	   CA
CHAINBREAK)
rangelenr   get_resnamehas_idr   is_disordered	get_coordr   r   )
ppr   	frag_listir#   jresiduer3   car4   r
   r
   r   _make_fragment_list   s   	


rP   c           	      C   sd   g }| D ]+}g }t t|D ]}|| }|| }|||f q|  |d d }|| q|S )a  Map flist fragments to closest entry in reflist (PRIVATE).

    Map all frgaments in flist to the closest (in RMSD) fragment in reflist.

    Returns a list of reflist indices.

    :param flist: list of protein fragments
    :type flist: [L{Fragment}, L{Fragment}, ...]

    :param reflist: list of reference (ie. library) fragments
    :type reflist: [L{Fragment}, L{Fragment}, ...]
    r   r	   )rD   rE   r   sort)	r   reflistmappedr#   rankrL   rfrmsfragmentr
   r
   r   _map_fragment_list   s   rX   c                   @   s2   e Zd ZdZdddZdd Zd	d
 Zdd ZdS )FragmentMapperzAMap polypeptides in a model to lists of representative fragments.      r   c                 C   sZ   |dkrd| _ n|dkrd| _ ntd|| _|| _t|||| _|| _| | j| _dS )a  Create instance of FragmentMapper.

        :param model: the model that will be mapped
        :type model: L{Model}

        :param lsize: number of fragments in the library
        :type lsize: int

        :param flength: length of fragments in the library
        :type flength: int

        :param fdir: directory where the definition files are
                     found (default=".")
        :type fdir: string
        r[         r   z!Fragment length should be 5 or 7.N)	edger   flengthlsizer%   rR   model_mapfd)r+   ra   r`   r_   fdirr
   r
   r   r,      s   zFragmentMapper.__init__c                 C   s   t  }||}i }|D ]Z}z<t|| j}t|| j}tt|D ]'}|| }	|| jk r-q!|t|| j kr7q!|| j }
|
dksBJ ||
 ||	< q!W q t	yf } z|dkrWnt	|dW Y d}~qd}~ww |S )zjMap (PRIVATE).

        :param model: the model that will be mapped
        :type model: L{Model}
        r   rC   N)
r   build_peptidesrP   r_   rX   rR   rD   rE   r^   r   )r+   ra   ppbpplrc   rJ   r   mflistrL   resindexwhyr
   r
   r   rb     s2   



zFragmentMapper._mapc                 C   s
   || j v S )zeCheck if the given residue is in any of the mapped fragments.

        :type res: L{Residue}
        rc   r+   ri   r
   r
   r   __contains__4  s   
zFragmentMapper.__contains__c                 C   s
   | j | S )z{Get an entry.

        :type res: L{Residue}

        :return: fragment classification
        :rtype: L{Fragment}
        rl   rm   r
   r
   r   __getitem__;  s   
zFragmentMapper.__getitem__N)rZ   r[   r   )r=   r>   r?   r@   r,   rb   rn   ro   r
   r
   r
   r   rY      s    
$rY   )r   )r@   numpyr   Bio.PDB.PDBExceptionsr   Bio.PDB.Polypeptider   Bio.SVDSuperimposerr   r   r%   r   rP   rX   rY   r
   r
   r
   r   <module>   s   %
([