/*-
* Copyright (c) 2012 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package uk.ac.diamond.scisoft.analysis.diffraction;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import javax.vecmath.Matrix3d;
import javax.vecmath.Vector3d;
import org.eclipse.dawnsci.analysis.api.diffraction.DetectorProperties;
import org.eclipse.dawnsci.analysis.api.diffraction.DiffractionCrystalEnvironment;
import org.eclipse.january.dataset.DatasetFactory;
import org.eclipse.january.dataset.DoubleDataset;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import uk.ac.diamond.scisoft.analysis.IOTestUtils;
import uk.ac.diamond.scisoft.analysis.io.DataHolder;
import uk.ac.diamond.scisoft.analysis.io.PNGSaver;
/**
*
*/
public class DetectorPropertiesTest {
static int[] detectorCorners = { 0, 0, 0, 3072, 3072, 0, 3072, 3072 };
static double pixelSize = 0.1026;
// static double pixelSize = 1.0;
static int[] imageSizePix = { 3072, 3072 };
static Vector3d detectorOrigin = new Vector3d(157.44, 157.44, 329.8);
static Vector3d beamCentre = new Vector3d(0, 0, 329.8);
static Matrix3d orientationMatrix = new Matrix3d(0.984657762021401, 0.017187265168157, -0.17364817766693,
0.012961831885909, 0.985184016468007, 0.171010071662834, 0.174014604574351, -0.170637192932859,
0.969846310392954);
static double lambda = 1.001;
private static String testScratchDirectoryName;
private static String filePath = "detectorproperties.png";
static double wavelength = 1.4;
static int[] ishape = new int[] { 800, 400 };
static double[] pxdim = new double[] { 0.2, 0.3 };
static double[] origin = new double[] { 80, 60, 234 };
static double ttheta = Math.toRadians(11.5);
private static DoubleDataset makeDiffImage() {
DoubleDataset data = DatasetFactory.zeros(DoubleDataset.class, ishape[1], ishape[0]);
double rho = origin[2] * Math.tan(ttheta);
double dphi = 45.;
Matrix3d orientn = new Matrix3d();
orientn.setIdentity();
DetectorProperties detprops = new DetectorProperties(new Vector3d(origin), ishape[1], ishape[0], pxdim[1],
pxdim[0], orientn);
DiffractionCrystalEnvironment diffexp = new DiffractionCrystalEnvironment(wavelength);
QSpace qspace = new QSpace(detprops, diffexp);
for (double phi = 0; phi < 360.; phi += dphi) {
int x = (int) Math.floor((origin[0] + rho * Math.cos(Math.toRadians(phi))) / pxdim[0]);
int y = (int) Math.floor((origin[1] + rho * Math.sin(Math.toRadians(phi))) / pxdim[1]);
data.set(phi + 30, y, x);
System.out.println("Q: " + qspace.qFromPixelPosition(x, y) + "; value = " + (phi + 30));
}
return data;
}
/**
* Creates an empty directory for use by test code.
*
* @throws Exception
* if the test fails
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
testScratchDirectoryName = IOTestUtils.generateDirectorynameFromClassname(DetectorPropertiesTest.class
.getCanonicalName());
IOTestUtils.makeScratchDirectory(testScratchDirectoryName);
DataHolder dh = new DataHolder();
DoubleDataset data = makeDiffImage();
dh.addDataset("testing data", data);
new PNGSaver(testScratchDirectoryName + filePath).saveFile(dh);
}
/**
* test the setters
*/
@Test
public void testSetters() {
DetectorProperties det = new DetectorProperties();
det.setHPxSize(pixelSize);
det.setVPxSize(pixelSize);
det.setPx(imageSizePix[0]);
det.setPy(imageSizePix[1]);
det.setOrientation(orientationMatrix);
det.setOrigin(new Vector3d(50, 50, 300000));
}
@Test
public void testCloningWithSetters() {
DetectorProperties det = new DetectorProperties();
det.setHPxSize(pixelSize);
det.setVPxSize(pixelSize);
det.setPx(imageSizePix[0]);
det.setPy(imageSizePix[1]);
det.setOrientation(orientationMatrix);
det.setOrigin(new Vector3d(50, 50, 300000));
det.setBeamVector(new Vector3d(0, 0, 1));
DetectorProperties newDetector = det.clone();
if (!det.equals(newDetector)) {
Assert.fail("Cloned object not equal");
}
}
@Test
public void testCloning() {
DetectorProperties det = new DetectorProperties(new Vector3d(50, 50, 300000), imageSizePix[0], imageSizePix[1],
pixelSize, pixelSize, orientationMatrix);
DetectorProperties newDetector = det.clone();
if (!det.equals(newDetector)) {
Assert.fail("Cloned object not equal");
}
}
@Test
public void testImageOrientation(){
DetectorProperties det = new DetectorProperties(new Vector3d(50, 50, 300000), imageSizePix[0], imageSizePix[1],
pixelSize, pixelSize, orientationMatrix);
if(!orientationMatrix.equals(det.getOrientation()))
Assert.fail("The orientation matrices are not equal");
}
@Test
public void testBeamCentre() {
DetectorProperties det = new DetectorProperties(detectorOrigin, imageSizePix[0], imageSizePix[1],
pixelSize, pixelSize, orientationMatrix);
double[] bc1 = det.getBeamCentreCoords();
System.out.printf("Initial centre: %f, %f\n", bc1[0], bc1[1]);
bc1[0] -= 75;
bc1[1] += 120;
det.setBeamCentreCoords(bc1);
double[] bc2 = det.getBeamCentreCoords();
Assert.assertEquals("X coord", bc1[0], bc2[0], 1e-7);
Assert.assertEquals("Y coord", bc1[1], bc2[1], 1e-7);
}
@Test
public void testDetectorOrigin() {
DetectorProperties detector = new DetectorProperties(detectorOrigin, beamCentre, imageSizePix[0], imageSizePix[1], pixelSize,
pixelSize, orientationMatrix);
Vector3d newOrigin;
newOrigin = new Vector3d(130, 120, 200);
detector.setOrigin(newOrigin);
assertEquals(detector.pixelPosition(0, 0), newOrigin);
newOrigin = new Vector3d(-130, 120, 200);
detector.setOrigin(newOrigin);
assertEquals(detector.pixelPosition(0, 0), newOrigin);
newOrigin = new Vector3d(130, -120, 200);
detector.setOrigin(newOrigin);
assertEquals(detector.pixelPosition(0, 0), newOrigin);
newOrigin = new Vector3d(130, 120, -200);
detector.setOrigin(newOrigin);
assertEquals(detector.pixelPosition(0, 0), newOrigin);
newOrigin = new Vector3d(-130, -120, 200);
detector.setOrigin(newOrigin);
assertEquals(detector.pixelPosition(0, 0), newOrigin);
newOrigin = new Vector3d(130, -120, -200);
detector.setOrigin(newOrigin);
assertEquals(detector.pixelPosition(0, 0), newOrigin);
newOrigin = new Vector3d(-130, -120, -200);
detector.setOrigin(newOrigin);
assertEquals(detector.pixelPosition(0, 0), newOrigin);
}
/**
* As a general check test the size of the detector a various orientations
*/
@Test
public void testDetectorSize() {
DetectorProperties detector = new DetectorProperties(detectorOrigin, beamCentre, imageSizePix[0], imageSizePix[1], pixelSize,
pixelSize, orientationMatrix);
// detector size for assert
double detSizeX = detector.getDetectorSizeH();
double detSizeY = detector.getDetectorSizeV();
double diagDetSize = Math.sqrt((detSizeX * detSizeX) + (detSizeY * detSizeY));
int[] detectorCorners = { 0, 0, 0, 3072, 3072, 0, 3072, 3072 };
Vector3d px1topx4 = new Vector3d();
px1topx4.sub(detector.pixelPosition(detectorCorners[0], detectorCorners[1]),
detector.pixelPosition(detectorCorners[6], detectorCorners[7]));
assertEquals(diagDetSize, px1topx4.length(), 0.00001);
Matrix3d newOri = detector.getOrientation();
newOri.rotY(1.5);
detector.setOrientation(newOri);
px1topx4.sub(detector.pixelPosition(detectorCorners[0], detectorCorners[1]),
detector.pixelPosition(detectorCorners[6], detectorCorners[7]));
assertEquals(diagDetSize, px1topx4.length(), 0.00001);
detector.setOrigin(new Vector3d(-150, 250, 389));
px1topx4.sub(detector.pixelPosition(detectorCorners[0], detectorCorners[1]),
detector.pixelPosition(detectorCorners[6], detectorCorners[7]));
assertEquals(diagDetSize, px1topx4.length(), 0.00001);
}
@Test
public void testDetectorMethods() {
DetectorProperties detector = new DetectorProperties(detectorOrigin, beamCentre, imageSizePix[0], imageSizePix[1], pixelSize,
pixelSize, orientationMatrix);
Vector3d p = new Vector3d();
Vector3d c = new Vector3d();
for (int x = 0; x < imageSizePix[0]; x++) {
for (int y = 0; y < imageSizePix[1]; y++) {
detector.pixelPosition(x, y, p);
detector.pixelCoords(p, c);
assertEquals(x, c.x, 1);
assertEquals(y, c.y, 1);
}
}
}
/**
* Check that vecmath has active transformation
*/
@Test
public void testMatrixConvention() {
Matrix3d a = new Matrix3d();
double angle = Math.PI/6.;
double answer = -Math.sin(angle);
a.rotX(angle);
Assert.assertEquals("X rotation", answer, a.getM12(), 1e-7);
a.rotY(angle);
Assert.assertEquals("Y rotation", answer, a.getM20(), 1e-7);
a.rotZ(angle);
Assert.assertEquals("Z rotation", answer, a.getM01(), 1e-7);
}
@Test
public void testEulerConversions() {
DetectorProperties det = DetectorProperties.getDefaultDetectorProperties(new int[] {100,100});
double[] angle;
angle = det.getNormalAnglesInDegrees();
Assert.assertEquals("Yaw", 0, angle[0], 1e-7);
Assert.assertEquals("Pitch", 0, angle[1], 1e-7);
Assert.assertEquals("Roll", 0, angle[2], 1e-7);
det.setNormalAnglesInDegrees(30, 25, -35);
angle = det.getNormalAnglesInDegrees();
Assert.assertEquals("Yaw", 30, angle[0], 1e-7);
Assert.assertEquals("Pitch", 25, angle[1], 1e-7);
Assert.assertEquals("Roll", -35, angle[2], 1e-7);
det.setNormalAnglesInDegrees(-95, -65, 103);
angle = det.getNormalAnglesInDegrees();
Assert.assertEquals("Yaw", -95, angle[0], 1e-7);
Assert.assertEquals("Pitch", -65, angle[1], 1e-7);
Assert.assertEquals("Roll", 103, angle[2], 1e-7);
det.setNormalAnglesInDegrees(-95, 90, 103);
angle = det.getNormalAnglesInDegrees();
Assert.assertEquals("Yaw", -95-103+360, angle[0], 1e-7);
Assert.assertEquals("Pitch", 90, angle[1], 1e-7);
Assert.assertEquals("Roll", 0, angle[2], 1e-7);
det.setNormalAnglesInDegrees(-95, -90, 103);
angle = det.getNormalAnglesInDegrees();
Assert.assertEquals("Yaw", -95+103, angle[0], 1e-7);
Assert.assertEquals("Pitch", -90, angle[1], 1e-7);
Assert.assertEquals("Roll", 0, angle[2], 1e-7);
}
@Test
public void testEulerXYZ() {
DetectorProperties det = DetectorProperties.getDefaultDetectorProperties(new int[] {100,100});
det.setOrientationEulerXYZ(Math.toRadians(0.4663), Math.toRadians(-44.01), Math.toRadians(-88.99));
Matrix3d m = det.getOrientation();
double[] row = new double[3];
m.getRow(0, row);
assertArrayEquals(new double[] {0.01268187, -0.99991112, 0.00411266}, row, 1e-4);
m.getRow(1, row);
assertArrayEquals(new double[] {0.71913747, 0.01197841, 0.69476458}, row, 1e-4);
m.getRow(2, row);
assertArrayEquals(new double[] {-0.69475209, -0.00585335, 0.71922547}, row, 1e-4);
}
@Test
public void testEulerZYZ() {
DetectorProperties det = DetectorProperties.getDefaultDetectorProperties(new int[] {100,100});
det.setOrientationEulerZYZ(Math.toRadians(10), Math.toRadians(20), Math.toRadians(25));
Matrix3d m = det.getOrientation();
Matrix3d me = MatrixUtils.createOrientationFromEulerZYZ(10, 20, 25);
MatrixUtils.isClose(me, m, 1e-14, 1e-14);
double[] angles = MatrixUtils.calculateFromOrientationEulerZYZ(m);
assertArrayEquals(new double[] {10, 20, 25}, angles, 1e-4);
}
@Test
public void testBeamCentreDistance() {
DetectorProperties det = new DetectorProperties(new Vector3d(500, 550, 600), 1000, 1100, 1, 1, null);
Vector3d o = det.getOrigin();
Assert.assertEquals("Detector origin, x", 500, o.x, 1e-7);
Assert.assertEquals("Detector origin, y", 550, o.y, 1e-7);
Assert.assertEquals("Detector origin, z", 600, o.z, 1e-7);
double[] c = det.getBeamCentreCoords();
Assert.assertEquals("Beam centre, x", 500, c[0], 1e-7);
Assert.assertEquals("Beam centre, y", 550, c[1], 1e-7);
Assert.assertEquals("Beam centre distance", 600, det.getBeamCentreDistance(), 1e-7);
Assert.assertEquals("Detector distance", 600, det.getDetectorDistance(), 1e-7);
det.setBeamCentreDistance(700);
Assert.assertEquals("Beam centre distance", 700, det.getBeamCentreDistance(), 1e-7);
Assert.assertEquals("Detector distance", 700, det.getDetectorDistance(), 1e-7);
det.setDetectorDistance(600);
Assert.assertEquals("Beam centre distance", 600, det.getBeamCentreDistance(), 1e-7);
Assert.assertEquals("Detector distance", 600, det.getDetectorDistance(), 1e-7);
c = det.getBeamCentreCoords();
det.setNormalAnglesInDegrees(30, 0, 0);
Assert.assertEquals("Beam centre distance", 600, det.getBeamCentreDistance(), 1e-7);
Assert.assertEquals("Detector distance", 600*Math.cos(Math.toRadians(30)), det.getDetectorDistance(), 1e-7);
double[] d = det.getBeamCentreCoords();
Assert.assertEquals("Beam centre, x", c[0], d[0], 1e-7);
Assert.assertEquals("Beam centre, y", c[1], d[1], 1e-7);
}
@Test
public void testDetectorOrientation() {
DetectorProperties det = DetectorProperties.getDefaultDetectorProperties(new int[] {100,100});
Vector3d row = new Vector3d(-1, 0, 0);
double roll = 0;
// check yaw
Assert.assertEquals("Normal to row", 90, Math.toDegrees(det.getNormal().angle(row)), 1e-7);
double yaw = 30;
det.setNormalAnglesInDegrees(yaw, 0, 0);
Vector3d n = det.getNormal();
Assert.assertEquals("Normal to row", 90+yaw, Math.toDegrees(n.angle(row)), 1e-7);
Assert.assertEquals("Normal x", Math.sin(Math.toRadians(yaw)), n.x, 1e-7);
Assert.assertEquals("Normal y", 0, n.y, 1e-7);
Assert.assertEquals("Normal z", -Math.cos(Math.toRadians(yaw)), n.z, 1e-7);
// check pitch
double pitch = 30;
det.setNormalAnglesInDegrees(0, pitch, 0);
n = det.getNormal();
Assert.assertEquals("Normal to row", 90, Math.toDegrees(n.angle(row)), 1e-7);
Assert.assertEquals("Normal to beam", 180-pitch, Math.toDegrees(det.getBeamVector().angle(n)), 1e-7);
Assert.assertEquals("Normal x", 0, n.x, 1e-7);
Assert.assertEquals("Normal y", Math.sin(Math.toRadians(pitch)), n.y, 1e-7);
Assert.assertEquals("Normal z", -Math.cos(Math.toRadians(pitch)), n.z, 1e-7);
det.setNormalAnglesInDegrees(0, 0, 0);
Assert.assertEquals("Image row angle", roll, Math.toDegrees(det.getPixelRow().angle(row)), 1e-7);
Assert.assertEquals("Image col angle", 90-roll, Math.toDegrees(det.getPixelColumn().angle(row)), 1e-7);
roll = 30;
det.setNormalAnglesInDegrees(0, 0, roll);
n = new Vector3d(det.getNormal());
Assert.assertEquals("Normal", 180, Math.toDegrees(det.getBeamVector().angle(n)), 1e-7);
Assert.assertEquals("Image row angle", roll, Math.toDegrees(det.getPixelRow().angle(row)), 1e-7);
Assert.assertEquals("Image col angle", 90-roll, Math.toDegrees(det.getPixelColumn().angle(row)), 1e-7);
roll = 60;
det.setNormalAnglesInDegrees(0, 0, roll);
Assert.assertEquals("Normal", 0, Math.toDegrees(det.getNormal().angle(n)), 1e-7);
Assert.assertEquals("Image row angle", roll, Math.toDegrees(det.getPixelRow().angle(row)), 1e-7);
Assert.assertEquals("Image col angle", 90-roll, Math.toDegrees(det.getPixelColumn().angle(row)), 1e-7);
roll = 120;
det.setNormalAnglesInDegrees(0, 0, roll);
Assert.assertEquals("Normal", 0, Math.toDegrees(det.getNormal().angle(n)), 1e-7);
Assert.assertEquals("Image row angle", roll, Math.toDegrees(det.getPixelRow().angle(row)), 1e-7);
if (roll > 90) {
roll = roll - 90;
} else {
roll = 90 - roll;
}
Assert.assertEquals("Image col angle", roll, Math.toDegrees(det.getPixelColumn().angle(row)), 1e-7);
// test normal is same for any roll...
Vector3d na = getNormal(30, 0, 0);
Vector3d nb = getNormal(0, 30, 0);
Vector3d nc = getNormal(30, 30, 0);
getNormal(0, 0, 30);
n = getNormal(30, 0, 30);
Assert.assertTrue("Normals rolled", n.epsilonEquals(na, 1e-7));
n = getNormal(0, 30, 30);
Assert.assertTrue("Normals rolled", n.epsilonEquals(nb, 1e-7));
n = getNormal(30, 30, 30);
Assert.assertTrue("Normals rolled", n.epsilonEquals(nc, 1e-7));
// check normal to row angle
det.setNormalAnglesInDegrees(0, 0, 0);
Assert.assertEquals("Normal to row", 90, Math.toDegrees(row.angle(det.getNormal())), 1e-7);
det.setNormalAnglesInDegrees(30, 0, roll);
nb = det.getNormal();
Assert.assertEquals("Normals rolled", 0, Math.toDegrees(na.angle(nb)), 1e-7);
// check sequence of normal angle changes through no-intersection cases and its effect on beam centre distance
det.setNormalAnglesInDegrees(70, 0, 0);
double dist = det.getBeamCentreDistance();
double[] centre = det.getBeamCentreCoords();
det.setNormalAnglesInDegrees(90, 0, 0);
Assert.assertTrue("No intersection", Double.isInfinite(det.getBeamCentreDistance()));
double[] centre2 = det.getBeamCentreCoords();
Assert.assertTrue("No intersection", Double.isNaN(centre2[0]));
Assert.assertTrue("No intersection", Double.isNaN(centre2[1]));
det.setNormalAnglesInDegrees(70, 0, 0);
Assert.assertEquals("Restored", dist, det.getBeamCentreDistance(), 1e-7);
centre2 = det.getBeamCentreCoords();
Assert.assertEquals("Restored", centre[0], centre2[0], 1e-7);
Assert.assertEquals("Restored", centre[1], centre2[1], 1e-7);
det.setNormalAnglesInDegrees(70, 5, 0);
dist = det.getBeamCentreDistance();
centre = det.getBeamCentreCoords();
det.setNormalAnglesInDegrees(70, 0, 0);
det.setNormalAnglesInDegrees(90, 0, 0);
det.setNormalAnglesInDegrees(90, 5, 0);
// det.setNormalAnglesInDegrees(70, 0, 0);
det.setNormalAnglesInDegrees(70, 5, 0);
centre2 = det.getBeamCentreCoords();
Assert.assertEquals("Restored", dist, det.getBeamCentreDistance(), 1e-7);
Assert.assertEquals("Restored", centre[0], centre2[0], 1e-7);
Assert.assertEquals("Restored", centre[1], centre2[1], 1e-7);
det.setNormalAnglesInDegrees(90, 0, 0);
Assert.assertEquals("Yaw 90", 90, det.getNormalAnglesInDegrees()[0], 1e-7);
det.setNormalAnglesInDegrees(120, 0, 0);
Assert.assertEquals("Yaw 120", 120, det.getNormalAnglesInDegrees()[0], 1e-7);
det.setNormalAnglesInDegrees(180, 0, 0);
Assert.assertEquals("Yaw 180", 180, det.getNormalAnglesInDegrees()[0], 1e-7);
det.setNormalAnglesInDegrees(185, 0, 0);
Assert.assertEquals("Yaw -175", -175, det.getNormalAnglesInDegrees()[0], 1e-7);
det.setNormalAnglesInDegrees(-120, 0, 0);
Assert.assertEquals("Yaw -120", -120, det.getNormalAnglesInDegrees()[0], 1e-7);
det.setNormalAnglesInDegrees(-180, 0, 0);
Assert.assertEquals("Yaw 180", 180, det.getNormalAnglesInDegrees()[0], 1e-7);
det.setNormalAnglesInDegrees(-185, 0, 0);
Assert.assertEquals("Yaw 175", 175, det.getNormalAnglesInDegrees()[0], 1e-7);
det.setNormalAnglesInDegrees(0, 85, 0);
Assert.assertEquals("Pitch 85", 85, det.getNormalAnglesInDegrees()[1], 1e-7);
det.setNormalAnglesInDegrees(0, 90, 0);
Assert.assertEquals("Pitch 90", 90, det.getNormalAnglesInDegrees()[1], 1e-7);
det.setNormalAnglesInDegrees(0, 95, 0);
Assert.assertEquals("Pitch 85", 85, det.getNormalAnglesInDegrees()[1], 1e-7);
Assert.assertEquals("Yaw 180", 180, det.getNormalAnglesInDegrees()[0], 1e-7);
Assert.assertEquals("Roll 180", 180, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, -85, 0);
Assert.assertEquals("Pitch -85", -85, det.getNormalAnglesInDegrees()[1], 1e-7);
det.setNormalAnglesInDegrees(0, -90, 0);
Assert.assertEquals("Pitch -90", -90, det.getNormalAnglesInDegrees()[1], 1e-7);
det.setNormalAnglesInDegrees(0, -95, 0);
Assert.assertEquals("Pitch 85", -85, det.getNormalAnglesInDegrees()[1], 1e-7);
Assert.assertEquals("Yaw 180", 180, det.getNormalAnglesInDegrees()[0], 1e-7);
Assert.assertEquals("Roll 180", 180, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, 90);
Assert.assertEquals("Roll 90", 90, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, 179);
Assert.assertEquals("Roll 179", 179, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, 180);
Assert.assertEquals("Roll 180", 180, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, 181);
Assert.assertEquals("Roll -179", -179, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, -90);
Assert.assertEquals("Roll -90", -90, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, -179);
Assert.assertEquals("Roll -179", -179, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, -180);
Assert.assertEquals("Roll 180", 180, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, -181);
Assert.assertEquals("Roll 179", 179, det.getNormalAnglesInDegrees()[2], 1e-7);
det.setNormalAnglesInDegrees(0, 0, -90);
Assert.assertEquals("Roll -90", -90, det.getNormalAnglesInDegrees()[2], 1e-7);
}
private Vector3d getNormal(double... angles) {
Matrix3d ta;
Vector3d va;
ta = DetectorProperties.inverseMatrixFromEulerAngles(angles[0], angles[1], angles[2]);
va = new Vector3d(0, 0, -1);
ta.transform(va);
// System.err.println(Arrays.toString(angles) + ": " + va);
return va;
}
public Vector3d findMajor(final Vector3d beam, final Vector3d normal) {
Vector3d u = new Vector3d();
Vector3d v = new Vector3d(-1, 0, 0);
u.cross(normal, beam);
if (u.length() != 0) {
v.cross(u, normal);
v.normalize();
}
return v;
}
@Test
public void testMajorAxis() {
DetectorProperties det = DetectorProperties.getDefaultDetectorProperties(new int[] {100, 100});
final Vector3d beam = det.getBeamVector();
Vector3d major = findMajor(beam, det.getNormal());
double angle = 0;
Assert.assertEquals("Maj x", -1, major.x, 1e-7);
Assert.assertEquals("Maj y", 0, major.y, 1e-7);
Assert.assertEquals("Maj z", 0, major.z, 1e-7);
angle = 30;
det.setNormalAnglesInDegrees(angle, 0, 0);
major = findMajor(beam, det.getNormal());
Assert.assertEquals("Maj x", Math.cos(Math.toRadians(angle)), major.x, 1e-7);
Assert.assertEquals("Maj y", 0, major.y, 1e-7);
Assert.assertEquals("Maj z", Math.sin(Math.toRadians(angle)), major.z, 1e-7);
det.setNormalAnglesInDegrees(0, angle, 0);
major = findMajor(beam, det.getNormal());
Assert.assertEquals("Maj x", 0, major.x, 1e-7);
Assert.assertEquals("Maj y", Math.cos(Math.toRadians(angle)), major.y, 1e-7);
Assert.assertEquals("Maj z", Math.sin(Math.toRadians(angle)), major.z, 1e-7);
det.setNormalAnglesInDegrees(0, 0, angle);
major = findMajor(beam, det.getNormal());
Assert.assertEquals("Maj x", -1, major.x, 1e-7);
Assert.assertEquals("Maj y", 0, major.y, 1e-7);
Assert.assertEquals("Maj z", 0, major.z, 1e-7);
det.setNormalAnglesInDegrees(-angle, 0, 0);
major = findMajor(beam, det.getNormal());
Assert.assertEquals("Maj x", -Math.cos(Math.toRadians(angle)), major.x, 1e-7);
Assert.assertEquals("Maj y", 0, major.y, 1e-7);
Assert.assertEquals("Maj z", Math.sin(Math.toRadians(angle)), major.z, 1e-7);
det.setNormalAnglesInDegrees(0, -angle, 0);
major = findMajor(beam, det.getNormal());
Assert.assertEquals("Maj x", 0, major.x, 1e-7);
Assert.assertEquals("Maj y", -Math.cos(Math.toRadians(angle)), major.y, 1e-7);
Assert.assertEquals("Maj z", Math.sin(Math.toRadians(angle)), major.z, 1e-7);
det.setNormalAnglesInDegrees(0, 0, -angle);
major = findMajor(beam, det.getNormal());
Assert.assertEquals("Maj x", -1, major.x, 1e-7);
Assert.assertEquals("Maj y", 0, major.y, 1e-7);
Assert.assertEquals("Maj z", 0, major.z, 1e-7);
}
@Test
public void testMatrixMultiply() {
Matrix3d a = new Matrix3d();
a.setM01(1);
a.setM10(1);
a.setM22(1);
Matrix3d b = new Matrix3d();
b.setM00(1);
b.setM11(-1);
b.setM22(1);
Matrix3d c = new Matrix3d();
c.mul(b, a);
Assert.assertEquals("M01", 1, c.getM01(), 1e-7);
Assert.assertEquals("M10", -1, c.getM10(), 1e-7);
Assert.assertEquals("M22", 1, c.getM22(), 1e-7);
c.mul(a, b);
Assert.assertEquals("M01", -1, c.getM01(), 1e-7);
Assert.assertEquals("M10", 1, c.getM10(), 1e-7);
Assert.assertEquals("M22", 1, c.getM22(), 1e-7);
// this.mul(other) == this x mul
a.mul(b);
Assert.assertEquals("M01", a.getM01(), c.getM01(), 1e-7);
Assert.assertEquals("M10", a.getM10(), c.getM10(), 1e-7);
Assert.assertEquals("M22", a.getM22(), c.getM22(), 1e-7);
}
@Test
public void testSolidAngle() {
Vector3d a = new Vector3d(1, -1, 1);
Vector3d b = new Vector3d(1, 1, 1);
Vector3d c = new Vector3d(1, -1, -1);
// half of a cube side
double s = DetectorProperties.calculatePlaneTriangleSolidAngle(a, b, c);
Assert.assertEquals(4.*Math.PI/12, s, 1e-12);
// check cos(alpha)^3 for a triangle in y-z that recedes
double alpha = Math.toRadians(24.);
double ca = Math.cos(alpha);
double ta = Math.tan(alpha);
double side = 1;
double x, y;
double factor = ca * ca * ca;
for (x = 200; x < 2000; x += 50) {
y = ta*x;
a.set(x, y, -side);
b.set(x, y, side);
c.set(x, y + side, 0);
s = DetectorProperties.calculatePlaneTriangleSolidAngle(a, b, c);
double r = side/x;
// ratio of solid angle subtended to that estimated by area by distance squared
// tends to cos(alpha)^3
Assert.assertEquals(factor, s/(r*r), factor*r/2.682);
}
}
}