
:>"^%                 @   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	 d Z
 d d	 d
  Z Gd d   d e  Z d d   Z d d   Z Gd d   d e  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

    )print_functionN)SVDSuperimposer)PDBException)	PPBuilderzlib_%s_z_%s.txt.c             C   s   | d t  |  | f } t | d   } g  } d } x | j   D] } | d d k sC | d d k rl qC | j   } | d d k r t | |  }	 | j |	  | d 7} qC t j d d	   | d d
  D  }
 |	 j d |
  qC WWd QRX| 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
    /rr   *
   z------c             S   s   g  |  ] } t  |   q S )float).0xr   r   ;/tmp/pip-build-ww9dw3qa/biopython/Bio/PDB/FragmentMapper.py
<listcomp>_   s   	 z#_read_fragments.<locals>.<listcomp>   ZXXXN)	_FRAGMENT_FILEopen	readlinessplitFragmentappendnumpyarrayadd_residue)sizelengthdirfilenamefpflistfidlslfZcoordr   r   r   _read_fragments=   s      
&r&   c               @   sv   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   sC   | |  _  d |  _ g  |  _ t j | 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   Zzeros	coords_car"   )selfr   r"   r   r   r   __init__h   s
    
			zFragment.__init__c             C   s   |  j  S)zcGet residue list.

        :return: the residue names
        :rtype: [string, string,...]
        )r)   )r+   r   r   r   get_resname_listz   s    zFragment.get_resname_listc             C   s   |  j  S)zcGet identifier for the fragment.

        :return: id for the fragment
        :rtype: int
        )r"   )r+   r   r   r   get_id   s    zFragment.get_idc             C   s   |  j  S)zGet the CA coordinates in the fragment.

        :return: the CA coords in the fragment
        :rtype: Numeric (Nx3) array
        )r*   )r+   r   r   r   
get_coords   s    zFragment.get_coordsc             C   sR   |  j  |  j k r t d   |  j 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 coorinates of the residues
        :type ca_coord: Numeric 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   s   |  j  S)zReturn lengt of the fragment.)r   )r+   r   r   r   __len__   s    zFragment.__len__c             C   s3   t    } | j |  j | j  | 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*   runZ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-   r.   r/   r   r2   r7   r8   r   r   r   r   r   e   s   r   c       
      C   s   g  } x t  d t |   | d  D] } t | d  } x t  d |  D]| } |  | | } | j   } | j d  r | d } n t d   | j   r t d   | j   }	 | j | |	  qI W| j	 |  q$ W| 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   r   CA
CHAINBREAK)
rangelenr   Zget_resnameZhas_idr   Zis_disorderedZ	get_coordr   r   )
ppr   Z	frag_listir%   jZresiduer0   car1   r   r   r   _make_fragment_list   s    	$rF   c       	      C   s   g  } x |  D]x } g  } xD t  d t |   D]- } | | } | | } | j | | f  q/ W| j   | d d } | j |  q W| 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   )r@   rA   r   sort)	r!   reflistZmappedr%   ZrankrC   rfZrmsfragmentr   r   r   _map_fragment_list   s    


rK   c               @   sO   e  Z d  Z d Z d d 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   s   | d k r d |  _  n$ | d k r0 d |  _  n t d   | |  _ | |  _ t | | |  |  _ | |  _ |  j |  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
        rN         r   z!Fragment length should be 5 or 7.N)	edger   flengthlsizer&   rH   model_mapfd)r+   rT   rS   rR   Zfdirr   r   r   r,      s    			zFragmentMapper.__init__c             C   s)  t    } | j |  } i  } x| D] } y t | |  j  } t | |  j  } x t d t |   D]q } | | }	 | |  j k  r qh qh | t |  |  j k r qh qh | |  j }
 |
 d k s t	  | |
 | |	 <qh WWq% t
 k
 r } z  | d k rn t
 |   WYd d } ~ Xq% Xq% W| S)zjMap (PRIVATE).

        :param model: the model that will be mapped
        :type model: L{Model}
        r   r>   N)r   Zbuild_peptidesrF   rR   rK   rH   r@   rA   rQ   AssertionErrorr   )r+   rT   ZppbZpplrV   rB   r!   ZmflistrC   resindexwhyr   r   r   rU     s*    	
#zFragmentMapper._mapc             C   s   | |  j  k S)zeCheck if the given residue is in any of the mapped fragments.

        :type res: L{Residue}
        )rV   )r+   rX   r   r   r   __contains__8  s    zFragmentMapper.__contains__c             C   s   |  j  | S)z{Get an entry.

        :type res: L{Residue}

        :return: fragment classification
        :rtype: L{Fragment}
        )rV   )r+   rX   r   r   r   __getitem__?  s    zFragmentMapper.__getitem__N)r9   r:   r;   r<   r,   rU   r[   r\   r   r   r   r   rL      s
   $rL   )r<   
__future__r   r   ZBio.SVDSuperimposerr   ZBio.PDB.PDBExceptionsr   ZBio.PDB.Polypeptider   r   r&   objectr   rF   rK   rL   r   r   r   r   <module>+   s   ([