/* * 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 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.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import uk.ac.diamond.scisoft.analysis.DoubleUtils; public class QSpaceTest { 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 }; private static DetectorProperties detprops; private static DiffractionCrystalEnvironment diffexp; private static QSpace qspace; @BeforeClass public static void setUp() { Matrix3d orientn = new Matrix3d(); orientn.setIdentity(); detprops = new DetectorProperties(new Vector3d(origin), ishape[1], ishape[0], pxdim[1], pxdim[0], orientn); diffexp = new DiffractionCrystalEnvironment(wavelength); qspace = new QSpace(detprops, diffexp); } @Test public void testQShape() { Vector3d qa = qspace.getInitialWavevector(); Assert.assertTrue("q " + qa.length() + " not equal " + (2*Math.PI/wavelength), DoubleUtils.equalsWithinTolerance(qa.length(), 2*Math.PI/wavelength, 1e-4)); // fake a pixel coordinate so 2*sin(theta) = 1 or theta = 30 degrees // i.e. equilateral triangle int[] bp = detprops.pixelCoords(detprops.getBeamCentrePosition()); // System.out.println("Beam on detector is " + Arrays.toString(bp)); double projlen = Math.tan(Math.toRadians(60.))*origin[2]; // System.out.println("coords are " + (projlen/pxdim[0]) + ", 0"); // System.out.println("coords are 0, " + (projlen/pxdim[1])); qa = qspace.qFromPixelPosition(bp[0] + projlen/pxdim[0], bp[1]); Assert.assertTrue("q " + qa.length() + " not equal " + (2*Math.PI/wavelength), DoubleUtils.equalsWithinTolerance(qa.length(), 2*Math.PI/wavelength, 1e-4)); qa = qspace.qFromPixelPosition(bp[0], bp[1]+projlen/pxdim[1]); Assert.assertTrue("q " + qa.length() + " not equal " + (2*Math.PI/wavelength), DoubleUtils.equalsWithinTolerance(qa.length(), 2*Math.PI/wavelength, 1e-4)); } @Test public void testPixelPositions() { double ttheta = Math.toRadians(11.5); double rho = origin[2]*Math.tan(ttheta); double dphi = 45.; 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]); Vector3d qa = qspace.qFromPixelPosition(x, y); Vector3d ta = new Vector3d(); qspace.pixelPosition(qa, ta); // System.out.println("At " + x + "," + y + ", q: " + qa + "; value = " + (phi+30) + "; at " + ta.x + "," + ta.y); Assert.assertEquals("x is wrong", x, ta.x, 1e-6); Assert.assertEquals("y is wrong", y, ta.y, 1e-6); } } @Test public void testScatteringAngles() { double ttheta = Math.toRadians(11.5); double rho = origin[2]*Math.tan(ttheta); double dphi = 45.; 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]); Vector3d qa = qspace.qFromPixelPosition(x, y); double pixdelta = Math.max(pxdim[0], pxdim[1])/origin[2]; // maximum angle subtended by a single pixel Assert.assertEquals(ttheta, qspace.scatteringAngle(qa), pixdelta); } } }