o
    RŀgMH                     @   s   d 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
 dd
lmZ ddlZddlmZ ddlmZ e	rNddlmZ e
ded dZe
ded dZe
dddZG dd deeef ZG dd dZdS )zBase class for Residue, Chain, Model and Structure classes.

It is a simple container class, with list and dictionary like properties.
    N)deque)copy)Any)Generic)Optional)TYPE_CHECKING)TypeVar)Union)BiopythonWarning)PDBConstructionException)Atom_Child)Entityr   )bound_Parentr   _SelfzEntity[Any, Any]c                	   @   s  e Zd ZU dZee ed< ee ed< e	e
ef ed< eed< 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	'dOd(ed)ed*ed+efd,d-Z d.d/ Z!d0efd1d2Z"d3d4 Z#d5d6 Z$d0efd7d8Z%d9e&d0efd:d;Z'd<d= Z(d>d? Z)d@dA Z*dBdC Z+dDdE Z,dFdG Z-dHdI Z.dOdJdKZ/dLdM Z0dNS )Pr   zBasic container object for PDB hierarchy.

    Structure, Model, Chain and Residue are subclasses of Entity.
    It deals with storage and lookup.
    parent
child_list
child_dictlevelc                 C   s(   || _ d| _d| _g | _i | _i | _dS zInitialize the class.N)_idfull_idr   r   r   xtraselfid r   B/var/www/html/myenv/lib/python3.10/site-packages/Bio/PDB/Entity.py__init__/   s   
zEntity.__init__c                 C   
   t | jS zReturn the number of children.)lenr   r   r   r   r   __len__;      
zEntity.__len__c                 C   
   | j | S )zReturn the child with given id.r   r   r   r   r   __getitem__?   r%   zEntity.__getitem__c                 C   s
   |  |S )Remove a child.)detach_childr   r   r   r   __delitem__C   r%   zEntity.__delitem__c                 C   
   || j v S )z4Check if there is a child element with the given id.r'   r   r   r   r   __contains__G   r%   zEntity.__contains__c                 c       | j E dH  dS )zIterate over children.Nr   r#   r   r   r   __iter__K      zEntity.__iter__c                 C   sD   t |t| r | jdu r| j|jkS | jdd |jdd kS t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__Q   
   
zEntity.__eq__c                 C   sD   t |t| r | jdu r| j|jkS | jdd |jdd kS tS )zTest for inequality.Nr2   r3   r7   r   r   r   __ne__[   r:   zEntity.__ne__c                 C   sD   t |t| r | jdu r| j|jkS | jdd |jdd kS tS )zTest greater than.Nr2   r3   r7   r   r   r   __gt__e   r:   zEntity.__gt__c                 C   sD   t |t| r | jdu r| j|jkS | jdd |jdd kS tS )zTest greater or equal.Nr2   r3   r7   r   r   r   __ge__o   r:   zEntity.__ge__c                 C   sD   t |t| r | jdu r| j|jk S | jdd |jdd k S tS )zTest less than.Nr2   r3   r7   r   r   r   __lt__y   r:   zEntity.__lt__c                 C   sD   t |t| r | jdu r| j|jkS | jdd |jdd kS tS )zTest less or equal.Nr2   r3   r7   r   r   r   __le__   r:   zEntity.__le__c                 C   r    )z&Hash method to allow uniqueness (set).)hashr   r#   r   r   r   __hash__   r%   zEntity.__hash__c              	   C   s6   | D ]}z|   W q ty   Y qw |  | _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   childr   r   r   rB      s   zEntity._reset_full_idc                 C   sP   |   }|g}|  }|dur |  }|| | }|dus|  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   rD      s   
zEntity._generate_full_idc                 C      | j S )zReturn identifier.)r   r#   r   r   r   r      s   z	Entity.idc              	   C   sp   || j krdS | jdur/|| jjv r#td| d| j  d| dt | 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The id `zB` is already used for a sibling of this entity. Changing id from `z` to `zG` might create access inconsistencies to children of the parent entity.)r   r   r   warningswarnr
   rB   )r   valuer   r   r   r      s    
	
Fr   r8   compare_coordinatesreturnc                 C   sv   t |t| s	dS | j|jkrdS t| jt|jkrdS t| j|jD ]\}}t|ds/J |||s8 dS q$dS )a  Compare this entity to the other entity for equality.

        Recursively compare the children of this entity to the other entity's children.
        Compare most properties including names and IDs.

        :param other: The entity to compare this entity with
        :type other: Entity
        :param compare_coordinates: Whether to compare atomic coordinates
        :type compare_coordinates: bool
        :return: Whether the two entities are strictly equal
        :rtype: bool
        Fstrictly_equalsT)r4   r5   r   r"   r   ziphasattrrT   )r   r8   rR   
