o
    RŀgG                     @   s2  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	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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" d8de#de#de$fddZ%		d9dee"eee f de$e&ef de#de$e&ef fddZ'de"fdd Z(d!ede)fd"d#Z*		d:d$e d%e d&ed'ede#d(e$d)e+d*e+ddfd+d,Z,		d:d$e d%e de#d(e$d)e+d*e+ddfd-d.Z-				d;d/ee"eef d0ee"eef de#de#d)e+d*e+de$e&ef fd1d2Z.	d:de"d3e&d4e&d5e&ddf
d6d7Z/dS )<zDConvert XYZ Structure to internal coordinates and back, test result.    N)StringIO)zip_longest)Any)Union)	as_handle)Atom)Chain)
IC_Residue)Model)PDBException)PDBIO)enumerate_atoms)pdb_date)read_PIC)	write_PIC)DisorderedResidue)Residue)	StructureFverbosequickreturnc                 C   sv   t  }| | t| | |d t|||d}t| tr$t| }|r,t	|dd |
| t| |||d}|S )a  Test rebuild PDB structure from internal coordinates.

    Generates internal coordinates for entity and writes to a .pic file in
    memory, then generates XYZ coordinates from the .pic file and compares the
    resulting entity against the original.

    See :data:`IC_Residue.pic_accuracy` to vary numeric accuracy of the
    intermediate .pic file if the only issue is small differences in coordinates.

    Note that with default settings, deuterated initial structures will fail
    the comparison, as will structures loaded with alternate `IC_Residue.accept_atoms`
    settings.  Use `quick=True` and/or variations on `AtomKey.d2h` and
    `IC_Residue.accept_atoms` settings.

    :param Entity entity: Biopython Structure, Model or Chain.
        Structure to test
    :param bool verbose: default False.
        print extra messages
    :param bool quick: default False.
        only check the internal coords atomArrays are identical
    :returns: dict
        comparison dict from :func:`.compare_residues`
    r   )r   r   T)r   )r   atom_to_internal_coordinatesr   seekr   
isinstancer   next
get_chains	report_ICinternal_to_atom_coordinatescompare_residues)entityr   r   sppdb2r r#   F/var/www/html/myenv/lib/python3.10/site-packages/Bio/PDB/ic_rebuild.pystructure_rebuild_test!   s   




r%   r   
reportDictc           
      C   s(  |du rddddg ddddd	}zd| j krtdt| ttfrY| jrX|d  d7  < t| jj}t| jj}d|k s@d|k rX|d  d7  < |d	  |7  < |d
  |7  < nt| t	ry|d  d7  < |d 
| j | D ]}t||}qpngt| tr|d  d7  < | D ]}t||}qnOt| trt| dr|d du r| jdd|d< | jdd}|r|d  d7  < | jdd}|r|d  d7  < | D ]}	t|	|}qn	tdt| j  W n ty   tdt|  w |rtd|d |d |d |d |d |d |d	 |d
  |S )aF  Generate dict with counts of ic data elements for each entity level.

    reportDict entries are:
        - idcode : PDB ID
        - hdr : PDB header lines
        - mdl : models
        - chn : chains
        - res : residue objects
        - res_e : residues with dihedra and/or hedra
        - dih : dihedra
        - hed : hedra

    :param Entity entity: Biopython PDB Entity object: S, M, C or R
    :raises PDBException: if entity level not S, M, C, or R
    :raises Exception: if entity does not have .level attribute
    :returns: dict with counts of IC data elements
    Nr   )	idcodehdrmdlchnchn_idsresres_edihhedAzNo IC output at Atom levelr,      r-   r.   r/   r*   r+   r)   headerr'   headr(   namezCannot identify level: z2write_PIC: argument is not a Biopython PDB Entity zS{} : {} models {} chains {} {} residue objects {} residues with {} dihedra {} hedra)levelr   r   r   r   internal_coordlendihedrahedrar   appendidr   r
   r   hasattrr2   getstrKeyError	Exceptionprintformat)
