
    RiJH                        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	rddlmZ  e
ded         Z e
ded         Z e
dd      Z G d deeef         Z G d d      Zy)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            	       l   e Zd ZU dZedz  ed<   ee   ed<   ee	ef   ed<   e
ed<   d Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zed        Zej8                  d        Z	 d.dedededefdZd Z defdZ!d  Z"d! Z#defd"Z$d#e%defd$Z&d% Z'd& Z(d' Z)d( Z*d) Z+d* Z,d+ Z-d.d,Z.d- Z/y)/r   zBasic container object for PDB hierarchy.

    Structure, Model, Chain and Residue are subclasses of Entity.
    It deals with storage and lookup.
    Nparent
child_list
child_dictlevelc                 X    || _         d| _        d| _        g | _        i | _        i | _        yzInitialize the class.N)_idfull_idr   r   r   xtraselfids     F/home/agent/.friday_env/lib/python3.12/site-packages/Bio/PDB/Entity.py__init__zEntity.__init__/   s,    	    c                 ,    t        | j                        S zReturn the number of children.)lenr   r   s    r    __len__zEntity.__len__;   s    4??##r"   c                      | j                   |   S )zReturn the child with given id.r   r   s     r    __getitem__zEntity.__getitem__?   s    r""r"   c                 $    | j                  |      S )Remove a child.)detach_childr   s     r    __delitem__zEntity.__delitem__C   s      $$r"   c                     || j                   v S )z4Check if there is a child element with the given id.r)   r   s     r    __contains__zEntity.__contains__G       T__$$r"   c              #   8   K   | j                   E d{    y7 w)zIterate over children.Nr   r&   s    r    __iter__zEntity.__iter__K        ??""   c                     t        |t        |             rD| j                  | 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   others     r    __eq__zEntity.__eq__Q   T    eT$Z({{"ww%((**||AB'5==+<<<!!r"   c                     t        |t        |             rD| j                  | j                  |j                  k7  S | j                  dd |j                  dd k7  S t
        S )zTest for inequality.Nr8   r9   r=   s     r    __ne__zEntity.__ne__[   r@   r"   c                     t        |t        |             rD| j                  | j                  |j                  kD  S | j                  dd |j                  dd kD  S t
        S )zTest greater than.Nr8   r9   r=   s     r    __gt__zEntity.__gt__e   T    eT$Z({{"ww))||AB'%--*;;;!!r"   c                     t        |t        |             rD| j                  | j                  |j                  k\  S | j                  dd |j                  dd k\  S t
        S )zTest greater or equal.Nr8   r9   r=   s     r    __ge__zEntity.__ge__o   r@   r"   c                     t        |t        |             rD| j                  | j                  |j                  k  S | j                  dd |j                  dd k  S t
        S )zTest less than.Nr8   r9   r=   s     r    __lt__zEntity.__lt__y   rE   r"   c                     t        |t        |             rD| j                  | j                  |j                  k  S | j                  dd |j                  dd k  S t
        S )zTest less or equal.Nr8   r9   r=   s     r    __le__zEntity.__le__   r@   r"   c                 ,    t        | j                        S )z&Hash method to allow uniqueness (set).)hashr   r&   s    r    __hash__zEntity.__hash__   s    DLL!!r"   c                 |    | D ]  }	 |j                           | j                         | _        y# t        $ r Y 7w xY w)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   childs     r    rP   zEntity._reset_full_id   sJ      	E$$&	
 --/ " s   /	;;c                     | j                         }|g}| j                         }|4|j                         }|j                  |       |j                         }|4|j                          t	        |      S )zGenerate full_id (PRIVATE).

        Generate the full_id of the Entity based on its
        Id and the IDs of the parents.
        )get_id
get_parentappendreversetuple)r   	entity_idpartsr   s       r    rR   zEntity._generate_full_id   sj     KKM	" ILL#&&(F   	U|r"   c                     | j                   S )zReturn identifier.)r   r&   s    r    r   z	Entity.id   s     xxr"   c           	      j   || j                   k(  ry| j                  || j                  j                  v r.t        j                  d| d| j                    d| dt
               | j                  j                  | j                   = | | j                  j                  |<   || _         | j                          y)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   rP   )r   values     r    r   z	Entity.id   s     DHH;;"...ug &))-
& @HH %	 &&txx0,0DKK""5)r"   r   r>   compare_coordinatesreturnc                 P   t        |t        |             sy| j                  |j                  k7  ryt        | j                        t        |j                        k7  ryt        | j                  |j                        D ]'  \  }}t        |d      sJ |j                  ||      r' y y)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)r:   r;   r   r%   r   ziphasattrre   )r   r>   rb   
left_childright_childs        r    re   zEntity.strictly_equals   s     %d,77ehht3u'7'7#88'*4??E<L<L'M 	#J:'8999--k;NO	
 r"   c                     | j                   S )zReturn level in hierarchy.

        A - atom
        R - residue
        C - chain
        M - model
        S - structure
        )r   r&   s    r    	get_levelzEntity.get_level   s     zzr"   entityc                 2    || _         | j                          y)zSet the parent Entity object.N)r   rP   )r   rl   s     r    