left_childright_childr   r   r   rT      s   zEntity.strictly_equalsc                 C   rN   )zReturn level in hierarchy.

        A - atom
        R - residue
        C - chain
        M - model
        S - structure
        r   r#   r   r   r   	get_level   s   	zEntity.get_levelentityc                 C   s   || _ |   dS )zSet the parent Entity object.N)r   rB   )r   r[   r   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   r%   zEntity.detach_parentc                 C   s*   | j | }|  | j |= | j| dS )r)   N)r   r_   r   remover   r   rF   r   r   r   r*     s   
zEntity.detach_childc                 C   sD   |  }| |rt| d||  | j| || j|< dS )zAdd a child to the Entity. defined twiceN)rG   has_idr   r\   r   rI   r   )r   r[   rL   r   r   r   add  s   

z
Entity.addposc                 C   sH   |  }| |rt| d||  |g| j||< || j|< dS )z2Add a child to the Entity at a specified position.rb   N)rG   rc   r   r\   r   r   )r   re   r[   rL   r   r   r   insert  s   

zEntity.insertc                 c   r.   )zReturn iterator over children.Nr/   r#   r   r   r   get_iterator  r1   zEntity.get_iteratorc                 C   r    )z&Return a copy of the list of children.)r   r   r#   r   r   r   get_list!  r%   zEntity.get_listc                 C   r,   )z&Check if a child with given id exists.r'   r   r   r   r   rc   %  r%   zEntity.has_idc                 C   rN   )z Return the parent Entity object.r^   r#   r   r   r   rH   )     zEntity.get_parentc                 C   rN   zReturn the id.r   r#   r   r   r   rG   -  ri   zEntity.get_idc                 C   s   | j du r
|  | _ | 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   rD   r#   r   r   r   get_full_id1  s   

zEntity.get_full_idc                 C   s   |   D ]}||| qdS )aF  Apply rotation and translation to the atomic coordinates.

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

        :param tran: the translation vector
        :type tran: size 3 NumPy 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)rh   	transform)r   rottranor   r   r   rm   I  s   zEntity.transformc           	      C   s   t | st|  dddh}dh}t| g}	 | }|j|v r(|| 7 }n||j7 }dd |D }||kr9nqtjdd	 |D tj	d
}|rLd}ntjdd	 |D tj	d
}tj
|d|dS )zReturn the center of mass of the Entity as a numpy array.

        If geometric is True, returns the center of geometry instead.
        z does not have childrenRCATc                 S   s   h | ]}|j qS r   rY   ).0er   r   r   	<setcomp>u      z(Entity.center_of_mass.<locals>.<setcomp>c                 S      g | ]}|j qS r   )coordrt   ar   r   r   