r   r&   r   dlenhlenr,   r*   r(   r4   r)   r#   r#   r$   r   H   s   





r   c                 C   s   t  }d}|  D ]}|jrt|jjdkrd} nq	|s6t| tr2| }|js,t| |_|j  n|   t	| | |
d t|S )a]  Duplicate structure entity with IC data, no atom coordinates.

    Employs :func:`.write_PIC`, :func:`.read_PIC` with StringIO buffer.
    Calls :meth:`.Chain.atom_to_internal_coordinates` if needed.

    :param Entity entity: Biopython PDB Entity (will fail for Atom)
    :returns: Biopython PDBStructure, no Atom objects except initial coords
    Fr   T)r   get_residuesr6   r7   r9   r   r   r	   r   r   r   r   )r   r    hasInternalCoordsr,   r#   r#   r$   IC_duplicate   s$   	



rG   atmc                 C   s\   t |  }t |d }tjdd|d dd}|d |d |d |d ||d ff}t|S )	N   DHr   r1   count      )listget_full_idresubtuple)rH   afidafid4afid40new_afidr#   r#   r$   _atmfid_d2h   s
   &rY   r0r1a0a1cmpdictrtolatolc                 C   sj  |d  d7  < |d u r|rt | d| |jj d S d S |d u r6|r4t |  | |jjd d S d S | | ksFt|| krO|d  d7  < n|rat |  | |jjd|  d}|d u r|d u rt| d}	t| d}
t|	|
}n| }	| }
tj	|	|
||d	}|r|d
  d7  < d S |rt d|  | | |	d|
 d S d S )NaCountr1   zNone !=z!= NoneaFullIdMatchCount!=FrO   r_   r`   aCoordMatchCountzatom coords disagree:)
rA   rQ   parentresnamerY   npround	get_coordarray_equalallclose)rZ   r[   r\   r]   r   r^   r_   r`   ac_rslta0ca1cr#   r#   r$   _cmp_atm   sd   
 rp   c                 C   s  | j | j|j}}}| jj }	|	|d vr|d |	 |d  d7  < ||kr1|d  d7  < n|r9t|d| t| dr| jd ur| j}
