
:>"^*5                 @   sV   d  Z  d d l m Z d d l m Z Gd d   d e  Z Gd d   d e  Z d S)	zBase class for Residue, Chain, Model and Structure classes.

It is a simple container class, with list and dictionary like properties.
    )copy)PDBConstructionExceptionc               @   s  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 d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z e d  d!    Z e j d" d!    Z d# d$   Z d% d&   Z d' d(   Z d) d*   Z d+ d,   Z d- d.   Z d/ d0   Z d1 d2   Z d3 d4   Z d5 d6   Z d7 d8   Z  d9 d:   Z! d; d<   Z" d= d>   Z# d? S)@EntityzBasic container object for PDB heirachy.

    Structure, Model, Chain and Residue are subclasses of Entity.
    It deals with storage and lookup.
    c             C   s:   | |  _  d |  _ d |  _ g  |  _ i  |  _ i  |  _ d S)zInitialize the class.N)_idfull_idparent
child_list
child_dictxtra)selfid r   3/tmp/pip-build-ww9dw3qa/biopython/Bio/PDB/Entity.py__init__   s    					zEntity.__init__c             C   s   t  |  j  S)zReturn the number of children.)lenr   )r   r   r   r   __len__$   s    zEntity.__len__c             C   s   |  j  | S)zReturn the child with given id.)r	   )r   r   r   r   r   __getitem__(   s    zEntity.__getitem__c             C   s   |  j  |  S)zRemove a child.)detach_child)r   r   r   r   r   __delitem__,   s    zEntity.__delitem__c             C   s   | |  j  k S)z4Check if there is a child element with the given id.)r	   )r   r   r   r   r   __contains__0   s    zEntity.__contains__c             c   s   x |  j  D] } | Vq
 Wd S)zIterate over children.N)r   )r   childr   r   r   __iter__4   s    zEntity.__iter__c             C   sc   t  | t |    r[ |  j d k r4 |  j | j k S|  j d d  | j d d  k Sn t Sd S)zJTest for equality. This compares full_id including the IDs of all parents.N   )
isinstancetyper   r   r   NotImplemented)r   otherr   r   r   __eq__;   s
    'zEntity.__eq__c             C   sc   t  | t |    r[ |  j d k r4 |  j | j k S|  j d d  | j d d  k Sn t Sd S)zTest for inequality.Nr   )r   r   r   r   r   r   )r   r   r   r   r   __ne__E   s
    'zEntity.__ne__c             C   sc   t  | t |    r[ |  j d k r4 |  j | j k S|  j d d  | j d d  k Sn t Sd S)zTest greater than.Nr   )r   r   r   r   r   r   )r   r   r   r   r   __gt__O   s
    'zEntity.__gt__c             C   sc   t  | t |    r[ |  j d k r4 |  j | j k S|  j d d  | j d d  k Sn t Sd S)zTest greater or equal.Nr   )r   r   r   r   r   r   )r   r   r   r   r   __ge__Y   s
    'zEntity.__ge__c             C   sc   t  | t |    r[ |  j d k r4 |  j | j k  S|  j d d  | j d d  k  Sn t Sd S)zTest less than.Nr   )r   r   r   r   r   r   )r   r   r   r   r   __lt__c   s
    'zEntity.__lt__c             C   sc   t  | t |    r[ |  j d k r4 |  j | j k S|  j d d  | j d d  k Sn t Sd S)zTest less or equal.Nr   )r   r   r   r   r   r   )r   r   r   r   r   __le__m   s
    'zEntity.__le__c             C   s   t  |  j  S)z&Hash method to allow uniqueness (set).)hashr   )r   r   r   r   __hash__w   s    zEntity.__hash__c             C   sG   x1 |  D]) } y | j    Wq t k
 r/ Yq Xq W|  j   |  _ d S)zReset the full_id (PRIVATE).

        Resets the full_id of this entity and
        recursively of all its children based on their ID.
        N)_reset_full_idAttributeError_generate_full_idr   )r   r   r   r   r   r%   }   s    	zEntity._reset_full_idc             C   sm   |  j    } | g } |  j   } x5 | d k	 rX | j    } | j |  | j   } q$ W| j   t |  S)zGenerate full_id (PRIVATE).

        Generate the full_id of the Entity based on its
        Id and the IDs of the parents.
        N)get_id
get_parentappendreversetuple)r   	entity_idpartsr   r   r   r   r'      s    	
zEntity._generate_full_idc             C   s   |  j  S)zReturn identifier.)r   )r   r   r   r   r      s    z	Entity.idc             C   s   | |  j  k r d S|  j rl | |  j j k rL t d j |  j  | |    |  j j |  j  =|  |  j j | <| |  _  |  j   d S)zChange the id of this entity.

        This will update the child_dict of this entity's parent
        and invalidate all cached full ids involving this entity.

        @raises: ValueError
        Nz]Cannot change id from `{}` to `{}`. The id `{}` is already used for a sibling of this entity.)r   r   r	   