set_parentzEntity.set_parent   s    r"   c                     d| _         yzDetach the parent.Nr   r&   s    r    detach_parentzEntity.detach_parent   s	    r"   c                     | j                   |   }|j                          | j                   |= | j                  j                  |       y)r,   N)r   rr   r   remover   r   rT   s      r    r-   zEntity.detach_child  s:    #OOBu%r"   c                     |j                         }| j                  |      rt        | d      |j                  |        | j                  j                  |       || j                  |<   y)zAdd a child to the Entity. defined twiceN)rV   has_idr   rn   r   rX   r   )r   rl   r[   s      r    addz
Entity.add  sY    MMO	;;y!*i[+GHH$v&%+	"r"   posc                     |j                         }| j                  |      rt        | d      |j                  |        |g| j                  || || j
                  |<   y)z2Add a child to the Entity at a specified position.rw   N)rV   rx   r   rn   r   r   )r   rz   rl   r[   s       r    insertzEntity.insert  sY    MMO	;;y!*i[+GHH$$*8C %+	"r"   c              #   8   K   | j                   E d{    y7 w)zReturn iterator over children.Nr3   r&   s    r    get_iteratorzEntity.get_iterator  r5   r6   c                 ,    t        | j                        S )z&Return a copy of the list of children.)r   r   r&   s    r    get_listzEntity.get_list!  s    DOO$$r"   c                     || j                   v S )z&Check if a child with given id exists.r)   r   s     r    rx   zEntity.has_id%  r1   r"   c                     | j                   S )z Return the parent Entity object.rq   r&   s    r    rW   zEntity.get_parent)      {{r"   c                     | j                   S zReturn the id.r   r&   s    r    rV   zEntity.get_id-      wwr"   c                 \    | j                   | 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".
        )r   rR   r&   s    r    get_full_idzEntity.get_full_id1  s(    ( <<113DL||r"   c                 R    | j                         D ]  }|j                  ||        y)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)r   	transform)r   rottranos       r    r   zEntity.transformI  s'    (  	#AKKT"	#r"   c                 j   t        |       st        |  d      ddh}dh}t        | g      }	 |j                         }|j                  |v r||j                         z  }n||j                  z  }|D ch c]  }|j                   }}||k(  rnat        j                  |D cg c]  }|j                   c}t        j                        }|rd}	n=t        j                  |D cg c]  }|j                   c}t        j                        }	t        j                  |d|	      S c c}w c c}w c c}w )	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A)dtypeNr   )axisweights)r%   
ValueErrorr   popleftr   get_unpacked_listr   npasarraycoordfloat32massaverage)
r   	geometricmaybe_disorderedonly_atom_levelentitieseelevelsacoordsmassess
             r    center_of_masszEntity.center_of_mass`  s    4yv%<=>>:%$=  "Aww**A//11ALL((011qww1G1/)  h7QWW7rzzJFZZ :A :"**MFzz&q&99 2 8 !;s   3D&"D+$D0c                     t        |       }g |_        i |_        t        | j                        |_        |j	                          | j                  D ]!  }|j                  |j                                # |S )zCopy entity recursively.)r   r   r   r   rr   ry   r   shallowrT   s      r    r   zEntity.copy  s`    t*DII__ 	&EKK

%	&r"   F)0__name__
__module____qualname____doc__r   __annotations__listr   dictr   strr!   r'   r*   r.   r0   r4   r?   rB   rD   rG   rI   rK   rN   rP   rR   propertyr   setterr   boolre   rk   rn   rr   r-   ry   intr|   r~   r   rx   rW   rV   r   r   r   r    r"   r    r   r   #   s<    dNVS&[!!J$#%%#"""""""0$   YY 4 @E!8<	>	 
&,& ,,# ,v ,#%%0#.:Br"   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Z	 d dd dedefdZd Zd Zd Zd Zd Zd Zd Zd Zd Zd!dZd Zy)"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                 <    || _         i | _        d| _        d| _        yr   )r   r   selected_childr   r   s     r    r!   z DisorderedEntityWrapper.__init__  s    "r"   c                 h    |dk(  rt         t        | d      st         t        | j                  |      S )z.Forward the method call to the selected child.__setstate__r   )rQ   rg   getattrr   )r   methods     r    __getattr__z#DisorderedEntityWrapper.__getattr__  s6    ^#  t-. ! t**F33r"   c                      | j                   |   S )z#Return the child with the given id.r   r   s     r    r*   z#DisorderedEntityWrapper.__getitem__  s    ""2&&r"   c                 "    || j                   |<   y)z*Add a child, associated with a certain id.Nr)   ru   s      r    __setitem__z#DisorderedEntityWrapper.__setitem__  s    #r"   c                     || j                   v S )z$Check if the child has the given id.r   r   s     r    r0   z$DisorderedEntityWrapper.__contains__  s    T((((r"   c                 ,    t        | j                        S r$   )iterr   r&   s    r    r4   z DisorderedEntityWrapper.__iter__  s    D''((r"   c                 ,    t        | j                        S r$   )r%   r   r&   s    r    r'   zDisorderedEntityWrapper.__len__  s    4&&''r"   c                      | j                   |z
  S )z Subtraction with another object.r   r=   s     r    __sub__zDisorderedEntityWrapper.__sub__      ""U**r"   c                      | j                   |kD  S )z&Return if child is greater than other.r   r=   s     r    rD   zDisorderedEntityWrapper.__gt__  r   r"   c                      | j                   |k\  S )z/Return if child is greater or equal than other.r   r=   s     r    rG   zDisorderedEntityWrapper.__ge__      ""e++r"   c                      | j                   |k  S )z#Return if child is less than other.r   r=   s     r    rI   zDisorderedEntityWrapper.__lt__  r   r"   c                      | j                   |k  S )z,Return if child is less or equal than other.r   r=   s     r    rK   zDisorderedEntityWrapper.__le__  r   r"   c                     t        |       }i |_        |j                          | j                         D ]!  }|j	                  |j                                # |S )z"Copy disorderd entity recursively.)r   r   rr   disordered_get_listdisordered_addr   s      r    r   zDisorderedEntityWrapper.copy  sR    t*--/ 	1E""5::<0	1 r"   c                     | j                   S r   r   r&   s    r    rV   zDisorderedEntityWrapper.get_id  r   r"   r>   rb   rc   c                    t        |t        |             sy| j                  |j                  k7  ry| j                  j	                         |j                  j	                         k(  sy| j
                  j                         |j
                  j                         k7  ry| j
                  j                         D ]0  }| j
                  |   j                  |j
                  |   |      r0 y y)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)r:   r;   r   r   rV   r   keysre   )r   r>   rb   keys       r    re   z'DisorderedEntityWrapper.strictly_equals  s     %d,77ehh""))+u/C/C/J/J/LL ??!U%5%5%:%:%<< ??'') 	C??3'77  %': 		 r"   c                     || j                   v S )z<Check if there is an object present associated with this id.r)   r   s     r    disordered_has_idz)DisorderedEntityWrapper.disordered_has_id  r1   r"   c                 \    d| _         | j                         D ]  }|j                           yrp   )r   r   rr   rS   s     r    rr   z%DisorderedEntityWrapper.detach_parent  s-    --/ 	"E!	"r"   c                     | j                   S )zReturn parent.rq   r&   s    r    rW   z"DisorderedEntityWrapper.get_parent  r   r"   c                 ^    || _         | j                         D ]  }|j                  |        y)z/Set the parent for the object and its children.N)r   r   rn   )r   r   rT   s      r    rn   z"DisorderedEntityWrapper.set_parent  s/    --/ 	%EV$	%r"   c                 ,    | j                   |   | _        y)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   s     r    disordered_selectz)DisorderedEntityWrapper.disordered_select%  s    
 #oob1r"   c                     t         )zdAdd disordered entry.

        This is implemented by DisorderedAtom and DisorderedResidue.
        NotImplementedErrorrS   s     r    r   z&DisorderedEntityWrapper.disordered_add,  
    
 "!r"   c                     t         )zgRemove disordered entry.

        This is implemented by DisorderedAtom and DisorderedResidue.
        r   rS   s     r    disordered_removez)DisorderedEntityWrapper.disordered_remove3  r   r"   c                      y)zBReturn 2, indicating that this Entity is a collection of Entities.   r   r&   s    r    is_disorderedz%DisorderedEntityWrapper.is_disordered:  s    r"   c                 ,    t        | j                        S )zReturn a list of id's.)sortedr   r&   s    r    disordered_get_id_listz.DisorderedEntityWrapper.disordered_get_id_list>  s     doo&&r"   Nc                 <    || j                   S | j                  |   S )zsGet the child object associated with id.

        If id is None, the currently selected child is returned.
        )r   r   r   s     r    disordered_getz&DisorderedEntityWrapper.disordered_getC  s$    
 :&&&r""r"   c                 H    t        | j                  j                               S )zReturn list of children.)r   r   valuesr&   s    r    r   z+DisorderedEntityWrapper.disordered_get_listL  s    DOO**,--r"   r   )N)r   r   r   r   r!   r   r*   r   r0   r4   r'   r   rD   rG   rI   rK   r   rV   r   re   r   rr   rW   rn   r   r   r   r   r   r   r   r   r"   r    r   r     s    		4'$))(++,+,
	
 MR#.#EI#	#J%"%2""'
#.r"   r   )r   r_   collectionsr   r   typingr   r   r   r   r	   r
   numpyr   Bior   Bio.PDB.PDBExceptionsr   Bio.PDB.Atomr   r   r   r   r   r   r   r"   r    <module>r      s   
              :!	'7!8	9
)8H#5
612jWWf_% jZ~. ~.r"   