o
    RŀgN                     @   s   d Z ddlZddlZddlZddlmZ ddlmZ ddlmZ ddl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 erHdd
lmZ edddZG dd dZG dd deZdS )z&Atom class, used in Structure objects.    N)Optional)TYPE_CHECKING)TypeVar)	IUPACData)DisorderedEntityWrapper)PDBConstructionWarning)Vector)Residue_AtomTAtom)boundc                   @   s  e Zd ZdZ			dmdedejdee dee deded	ee d
ee dee f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	$dnd%ed&ed'ed(efd)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z#dCdD Z$dEdF Z%dGdH Z&dIdJ Z'dKdL Z(dMdN Z)dOdP Z*dQdR Z+dSdT Z,dUdV Z-dWdX Z.dYdZ Z/d[d\ Z0d]d^ Z1d_d` Z2dadb Z3dcdd Z4dedf Z5dgdh Z6didj Z7dkdl Z8dS )or   ag  Define Atom class.

    The Atom object stores atom name (both with and without spaces),
    coordinates, B factor, occupancy, alternative location specifier
    and (optionally) anisotropic B factor and standard deviations of
    B factor and positions.

    In the case of PQR files, B factor and occupancy are replaced by
    atomic charge and radius.
    Nnamecoordbfactor	occupancyaltlocfullnameelement
pqr_chargeradiusc                 C   s   d| _ d| _|| _|| _|| _|| _|| _|| _d| _|| _	d| _
d| _d| _d| _|| _i | _|r<|| ks<J || || _|  | _|	| _|
| _ddddd| _dS )a  Initialize Atom object.

        :param name: atom name (eg. "CA"). Note that spaces are normally stripped.
        :type name: string

        :param coord: atomic coordinates (x,y,z)
        :type coord: NumPy array (Float0, length 3)

        :param bfactor: isotropic B factor
        :type bfactor: number

        :param occupancy: occupancy (0.0-1.0)
        :type occupancy: number

        :param altloc: alternative location specifier for disordered atoms
        :type altloc: string

        :param fullname: full atom name, including spaces, e.g. " CA ". Normally
                         these spaces are stripped from the atom name.
        :type fullname: string

        :param element: atom element, e.g. "C" for Carbon, "HG" for mercury,
        :type element: uppercase string (or None if unknown)

        :param pqr_charge: atom charge
        :type pqr_charge: number

        :param radius: atom radius
        :type radius: number
        ANr            )NCACO)levelparentr   r   r   r   r   r   full_ididdisordered_flaganisou_arraysiguij_arraysigatm_arrayserial_numberxtraupper_assign_elementr   _assign_atom_massmassr   r   _sorting_keys)selfr   r   r   r   r   r   r&   r   r   r    r.   @/var/www/html/myenv/lib/python3.10/site-packages/Bio/PDB/Atom.py__init__+   s,   +
zAtom.__init__c                 C   s*   t |tr| jdd |jdd kS tS )zTest equality.r   N
isinstancer   r    NotImplementedr-   otherr.   r.   r/   __eq__t      
zAtom.__eq__c                 C   s*   t |tr| jdd |jdd kS tS )zTest inequality.r   Nr1   r4   r.   r.   r/   __ne__{   r7   zAtom.__ne__c                 C   sz   t |tr;| j|jkr| j|jkS | j| jd}| j|jd}||kr)||kS | j|jkr5| j|jkS | j|jkS tS )zTest greater than.   r2   r   r   r,   getr   r   r3   r-   r5   order_sorder_or.   r.   r/   __gt__      
zAtom.__gt__c                 C   sz   t |tr;| j|jkr| j|jkS | j| jd}| j|jd}||kr)||kS | j|jkr5| j|jkS | j|jkS tS )zTest greater or equal.r9   r:   r<   r.   r.   r/   __ge__   r@   zAtom.__ge__c                 C   sz   t |tr;| j|jkr| j|jk S | j| jd}| j|jd}||kr)||k S | j|jkr5| j|jk S | j|jk S tS )zTest less than.r9   r:   r<   r.   r.   r/   __lt__   r@   zAtom.__lt__c                 C   sz   t |tr;| j|jkr| j|jkS | j| jd}| j|jd}||kr)||kS | j|jkr5| j|jkS | j|jkS tS )zTest less or equal.r9   r:   r<   r.   r.   r/   __le__   r@   zAtom.__le__c                 C   s   t |  S )zReturn atom full identifier.)hashget_full_idr-   r.   r.   r/   __hash__   s   zAtom.__hash__c                 C   s   |r	|  tjvrS| jd  r| jdd  s| j }n| jd  r,| jd }n| jd }|  tjv rCd|| j|f }|}n
d|| j|f }d}t	|t
 |S )a\  Guess element from atom name if not recognised (PRIVATE).

        There is little documentation about extracting/encoding element
        information in atom names, but some conventions seem to prevail:

            - C, N, O, S, H, P, F atom names start with a blank space (e.g. " CA ")
              unless the name is 4 characters long (e.g. HE21 in glutamine). In both
              these cases, the element is the first character.

            - Inorganic elements do not have a blank space (e.g. "CA  " for calcium)
              but one must check the full name to differentiate between e.g. helium
              ("HE  ") and long-name hydrogens (e.g. "HE21").

            - Atoms with unknown or ambiguous elements are marked with 'X', e.g.
              PDB 4cpa. If we fail to identify an element, we should mark it as
              such.

        r   r   Nr   z8Used element %r for Atom (name=%s) with given element %rzDCould not assign element %r for Atom (name=%s) with given element %rX)
capitalizer   atom_weightsr   isalphaisdigitr   stripwarningswarnr   )r-   r   putative_elementmsgr.   r.   r/   r)      s(    

zAtom._assign_elementc              	   C   s2   z	t j| j  W S  ttfy   td Y S w )zReturn atom weight (PRIVATE).NaN)r   rJ   r   rI   AttributeErrorKeyErrorfloatrF   r.   r.   r/   r*      s
   zAtom._assign_atom_massc                 C   s   d|    dS )z&Print Atom object as <Atom atom_name>.z<Atom >)get_idrF   r.   r.   r/   __repr__   s   zAtom.__repr__c                 C   s   | j |j  }tt||S )zCalculate distance between two atoms.

        :param other: the other atom
        :type other: L{Atom}

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

            distance = atom1 - atom2

        )r   npsqrtdot)r-   r5   diffr.   r.   r/   __sub__  s   zAtom.__sub__Fr-   r5   compare_coordinatesreturnc                 C   s   t |t| s	dS | j|jkoZt| j|joZt| j|joZ| j|jkoZ| j|jkoZ|r5t	| j
|j
ndoZt| ddt| ddkoZt| ddt| ddkoZt| ddt| ddkS )af  Compare this atom to the other atom using a strict definition of equality.

        Indicates whether the atoms have the same name, B factor, occupancy,
        alternate location indicator (altloc), fullname, element, charge, and radius.
        If ``compare_coordinates`` is true, then the coordinates are also compared.

        :param other: The atom to compare this atom with
        :type other: Atom
        :param compare_coordinates: Whether to compare the coordinates of the atoms
        :type compare_coordinates: bool
        :return: Whether the atoms are strictly equal
        :rtype: bool
        FTr   Nr   r   )r2   typer   rY   iscloser   r   r   r   allcloser   getattr)r-   r5   r^   r.   r.   r/   strictly_equals  s&   

zAtom.strictly_equalsc                 C   
   || _ dS )zSet serial number.Nr&   )r-   nr.   r.   r/   set_serial_number3     
zAtom.set_serial_numberc                 C   re   )zSet isotroptic B factor.Nr   )r-   r   r.   r.   r/   set_bfactor7  ri   zAtom.set_bfactorc                 C   re   )zSet coordinates.Nr   )r-   r   r.   r.   r/   	set_coord;  ri   zAtom.set_coordc                 C   re   )z#Set alternative location specifier.Nr   )r-   r   r.   r.   r/   
set_altloc?  ri   zAtom.set_altlocc                 C   re   )zSet occupancy.Nr   )r-   r   r.   r.   r/   set_occupancyC  ri   zAtom.set_occupancyc                 C   re   )a>  Set standard deviation of atomic parameters.

        The standard deviation of atomic parameters consists
        of 3 positional, 1 B factor and 1 occupancy standard
        deviation.

        :param sigatm_array: standard deviations of atomic parameters.
        :type sigatm_array: NumPy array (length 5)
        Nr%   )r-   r%   r.   r.   r/   
set_sigatmG  s   

zAtom.set_sigatmc                 C   re   )zSet standard deviations of anisotropic temperature factors.

        :param siguij_array: standard deviations of anisotropic temperature factors.
        :type siguij_array: NumPy array (length 6)
        Nr$   )r-   r$   r.   r.   r/   
set_siguijS     
zAtom.set_siguijc                 C   re   )zSet anisotropic B factor.

        :param anisou_array: anisotropic B factor.
        :type anisou_array: NumPy array (length 6)
        Nr#   )r-   r#   r.   r.   r/   
set_anisou[  rv   zAtom.set_anisouc                 C   re   )zSet charge.Nr   )r-   r   r.   r.   r/   
set_chargec  ri   zAtom.set_chargec                 C   re   )zSet radius.Nr   )r-   r   r.   r.   r/   
set_radiusg  ri   zAtom.set_radiusc                 C   s
   d| _ dS )ztSet the disordered flag to 1.

        The disordered flag indicates whether the atom is disordered or not.
        r   Nr"   rF   r.   r.   r/   flag_disorderm  s   
zAtom.flag_disorderc                 C      | j S )z:Return the disordered flag (1 if disordered, 0 otherwise).r}   rF   r.   r.   r/   is_disorderedt     zAtom.is_disorderedc                 C   s   || _ |  | _dS )zXSet the parent residue.

        Arguments:
         - parent - Residue object

        N)r   rE   r    )r-   r   r.   r.   r/   
set_parentx  s   zAtom.set_parentc                 C   s
   d| _ dS )zRemove reference to parent.Nr   rF   r.   r.   r/   detach_parent  ri   zAtom.detach_parentc                 C   r   )z/Return standard deviation of atomic parameters.rr   rF   r.   r.   r/   
get_sigatm  r   zAtom.get_sigatmc                 C   r   )z>Return standard deviations of anisotropic temperature factors.rt   rF   r.   r.   r/   
get_siguij  r   zAtom.get_siguijc                 C   r   )zReturn anisotropic B factor.rw   rF   r.   r.   r/   
get_anisou  r   zAtom.get_anisouc                 C   r   )zReturn parent residue.r   rF   r.   r.   r/   
get_parent  r   zAtom.get_parentc                 C   r   )zReturn the serial number.rf   rF   r.   r.   r/   get_serial_number  r   zAtom.get_serial_numberc                 C   r   )zReturn atom name.)r   rF   r.   r.   r/   get_name  r   zAtom.get_namec                 C   r   )z3Return the id of the atom (which is its atom name).)r!   rF   r.   r.   r/   rW     r   zAtom.get_idc              	   C   sB   z| j  | j| jff W S  ty    dddd| j| jf Y S w )zReturn the full id of the atom.

        The full id of an atom is a tuple used to uniquely identify
        the atom and consists of the following elements:
        (structure id, model id, chain id, residue id, atom name, altloc)
        N)r   rE   r   r   rS   rF   r.   r.   r/   rE     s
   zAtom.get_full_idc                 C   r   )zReturn atomic coordinates.rl   rF   r.   r.   r/   	get_coord  r   zAtom.get_coordc                 C   r   )zReturn B factor.rj   rF   r.   r.   r/   get_bfactor  r   zAtom.get_bfactorc                 C   r   )zReturn occupancy.rp   rF   r.   r.   r/   get_occupancy  r   zAtom.get_occupancyc                 C   r   )z<Return the atom name, including leading and trailing spaces.)r   rF   r.   r.   r/   get_fullname  r   zAtom.get_fullnamec                 C   r   )z&Return alternative location specifier.rn   rF   r.   r.   r/   
get_altloc  r   zAtom.get_altlocc                 C   r   )zReturn level.)r   rF   r.   r.   r/   	get_level  r   zAtom.get_levelc                 C   r   )zReturn charge.ry   rF   r.   r.   r/   
get_charge  r   zAtom.get_chargec                 C   r   )zReturn radius.r{   rF   r.   r.   r/   
get_radius  r   zAtom.get_radiusc                 C   s   t | j|| | _dS )aD  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')
            atom.transform(rotation, translation)

        NrY   r[   r   )r-   rottranr.   r.   r/   	transform  s   zAtom.transformc                 C   s   | j \}}}t|||S )zvReturn coordinates as Vector.

        :return: coordinates as 3D vector
        :rtype: Bio.PDB.Vector class
        )r   r   )r-   xyzr.   r.   r/   
get_vector  s   zAtom.get_vectorc                 C   s6   t  | }|  |t  |   | j  |_|S )zHCreate a copy of the Atom.

        Parent information is lost.
        )copyr   rm   r   r'   )r-   shallowr.   r.   r/   r     s
   
z	Atom.copy)NNN)F)9__name__
__module____qualname____doc__strrY   ndarrayr   rU   r0   r6   r8   r?   rA   rB   rC   rG   r)   r*   rX   r]   r
   boolrd   rh   rk   rm   ro   rq   rs   ru   rx   rz   r|   r~   r   r   r   r   r   r   r   r   r   rW   rE   r   r   r   r   r   r   r   r   r   r   r   r.   r.   r.   r/   r      s    	

I.	
!
	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 )DisorderedAtoma  Contains all Atom objects that represent the same disordered atom.

    One of these atoms is "selected" and all method calls not caught
    by DisorderedAtom are forwarded to the selected Atom object. In that way, a
    DisorderedAtom behaves exactly like a normal Atom. By default, the selected
    Atom object represents the Atom object with the highest occupancy, but a
    different Atom object can be selected by using the disordered_select(altloc)
    method.
    c                 C   s   t j | _t| | dS )zVCreate DisorderedAtom.

        Arguments:
         - id - string, atom name

        N)sysmaxsizelast_occupancyr   r0   )r-   r!   r.   r.   r/   r0     s   
zDisorderedAtom.__init__c                 c   s    |   E dH  dS )z!Iterate through disordered atoms.N)disordered_get_listrF   r.   r.   r/   __iter__  s   zDisorderedAtom.__iter__c                 C   s&   | j rd|   dS d|   dS )z"Return disordered atom identifier.z<DisorderedAtom rV   z<Empty DisorderedAtom )
child_dictrW   rF   r.   r.   r/   rX     s   zDisorderedAtom.__repr__c                 C   sD   |   }|st|  dtjdd |D tjd}tj|dddS )zReturn the center of mass of the DisorderedAtom as a numpy array.

        Assumes all child atoms have the same mass (same element).
        z does not have childrenc                 S   s   g | ]}|j qS r.   rl   ).0ar.   r.   r/   
<listcomp>*  s    z1DisorderedAtom.center_of_mass.<locals>.<listcomp>)dtyper   N)axisweights)r   
ValueErrorrY   asarrayfloat32average)r-   childrencoordsr.   r.   r/   center_of_mass   s
   zDisorderedAtom.center_of_massc                 C   s   t | j dd dS )zeReturn list of atom instances.

        Sorts children by altloc (empty, then alphabetical).
        c                 S   s
   t | jS N)ordr   r   r.   r.   r/   <lambda>2  s   
 z4DisorderedAtom.disordered_get_list.<locals>.<lambda>key)sortedr   valuesrF   r.   r.   r/   r   -  s   z"DisorderedAtom.disordered_get_listc                 C   sT   |   |  }|| | }| }|| |< || jkr(|| _| | dS dS )zAdd a disordered atom.N)r~   r   r   r   r   r   disordered_select)r-   atomresiduer   r   r.   r.   r/   disordered_add4  s   

zDisorderedAtom.disordered_addc                 C   sv   | j | }| j|u }| j |= |  |r,| j r,t| j  dd dd }| |j dS | j s9d| _tj | _	dS dS )zRemove a child atom altloc from the DisorderedAtom.

        Arguments:
         - altloc - name of the altloc to remove, as a string.

        c                 S   r   r   rp   r   r.   r.   r/   r   R  s    z2DisorderedAtom.disordered_remove.<locals>.<lambda>r   N)
r   selected_childr   r   r   r   r   r   r   r   )r-   r   r   is_selectedchildr.   r.   r/   disordered_removeB  s   


z DisorderedAtom.disordered_removec                 C   s"   | D ]}t |j|| |_qdS )zvApply rotation and translation to all children.

        See the documentation of Atom.transform for details.
        Nr   )r-   r   r   r   r.   r.   r/   r   X  s   zDisorderedAtom.transformN)r   r   r   r   r0   r   rX   r   r   r   r   r   r.   r.   r.   r/   r     s    

r   )r   r   r   rN   typingr   r   r   numpyrY   Bio.PDB.AtomBioBio.Datar   Bio.PDB.Entityr   Bio.PDB.PDBExceptionsr   Bio.PDB.vectorsr   Bio.PDB.Residuer	   r
   r   r   r.   r.   r.   r/   <module>   s*      ^