<listcomp>y  rw   z)Entity.center_of_mass.<locals>.<listcomp>)dtypeNc                 S   rx   r   )massrz   r   r   r   r|   }  rw   r   )axisweights)r"   
ValueErrorr   popleftr   get_unpacked_listr   npasarrayfloat32average)	r   	geometricmaybe_disorderedonly_atom_levelentitiesru   elevelscoordsmassesr   r   r   center_of_mass`  s&   


zEntity.center_of_massc                 C   sF   t | }g |_i |_t | j|_|  | jD ]	}||   q|S )zCopy entity recursively.)r   r   r   r   r_   rd   r   shallowrF   r   r   r   r     s   
zEntity.copyNF)1__name__
__module____qualname____doc__r   r   __annotations__listr   dictr   strr   r$   r(   r+   r-   r0   r9   r;   r<   r=   r>   r?   rA   rB   rD   propertyr   setterr   boolrT   rZ   r\   r_   r*   rd   intrf   rg   rh   rc   rH   rG   rl   rm   r   r   r   r   r   r   r   #   sd   
 








		
!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d d ed!efd"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd<d7d8Zd9d: Zd6S )=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 r   )r   r   selected_childr   r   r   r   r   r     s   
z DisorderedEntityWrapper.__init__c                 C   s&   |dkrt t| dst t| j|S )z.Forward the method call to the selected child.__setstate__r   )rC   rV   getattrr   )r   methodr   r   r   __getattr__  s
   
z#DisorderedEntityWrapper.__getattr__c                 C   r&   )z#Return the child with the given id.r   r   r   r   r   r(     r%   z#DisorderedEntityWrapper.__getitem__c                 C   s   || j |< dS )z*Add a child, associated with a certain id.Nr'   ra   r   r   r   __setitem__     z#DisorderedEntityWrapper.__setitem__c                 C   r,   )z$Check if the child has the given id.r   r   r   r   r   r-     r%   z$DisorderedEntityWrapper.__contains__c                 C   r    r!   )iterr   r#   r   r   r   r0     r%   z DisorderedEntityWrapper.__iter__c                 C   r    r!   )r"   r   r#   r   r   r   r$     r%   zDisorderedEntityWrapper.__len__c                 C   s
   | j | S )z Subtraction with another object.r   r7   r   r   r   __sub__  r%   zDisorderedEntityWrapper.__sub__c                 C   s
   | j |kS )z&Return if child is greater than other.r   r7   r   r   r   r<     r%   zDisorderedEntityWrapper.__gt__c                 C   s
   | j |kS )z/Return if child is greater or equal than other.r   r7   r   r   r   r=     r%   zDisorderedEntityWrapper.__ge__c                 C   s
   | j |k S )z#Return if child is less than other.r   r7   r   r   r   r>     r%   zDisorderedEntityWrapper.__lt__c                 C   s
   | j |kS )z,Return if child is less or equal than other.r   r7   r   r   r   r?     r%   zDisorderedEntityWrapper.__le__c                 C   s6   t | }i |_|  |  D ]	}||   q|S )z"Copy disorderd entity recursively.)r   r   r_   disordered_get_listdisordered_addr   r   r   r   r     s   zDisorderedEntityWrapper.copyc                 C   rN   rj   rk   r#   r   r   r   rG     ri   zDisorderedEntityWrapper.get_idFr8   rR   rS   c                 C   s   t |t| s	dS | j|jkrdS | j |j ksdS | j |j kr)dS | j D ]}| j| |j| |s? dS q.dS )a-  Compare this entity to the other entity using a strict definition of equality.

        Recursively compare the children of this entity to the other entity's children.
        Compare most properties including the selected child, names, and IDs.

        :param other: The entity to compare this entity with
        :type other: DisorderedEntityWrapper
        :param compare_coordinates: Whether to compare atomic coordinates
        :type compare_coordinates: bool
        :return: Whether the two entities are strictly equal
        :rtype: bool
        FT)r4   r5   r   r   rG   r   keysrT   )r   r8   rR   keyr   r   r   rT     s   

z'DisorderedEntityWrapper.strictly_equalsc                 C   r,   )z<Check if there is an object present associated with this id.r'   r   r   r   r   disordered_has_id  r%   z)DisorderedEntityWrapper.disordered_has_idc                 C   s    d| _ |  D ]}|  qdS r]   )r   r   r_   rE   r   r   r   r_     s   
z%DisorderedEntityWrapper.detach_parentc                 C   rN   )zReturn parent.r^   r#   r   r   r   rH     ri   z"DisorderedEntityWrapper.get_parentc                 C   s"   || _ |  D ]}|| qdS )z/Set the parent for the object and its children.N)r   r   r\   )r   r   rF   r   r   r   r\     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   r   r   r   r   r   disordered_select%  s   z)DisorderedEntityWrapper.disordered_selectc                 C      t )zdAdd disordered entry.

        This is implemented by DisorderedAtom and DisorderedResidue.
        NotImplementedErrorrE   r   r   r   r   ,     z&DisorderedEntityWrapper.disordered_addc                 C   r   )zgRemove disordered entry.

        This is implemented by DisorderedAtom and DisorderedResidue.
        r   rE   r   r   r   disordered_remove3  r   z)DisorderedEntityWrapper.disordered_removec                 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   r    )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u r| j S | j| S )zsGet the child object associated with id.

        If id is None, the currently selected child is returned.
        N)r   r   r   r   r   r   disordered_getC  s   
z&DisorderedEntityWrapper.disordered_getc                 C   s   t | j S )zReturn list of children.)r   r   valuesr#   r   r   r   r   L  r   z+DisorderedEntityWrapper.disordered_get_listr   )N)r   r   r   r   r   r   r(   r   r-   r0   r$   r   r<   r=   r>   r?   r   rG   r   rT   r   r_   rH   r\   r   r   r   r   r   r   r   r   r   r   r   r     sF    	
%
	r   )r   rO   collectionsr   r   typingr   r   r   r   r   r	   numpyr   Bior
   Bio.PDB.PDBExceptionsr   Bio.PDB.Atomr   r   r   r   r   r   r   r   r   r   <module>   s,     o