o
    Rŀg0                     @   s2   d Z ddlZddlmZ dd ZG dd dZdS )aE  Structural alignment using Quaternion Characteristic Polynomial (QCP).

QCPSuperimposer finds the best rotation and translation to put
two point sets on top of each other (minimizing the RMSD). This is
eg. useful to superimpose crystal structures. QCP stands for
Quaternion Characteristic Polynomial, which is used in the algorithm.

Algorithm and original code described in:

Theobald DL.
Rapid calculation of RMSDs using a quaternion-based characteristic polynomial.
Acta Crystallogr A. 2005 Jul;61(Pt 4):478-80. doi: 10.1107/S0108767305015266.
Epub 2005 Jun 23. PMID: 15973002.
    N)PDBExceptionc           d   	   C   s  t t ||j}t t | | j}t |j| }|| d }| \	}}}	}
}}}}}|| }|| }|| }|| }|| }|	|	 }|
|
 }|| }|| }d|| ||   }|| | | | }d|| | | | | | | |  }d|| | || |	  || |
  || |  || |  ||
 |	   }|	| }|| }||
 }|| } |	| }!||
 }"|| }#|| }$|| | | }%| }&|! }'|" }(|#| })|%|% || ||   |&|  |"|$|   |'| |"|$|     |&| ||#|   |'|  ||)    |
 | ||$|   |(|  ||)    |
 |  |!|$|   |(| |!|#|     }*d}+|},d}-t|+D ]:}.|,}/|,|, }0|0| |, }1|1| }2|2|, |* }3d|0 |, |1 |2 }4|3|4|-  }5t|,|5 },|,|/ |-|, k rr n
q9td|+ d dt||,  | d }6|#| |, }7| }8|'}9|"}:| };|$| |, }<|}=|}>|9}?|=}@|| | |, }A|}B|:}C|>}D|B}E||# |, }F|A|F |E|B  }G|@|F |D|B  }H|@|E |D|A  }I|?|E |C|A  }J|?|F |C|B  }K|?|D |C|@  }L|<|G |=|H  |>|I  }M|; |G |=|K  |>|J  }N|;|H |<|K  |>|L  }O|; |I |<|J  |=|L  }P|M|M |N|N  |O|O  |P|P  }Qd	}R|Q|Rk rF|8|G |9|H  |:|I  }M|7 |G |9|K  |:|J  }N|7|H |8|K  |:|L  }O|7 |I |8|J  |9|L  }P|M|M |N|N  |O|O  |P|P  }Q|Q|Rk rF|9|> |:|=  }S|8|> |:|<  }T|8|= |9|<  }U|7|> |:|;  }V|7|= |9|;  }W|7|< |8|;  }X|D|S |E|T  |F|U  }M|C |S |E|V  |F|W  }N|C|T |D|V  |F|X  }O|C |U |D|W  |E|X  }P|M|M |N|N  |O|O  |P|P  }Q|Q|Rk rF|@|S |A|T  |B|U  }M|? |S |A|V  |B|W  }N|?|T |@|V  |B|X  }O|? |U |@|W  |A|X  }P|M|M |N|N  |O|O  |P|P  }Q|Q|Rk rFt d
}Y|6|Y|M|N|O|PgfS |Qd }Z|M|Z }M|N|Z }N|O|Z }O|P|Z }P|M|M }[|N|N }0|O|O }\|P|P }]|N|O }^|M|P }_|P|N }`|M|O }a|O|P }b|M|N }ct 	d}Y|[|0 |\ |] |Yd d< d|^|_  |Yd d< d|`|a  |Yd d< d|^|_  |Yd d< |[|0 |\ |] |Yd d< d|b|c  |Yd d< d|`|a  |Yd d< d|b|c  |Yd d< |[|0 |\ |] |Yd d< |6|Y|M|N|O|PffS )zImplement the QCP code in Python.

    Input coordinate arrays must be centered at the origin and have
    shape Nx3.

    Variable names match (as much as possible) the C implementation.
    g      ?g       @g       g       @2   gdy=z&Newton-Rhapson did not converge after z iterationsgư>   )r   r   r         )
nptracedotTflattenrangeabsprinteyezeros)dcoords1coords2natomsG1G2AE0SxxSxySxzSyxSyySyzSzxSzySzzSxx2Syy2Szz2Sxy2Syz2Sxz2Syx2Szy2Szx2SyzSzymSyySzz2Sxx2Syy2Szz2Syz2Szy2C2C1SxzpSzxSyzpSzySxypSyxSyzmSzySxzmSzxSxymSyxSxxpSyySxxmSyySxy2Sxz2Syx2Szx2
negSxzpSzx
negSxzmSzx
negSxymSyxSxxpSyy_p_SzzC0nr_itmxEigenVevalprec_oldgx2baff_primedeltarmsda11a12a13a14a21a22a23a24a31a32a33a34a41a42a43a44
a3344_4334
a3244_4234
a3243_4233
a3143_4133
a3144_4134
a3142_4132q1q2q3q4qsqrevecprec
a1324_1423
a1224_1422
a1223_1322
a1124_1421
a1123_1321
a1122_1221rotnormqa2y2z2xyazzxayyzax ru   B/var/www/html/myenv/lib/python3.10/site-packages/Bio/PDB/qcprot.pyqcp   sF  
(





		 
 
 
 


rw   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S )QCPSuperimposera  Quaternion Characteristic Polynomial (QCP) Superimposer.

    QCPSuperimposer finds the best rotation and translation to put
    two point sets on top of each other (minimizing the RMSD). This is
    eg. useful to superimposing 3D structures of proteins.

    QCP stands for Quaternion Characteristic Polynomial, which is used
    in the algorithm.

    Reference:

    Douglas L Theobald (2005), "Rapid calculation of RMSDs using a
    quaternion-based characteristic polynomial.", Acta Crystallogr
    A 61(4):478-480
    c                 C   s   |    dS )zInitialize the class.N)_reset_propertiesselfru   ru   rv   __init__   s   zQCPSuperimposer.__init__c                 C   s.   d| _ d| _d| _d| _d| _d| _d| _dS )zFReset all relevant properties to None to avoid conflicts between runs.N)reference_coordscoordstransformed_coordsrj   tranrmsinit_rmsrz   ru   ru   rv   ry      s   
z!QCPSuperimposer._reset_propertiesc                 C   sx   t |t |ksJ dtjdd |D tjd}tjdd |D tjd}| || |   |  | _|  | _	dS )a=  Prepare alignment between two atom lists.

        Put (translate/rotate) the atoms in fixed on the atoms in
        moving, in such a way that the RMSD is minimized.

        :param fixed: list of (fixed) atoms
        :param moving: list of (moving) atoms
        :type fixed,moving: [L{Atom}, L{Atom},...]
        z*Fixed and moving atom lists differ in sizec                 S      g | ]}|  qS ru   	get_coord.0rC   ru   ru   rv   
<listcomp>      z-QCPSuperimposer.set_atoms.<locals>.<listcomp>)dtypec                 S   r   ru   r   r   ru   ru   rv   r     r   N)
lenr   arrayfloat64setrunget_rmsr   
get_rotranrotran)r{   fixedmoving	fix_coord	mov_coordru   ru   rv   	set_atoms  s   

zQCPSuperimposer.set_atomsc                 C   s6   | j du r	td| j \}}|D ]}||| qdS )zCApply the QCP rotation matrix/translation vector to a set of atoms.Nz)No transformation has been calculated yet)r   r   	transform)r{   	atom_listrj   r   atomru   ru   rv   apply  s   

zQCPSuperimposer.applyc                 C   sH   |    || _|| _|j\| _}|j|jkrtd|dkr"tddS )a  Set the coordinates to be superimposed.

        coords will be put on top of reference_coords.

        - reference_coords: an NxDIM array
        - coords: an NxDIM array

        DIM is the dimension of the points, N is the number
        of points to be superimposed.
        z*Coordinates must have the same dimensions.r   zCoordinates must be Nx3 arrays.N)ry   r}   r~   shape_natomsr   )r{   r}   r~   n_dimru   ru   rv   r   "  s   zQCPSuperimposer.setc                 C   s   | j du s
| jdu rtd| j  }| j }tj|dd}tj|dd}||8 }||8 }t||| j\| _| _	}|t
|| j	 | _dS )z Superimpose the coordinate sets.NNo coordinates set.r   axis)r~   r}   r   copyr   meanrw   r   r   rj   r	   r   )r{   r~   
coords_ref
com_coordscom_refr?   ru   ru   rv   r   9  s   

zQCPSuperimposer.runc                 C   sL   | j du s
| jdu rtd| jdu rtdt| j | j| j | _| jS )z#Get the transformed coordinate set.Nr   Nothing is superimposed yet.)r~   r}   r   rj   r   r	   r   r   rz   ru   ru   rv   get_transformedL  s   
zQCPSuperimposer.get_transformedc                 C   s   | j du r	td| j | jfS )z@Return right multiplying rotation matrix and translation vector.Nr   )rj   r   r   rz   ru   ru   rv   r   W  s   
zQCPSuperimposer.get_rotranc                 C   sT   | j du r	td| jdu r'| j | j }tttj|| dd| j | _| jS )zCReturn the root mean square deviation of untransformed coordinates.NzNo coordinates set yet.r   r   )r~   r   r   r}   r   sqrtsumr   )r{   diffru   ru   rv   get_init_rms]  s   

&zQCPSuperimposer.get_init_rmsc                 C   s   | j du r	td| j S )z7Root mean square deviation of superimposed coordinates.NzNothing superimposed yet.)r   r   rz   ru   ru   rv   r   g  s   
zQCPSuperimposer.get_rmsN)__name__
__module____qualname____doc__r|   ry   r   r   r   r   r   r   r   r   ru   ru   ru   rv   rx      s    

rx   )r   numpyr   Bio.PDB.PDBExceptionsr   rw   rx   ru   ru   ru   rv   <module>   s    D