package uk.ac.diamond.scisoft.xpdf.test;
import static org.junit.Assert.*;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetFactory;
import org.eclipse.january.dataset.DatasetUtils;
import org.eclipse.january.dataset.DoubleDataset;
import org.eclipse.january.dataset.Maths;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import uk.ac.diamond.scisoft.xpdf.XPDFScaled2DCalculation;
public class XPDFScaled2DCalculationTest {
Dataset theta, phi, fullSize, fullSize1D;
final int nx = 4096, ny = 2048, nMax = 512;
@Before
public void setUp() throws Exception {
// Set up the full size arrays
// One dimensional arrays
theta = Maths.multiply(DatasetFactory.createRange(DoubleDataset.class, 0.5, ny+0.5, 1.0), Math.PI/ny);
phi = Maths.multiply(DatasetFactory.createRange(DoubleDataset.class, 0.5, nx+0.5, 1.0), 2*Math.PI/nx);
// spread to two dimensions
theta = DatasetUtils.repeat(theta.reshape(1, ny), new int[]{nx}, 0);
phi = DatasetUtils.repeat(phi.reshape(nx, 1), new int[]{ny}, 1);
fullSize = realY36(phi, theta);
fullSize1D = realY06(theta);
}
@After
public void tearDown() throws Exception {
}
@Test
public void testRun() {
XPDFScaled2DCalculation why36 = new XPDFScaled2DCalculation(nMax) {
@Override
protected Dataset calculate(Dataset phi, Dataset theta) {
return realY36(phi, theta);
}
};
Dataset scaled = why36.run(phi, theta);
Dataset difference = Maths.subtract(scaled, fullSize);
Dataset squaredDifference = Maths.square(difference);
double rmsDifference = Math.sqrt((double) squaredDifference.mean());
double maxError = 5e-2;
assertTrue("Difference in scaled 2D calculation too large: " + rmsDifference, rmsDifference < maxError);
}
@Test
public void testRunTwoTheta() {
XPDFScaled2DCalculation why06 = new XPDFScaled2DCalculation(nMax) {
@Override
protected Dataset calculateTwoTheta(Dataset theta) {
return realY06(theta);
}
};
Dataset scaled = why06.runTwoTheta(theta);
Dataset difference = Maths.subtract(scaled, fullSize1D);
Dataset squaredDifference = Maths.square(difference);
double rmsDifference = Math.sqrt((double) squaredDifference.mean());
double maxError = 5e-2;
assertTrue("Difference in scaled 1D calculation too large: " + rmsDifference, rmsDifference < maxError);
}
// ℝe(Y³₆(θ, φ))
private Dataset realY36(Dataset phi, Dataset theta) {
double leader = -1/32.*Math.sqrt(1365/Math.PI);
// -1/32 √(1365/π) cos 3φ sin³ θ (11 cos³ θ - 3 cos θ)
return Maths.multiply(
leader,
Maths.multiply(
Maths.cos(Maths.multiply(3, phi)),
Maths.multiply(
Maths.power(Maths.sin(theta), 3),
Maths.subtract(
Maths.multiply(11, Maths.power(Maths.cos(theta), 3)),
Maths.multiply(3, Maths.cos(theta))))));
}
// Y⁰₆(θ, φ)
private Dataset realY06(Dataset theta) {
double leader = 1/32.*Math.sqrt(13/Math.PI);
Dataset cosSquared = Maths.square(Maths.cos(theta));
// 1/32 √(13/π) (231 cos⁶ θ - 315 cos⁴ θ + 105 cos² θ - 5), evaluated using Horner's scheme
return Maths.multiply(
leader,
Maths.add(-5, Maths.multiply(cosSquared,
Maths.add(105, Maths.multiply(cosSquared,
Maths.add(-315, Maths.multiply(cosSquared,
231
))
))
))
);
}
}