package org.biojava.nbio.structure.geometry;
import static org.junit.Assert.*;
import javax.vecmath.AxisAngle4d;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import org.biojava.nbio.structure.geometry.SuperPositionQuat;
import org.biojava.nbio.structure.geometry.SuperPositionQCP;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Test the Quaternion-Based Characteristic Polynomial {@link SuperPositionQCP}
* algorithm for RMSD and Superposition calculations.
*
* @author Aleix Lafita
* @since 5.0.0
*
*/
public class TestSuperPositionQCP {
private static final Logger logger = LoggerFactory
.getLogger(TestSuperPositionQCP.class);
/**
* Test case proposed by Peter Rose from his observations about quaternary
* symmetry artifacts with the QCP algorithm.
*/
@Test
public void testSymmetryQCP() {
// Generate an array of points with symmetry
Point3d[] set1 = new Point3d[16];
set1[0] = new Point3d(14.065934, 47.068832, -32.895836);
set1[1] = new Point3d(-14.065934, -47.068832, -32.895836);
set1[2] = new Point3d(-47.068832, 14.065934, -32.895836);
set1[3] = new Point3d(47.068832, -14.065934, -32.895836);
set1[4] = new Point3d(-14.065934, 47.068832, 32.895836);
set1[5] = new Point3d(14.065934, -47.068832, 32.895836);
set1[6] = new Point3d(47.068832, 14.065934, 32.895836);
set1[7] = new Point3d(-47.068832, -14.065934, 32.895836);
set1[8] = new Point3d(43.813946, 22.748293, -32.14434);
set1[9] = new Point3d(-43.813946, -22.748293, -32.14434);
set1[10] = new Point3d(-22.748293, 43.813946, -32.14434);
set1[11] = new Point3d(22.748293, -43.813946, -32.14434);
set1[12] = new Point3d(-43.813946, 22.748293, 32.14434);
set1[13] = new Point3d(43.813946, -22.748293, 32.14434);
set1[14] = new Point3d(22.748293, 43.813946, 32.14434);
set1[15] = new Point3d(-22.748293, -43.813946, 32.14434);
Point3d[] set2 = CalcPoint.clonePoint3dArray(set1);
// Use a random transformation to set2
AxisAngle4d rotAxis = new AxisAngle4d(0.440, 0.302, 0.845, 1.570);
Vector3d translation = new Vector3d(0.345, 2.453, 5.324);
Matrix4d transform = new Matrix4d();
transform.set(rotAxis);
transform.setTranslation(translation);
CalcPoint.transform(transform, set2);
// Use Quaternion superposition to obtain the RMSD
SuperPosition algorithm = new SuperPositionQuat(false);
long quatStart = System.nanoTime();
double quatrmsd = algorithm.getRmsd(set1, set2);
long quatTime = (System.nanoTime() - quatStart) / 1000;
// Use QCP algorithm to get the RMSD
algorithm = new SuperPositionQCP(false);
long qcpStart = System.nanoTime();
double qcprmsd = algorithm.getRmsd(set1, set2);
long qcpTime = (System.nanoTime() - qcpStart) / 1000;
logger.info(String.format("RMSD Symmetry: Quat time: %d us"
+ ", QCP time: %d us", quatTime, qcpTime));
// Check that the returned RMSDs are equal
assertEquals(quatrmsd, qcprmsd, 0.001);
}
}