ValueErrorformatr%   )r   valuer   r   r   r      s    			c             C   s   |  j  S)zReturn level in hierarchy.

        A - atom
        R - residue
        C - chain
        M - model
        S - structure
        )level)r   r   r   r   	get_level   s    	zEntity.get_levelc             C   s   | |  _  |  j   d S)zSet the parent Entity object.N)r   r%   )r   entityr   r   r   
set_parent   s    	zEntity.set_parentc             C   s   d |  _  d S)zDetach the parent.N)r   )r   r   r   r   detach_parent   s    zEntity.detach_parentc             C   s5   |  j  | } | j   |  j  | =|  j j |  d S)zRemove a child.N)r	   r6   r   remove)r   r   r   r   r   r   r      s    

zEntity.detach_childc             C   sY   | j    } |  j |  r+ t d |   | j |   |  j j |  | |  j | <d S)zAdd a child to the Entity.z%s defined twiceN)r(   has_idr   r5   r   r*   r	   )r   r4   r-   r   r   r   add   s    z
Entity.addc             C   s_   | j    } |  j |  r+ t d |   | j |   | g |  j | |  <| |  j | <d S)z2Add a child to the Entity at a specified position.z%s defined twiceN)r(   r8   r   r5   r   r	   )r   posr4   r-   r   r   r   insert   s    zEntity.insertc             c   s   x |  j  D] } | Vq
 Wd S)zReturn iterator over children.N)r   )r   r   r   r   r   get_iterator   s    zEntity.get_iteratorc             C   s   t  |  j  S)z&Return a copy of the list of children.)r   r   )r   r   r   r   get_list   s    zEntity.get_listc             C   s   | |  j  k S)z&Check if a child with given id exists.)r	   )r   r   r   r   r   r8      s    zEntity.has_idc             C   s   |  j  S)z Return the parent Entity object.)r   )r   r   r   r   r)      s    zEntity.get_parentc             C   s   |  j  S)zReturn the id.)r   )r   r   r   r   r(      s    zEntity.get_idc             C   s    |  j  d k r |  j   |  j  S)ak  Return the full id.

        The full id is a tuple containing all id's starting from
        the top object (Structure) down to the current object. A full id for
        a Residue object e.g. is something like:

        ("1abc", 0, "A", (" ", 10, "A"))

        This corresponds to:

        Structure with id "1abc"
        Model with id 0
        Chain with id "A"
        Residue with id (" ", 10, "A")

        The Residue id indicates that the residue is not a hetero-residue
        (or a water) because it has a blank hetero field, that its sequence
        identifier is 10 and its insertion code "A".
        N)r   r%   )r   r   r   r   get_full_id   s    
zEntity.get_full_idc             C   s+   x$ |  j    D] } | j | |  q Wd S)aJ  Apply rotation and translation to the atomic coordinates.

        :param rot: A right multiplying rotation matrix
        :type rot: 3x3 Numeric array

        :param tran: the translation vector
        :type tran: size 3 Numeric array

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

            from numpy import pi, array
            from Bio.PDB.vectors import Vector, rotmat
            rotation = rotmat(pi, Vector(1, 0, 0))
            translation = array((0, 0, 1), 'f')
            entity.transform(rotation, translation)

        N)r=   	transform)r   ZrotZtranor   r   r   r?     s    zEntity.transformc             C   se   t  |   } g  | _ i  | _ t  |  j  | _ | j   x$ |  j D] } | j | j     qD W| S)zCopy entity recursively.)r   r   r	   r
   r6   r9   )r   Zshallowr   r   r   r   r   )  s    		