|j}tdd |
jD }td	d |jD }td
d |
j	D }tdd |j	D }||kr|rt| d|d| |d  d7  < ||kr|rt| d|d| |d  d7  < d|d kr{d| j
d ks}dt| j
ks|d  d7  < t| jt|jkr| n|}|jD ]}| j|d }|d u rtjdd|dd}| j|d }|j|d }|d u rtjdd|dd}|j|d }|d u s"|d u s"d|   kr | kr/n nt| |||||||d qd|   kr?| krgn n&|d  d7  < |jD ]}t| ||j|d |j|d ||||d qLq|rrtd|  | |d  d7  < qd S d S d S d S )NchainsrCountr1   rMatchCountrc   r6   c                 s       | ]}|j V  qd S Nrbase.0ricr#   r#   r$   	<genexpr>"      z_cmp_res.<locals>.<genexpr>c                 s   rt   ru   rv   rx   r#   r#   r$   r{   #  r|   c                 s   rt   ru   rv   rx   r#   r#   r$   r{   $  r|   c                 s   rt   ru   rv   rx   r#   r#   r$   r{   %  r|   zrprev error:rpnMismatchCountzrnext error r   rN   residuesrJ   rK   rL   rd   disAtmCountzdisorder disagreement:ra   )r;   full_idrf   r:   rA   r<   r6   sortedrprevrnextrg   r7   
child_dictr=   rR   rS   is_disorderedrp   rQ   )rZ   r[   r   r^   r_   r`   r0idr0fidr1fidr*   ric0ric1r0prevr1prevr0nextr1nextlongerakr\   akndr]   da0kr#   r#   r$   _cmp_res  sv   .



$$

r   e0e1c                 C   s  i }g |d< d|d< d|d< d|d< d|d< d|d< d|d< d|d	< d|d
< |   |d< |  |d< d|d< d|d< |r
t| tr| jjdurt| jjt|jjkrtj| jj|jj|du rddn||du rkdn|drt| jjd|d< t| jjd|d	< |d	 dkrd|d< nd|d< n| jjdu rdnt| jjd|d< d|d< nd|d< t	| 
 |
 D ]D\}}|jjdurtj|jj|jj|du rdn||du rdn|dr|d	  t|jjd7  < nd|d< |d  t|jjd7  < q|d	 |d k r	d|d< nst	|  | D ]>\}	}
d|	   kr'|
 krFn nt	|	j |
j D ]\}}t||||||d q4qt|	|
||||d q|d |d kry|d	 |d kry|d
 |d kry|d dkryd|d< nd|d< d|d |d |d |d |d |d |d	 |d
 |d |d |d sdnd}|d s|d |d kr|d7 }|d	 |d
 kr|d7 }|d
 |d kr|d7 }||d< |S )aQ  Compare full IDs and atom coordinates for 2 Biopython PDB entities.

    Skip DNA and HETATMs.

    :param Entity e0,e1: Biopython PDB Entity objects (S, M or C).
        Structures, Models or Chains to be compared
    :param bool verbose:
        Whether to print mismatch info, default False
    :param bool quick: default False.
        Only check atomArrays are identical, aCoordMatchCount=0 if different
    :param float rtol, atol: default 1e-03, 1e-03 or round to 3 places.
        NumPy allclose parameters; default is to round atom coordinates to 3
        places and test equal.  For 'quick' will use defaults above for
        comparing atomArrays
    :returns dict:
        Result counts for Residues, Full ID match Residues, Atoms,
        Full ID match atoms, and Coordinate match atoms; report string;
        error status (bool)
    rq   r   r   rr   rs   r}   ra   r   re   rb   id0id1NpassreportgMbP?rd   TFrN   zv{}:{} {} -- {} of {} residue IDs match; {} residues {} atom coords, {} full IDs of {} atoms ({} disordered) match : {}ERRORzALL OKz -RESIDUE IDS-z -COORDINATES-z -ATOM IDS-)rQ   r   r   r6   	atomArrayrh   shaperl   sizer   r   rE   r   r   valuesr   rB   )r   r   r   r   r_   r`   r^   c0c1rZ   r[   dr0dr1rstrr#   r#   r$   r   V  s   
	



$

r   filepdbidchainidc           	   	   C   s  t |  t|dn}zUt| drO|s| jdd}| jdd}t| jdd}|r;|d| |p5d|p8d | jd	d}|rO|d
|  d  t	 }|
|  |j|dd W n tyn   tdt|  w W d   dS 1 szw   Y  dS )z2Write PDB file with HEADER and TITLE if available.wr2   r'   Nr3   deposition_datezHEADER    {:40}{:8}   {:4}
 r4   z
TITLE     
T)preserve_atom_numberingz2write_PDB: argument is not a Biopython PDB Entity )r   r   r<   r2   r=   r   writerB   upperr   set_structuresaver?   r@   r>   )	r   r   r   r   fpr(   ddr4   ior#   r#   r$   	write_PDB  s6   


"r   )FF)NF)NN)FFNN)0__doc__rR   r   r   	itertoolsr   typingr   r   numpyrh   Bio.Filer   Bio.PDB.Atomr   Bio.PDB.Chainr   Bio.PDB.internal_coordsr	   Bio.PDB.Modelr
   Bio.PDB.PDBExceptionsr   Bio.PDB.PDBIOr   Bio.PDB.PICIOr   r   r   r   Bio.PDB.Residuer   r   Bio.PDB.Structurer   booldictr%   r>   r   rG   rT   rY   floatrp   r   r   r   r#   r#   r#   r$   <module>   s   )


`	
C
L

 	