zEntity.copyN)$__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r    r!   r"   r$   r%   r'   propertyr   setterr3   r5   r6   r   r9   r;   r<   r=   r8   r)   r(   r>   r?   r   r   r   r   r   r      s@   





		r   c               @   s-  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 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$ d%   Z d& d'   Z d( d)   Z d* d+   Z d, d- d.  Z d/ d0   Z d, S)1DisorderedEntityWrappera  Wrapper class to group equivalent Entities.

    This class is a simple wrapper class that groups a number of equivalent
    Entities and forwards all method calls to one of them (the currently selected
    object). DisorderedResidue and DisorderedAtom are subclasses of this class.

    E.g.: A DisorderedAtom object contains a number of Atom objects,
    where each Atom object represents a specific position of a disordered
    atom in the structure.
    c             C   s(   | |  _  i  |  _ d |  _ d |  _ d S)zInitialize the class.N)r   r	   selected_childr   )r   r   r   r   r   r   D  s    			z DisorderedEntityWrapper.__init__c             C   s7   | d k r t   t |  d  s' t   t |  j |  S)z.Forward the method call to the selected child.__setstate__rH   )r&   hasattrgetattrrH   )r   methodr   r   r   __getattr__M  s
    z#DisorderedEntityWrapper.__getattr__c             C   s   |  j  | S)z#Return the child with the given id.)rH   )r   r   r   r   r   r   X  s    z#DisorderedEntityWrapper.__getitem__c             C   s   | |  j  | <d S)z*Add a child, associated with a certain id.N)r	   )r   r   r   r   r   r   __setitem__^  s    z#DisorderedEntityWrapper.__setitem__c             C   s   | |  j  k S)z$Check if the child has the given id.)rH   )r   r   r   r   r   r   b  s    z$DisorderedEntityWrapper.__contains__c             C   s   t  |  j  S)zReturn the number of children.)iterrH   )r   r   r   r   r   f  s    z DisorderedEntityWrapper.__iter__c             C   s   t  |  j  S)zReturn the number of children.)r   rH   )r   r   r   r   r   j  s    zDisorderedEntityWrapper.__len__c             C   s   |  j  | S)z Subtraction with another object.)rH   )r   r   r   r   r   __sub__n  s    zDisorderedEntityWrapper.__sub__c             C   s   |  j  | k S)z&Return if child is greater than other.)rH   )r   r   r   r   r   r   t  s    zDisorderedEntityWrapper.__gt__c             C   s   |  j  | k S)z/Return if child is greater or equal than other.)rH   )r   r   r   r   r   r    x  s    zDisorderedEntityWrapper.__ge__c             C   s   |  j  | k  S)z#Return if child is less than other.)rH   )r   r   r   r   r   r!   |  s    zDisorderedEntityWrapper.__lt__c             C   s   |  j  | k S)z,Return if child is less or equal than other.)rH   )r   r   r   r   r   r"     s    zDisorderedEntityWrapper.__le__c             C   s   |  j  S)zReturn the id.)r   )r   r   r   r   r(     s    zDisorderedEntityWrapper.get_idc             C   s   | |  j  k S)z<Check if there is an object present associated with this id.)r	   )r   r   r   r   r   disordered_has_id  s    z)DisorderedEntityWrapper.disordered_has_idc             C   s.   d |  _  x |  j   D] } | j   q Wd S)zDetach the parent.N)r   disordered_get_listr6   )r   r   r   r   r   r6     s    	z%DisorderedEntityWrapper.detach_parentc             C   s   |  j  S)zReturn parent.)r   )r   r   r   r   r)     s    z"DisorderedEntityWrapper.get_parentc             C   s1   | |  _  x! |  j   D] } | j |  q Wd S)z/Set the parent for the object and its children.N)r   rR   r5   )r   r   r   r   r   r   r5     s    	z"DisorderedEntityWrapper.set_parentc             C   s   |  j  | |  _ d S)zSelect the object with given id as the currently active object.

        Uncaught method calls are forwarded to the selected child object.
        N)r	   rH   )r   r   r   r   r   disordered_select  s    z)DisorderedEntityWrapper.disordered_selectc             C   s
   t   d S)zdAdd disordered entry.

        This is implemented by DisorderedAtom and DisorderedResidue.
        N)NotImplementedError)r   r   r   r   r   disordered_add  s    z&DisorderedEntityWrapper.disordered_addc             C   s   d S)zBReturn 2, indicating that this Entity is a collection of Entities.   r   )r   r   r   r   is_disordered  s    z%DisorderedEntityWrapper.is_disorderedc             C   s   t  |  j  S)zReturn a list of id's.)sortedr	   )r   r   r   r   disordered_get_id_list  s    z.DisorderedEntityWrapper.disordered_get_id_listNc             C   s   | d k r |  j  S|  j | S)zsGet the child object associated with id.

        If id is None, the currently selected child is returned.
        N)rH   r	   )r   r   r   r   r   disordered_get  s    z&DisorderedEntityWrapper.disordered_getc             C   s   t  |  j j    S)zReturn list of children.)listr	   values)r   r   r   r   rR     s    z+DisorderedEntityWrapper.disordered_get_list)rA   rB   rC   rD   r   rM   r   rN   r   r   r   rP   r   r    r!   r"   r(   rQ   r6   r)   r5   rS   rU   rW   rY   rZ   rR   r   r   r   r   rG   8  s0   
		rG   N)rD   r   ZBio.PDB.PDBExceptionsr   objectr   rG   r   r   r   r   <module>
   s
    (