/*- * Copyright 2015 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.io; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.dawnsci.analysis.api.diffraction.DetectorProperties; import org.eclipse.dawnsci.analysis.api.tree.DataNode; import org.eclipse.dawnsci.analysis.api.tree.GroupNode; import org.eclipse.dawnsci.analysis.api.tree.Node; import org.eclipse.dawnsci.analysis.api.tree.Tree; import org.eclipse.dawnsci.analysis.tree.TreeFactory; import org.eclipse.january.dataset.Dataset; import org.eclipse.january.dataset.DatasetFactory; import org.eclipse.january.dataset.ILazyDataset; import org.eclipse.january.dataset.ShapeUtils; import org.eclipse.january.metadata.AxesMetadata; import org.junit.Assert; import org.junit.Test; import uk.ac.diamond.scisoft.analysis.diffraction.MatrixUtils; public class NexusTreeUtilsTest { public static void addNXclass(Node node, String nxClass) { node.addAttribute(TreeFactory.createAttribute(NexusTreeUtils.NX_CLASS, nxClass)); } class AxisDataset { Dataset axis; int dim; int[] indices; public AxisDataset(int dim, Dataset axis, int... indices) { this.axis = axis; this.dim = dim; this.indices = indices; } } @Test public void testParseNXdataA() { int[] shape = new int[] {100}; Dataset signal = DatasetFactory.ones(shape, Dataset.INT16); signal.setName("data"); List<AxisDataset> axes = new ArrayList<>(); Dataset axis; axis = DatasetFactory.createRange(shape[0], Dataset.INT16); axis.setName("x"); axes.add(new AxisDataset(0, axis, 0)); GroupNode group = createNXdata(signal, axes); checkMetadata(group, signal); } @Test public void testParseNXdataB() { int[] shape = new int[] {100, 20}; Dataset signal = DatasetFactory.ones(shape, Dataset.INT16); signal.setName("data"); List<AxisDataset> axes = new ArrayList<>(); Dataset axis; axis = DatasetFactory.createRange(shape[0], Dataset.INT16); axis.setName("time"); axes.add(new AxisDataset(0, axis, 0)); axis = DatasetFactory.createRange(shape[1], Dataset.INT16); axis.setName("pressure"); axes.add(new AxisDataset(1, axis, 1)); axis = DatasetFactory.createRange(shape[1], Dataset.INT16); axis.setName("temperature"); axes.add(new AxisDataset(-1, axis, 1)); GroupNode group = createNXdata(signal, axes); checkMetadata(group, signal); } @Test public void testParseNXdataC() { int[] shape = new int[] {1000, 10000}; Dataset signal = DatasetFactory.ones(shape, Dataset.INT16); signal.setName("det"); List<AxisDataset> axes = new ArrayList<>(); Dataset axis; axis = DatasetFactory.createRange(shape[0], Dataset.INT16); axis.setName("pressure"); axes.add(new AxisDataset(0, axis, 0)); axis = DatasetFactory.createRange(shape[1], Dataset.INT16); axis.setName("tof"); axes.add(new AxisDataset(1, axis, 1)); GroupNode group = createNXdata(signal, axes); checkMetadata(group, signal); } @Test public void testParseNXdataD() { int[] shape = new int[] {100, 5, 40}; Dataset signal = DatasetFactory.ones(shape, Dataset.INT16); signal.setName("det"); List<AxisDataset> axes = new ArrayList<>(); Dataset axis; axis = DatasetFactory.createRange(shape[0]*shape[1], Dataset.INT16).reshape(shape[0], shape[1]); axis.setName("x"); axes.add(new AxisDataset(0, axis, 0, 1)); axis = DatasetFactory.createRange(shape[0]*shape[1], Dataset.INT16).reshape(shape[0], shape[1]); axis.setName("y"); axes.add(new AxisDataset(1, axis, 0, 1)); axis = DatasetFactory.createRange(shape[2], Dataset.INT16); axis.setName("tof"); axes.add(new AxisDataset(2, axis, 2)); GroupNode group = createNXdata(signal, axes); checkMetadata(group, signal); } @Test public void testParseNXdataE() { int[] shape = new int[] {50, 5, 1024}; Dataset signal = DatasetFactory.ones(shape, Dataset.INT16); signal.setName("det1"); List<AxisDataset> axes = new ArrayList<>(); Dataset axis; axis = DatasetFactory.createRange(shape[0], Dataset.INT16); axis.setName("polar_angle_set"); axes.add(new AxisDataset(0, axis, 0)); axis = DatasetFactory.createRange(shape[1], Dataset.INT16); axis.setName("frame_number"); axes.add(new AxisDataset(1, axis, 1)); axis = DatasetFactory.createRange(shape[0]*shape[1], Dataset.INT16).reshape(shape[0], shape[1]); axis.setName("polar_angle_rbv"); axes.add(new AxisDataset(-1, axis, 0, 1)); axis = DatasetFactory.createRange(shape[0]*shape[1], Dataset.INT16).reshape(shape[0], shape[1]); axis.setName("time"); axes.add(new AxisDataset(-1, axis, 0, 1)); GroupNode group = createNXdata(signal, axes); checkMetadata(group, signal); } private static GroupNode createNXdata(Dataset signal, List<AxisDataset> axes) { long count = 0; GroupNode group = TreeFactory.createGroupNode(count++); addNXclass(group, NexusTreeUtils.NX_DATA); DataNode dNode; dNode = TreeFactory.createDataNode(count++); dNode.setDataset(signal); group.addDataNode(signal.getName(), dNode); group.addAttribute(TreeFactory.createAttribute(NexusTreeUtils.NX_SIGNAL, signal.getName())); String[] axisArray = new String[signal.getRank()]; Arrays.fill(axisArray, NexusTreeUtils.NX_AXES_EMPTY); for (AxisDataset axis : axes) { dNode = TreeFactory.createDataNode(count++); dNode.setDataset(axis.axis); String n = axis.axis.getName(); group.addDataNode(n, dNode); if (axis.dim >= 0) { axisArray[axis.dim] = n; } group.addAttribute(TreeFactory.createAttribute(n + NexusTreeUtils.NX_INDICES_SUFFIX, axis.indices)); } group.addAttribute(TreeFactory.createAttribute(NexusTreeUtils.NX_AXES, axisArray)); return group; } private static void checkMetadata(GroupNode group, Dataset signal) { Assert.assertTrue(NexusTreeUtils.parseNXdataAndAugment(group)); List<AxesMetadata> amds; try { amds = signal.getMetadata(AxesMetadata.class); Assert.assertTrue(amds != null); AxesMetadata amd = amds.get(0); int[] shape = signal.getShapeRef(); int rank = shape.length; for (int i = 0; i < rank; i++) { ILazyDataset[] ds = amd.getAxis(i); for (ILazyDataset l : ds) { Assert.assertTrue(ShapeUtils.areShapesBroadcastCompatible(l.getShape(), shape)); } } } catch (Exception e) { } } @Test public void test2014Axes() throws Exception { NexusHDF5Loader loader = new NexusHDF5Loader(); loader.setFile("testfiles/gda/analysis/io/NexusLoaderTest/nxdata.nxs"); Tree t = loader.loadTree(); GroupNode g = t.getGroupNode().getGroupNode("entry1").getGroupNode("complex"); ILazyDataset d = g.getDataNode("detector").getDataset(); Assert.assertArrayEquals(new int[] {5, 6, 10, 20}, d.getShape()); AxesMetadata amd = d.getMetadata(AxesMetadata.class).get(0); ILazyDataset[] a; a = amd.getAxis(0); Assert.assertEquals(3, a.length); Assert.assertEquals("x", a[0].getName()); Assert.assertArrayEquals(new int[] {5, 1, 1, 1}, a[0].getShape()); Assert.assertEquals("y", a[1].getName()); Assert.assertArrayEquals(new int[] {5, 6, 1, 1}, a[1].getShape()); Assert.assertEquals("temp", a[2].getName()); Assert.assertArrayEquals(new int[] {5, 6, 1, 1}, a[2].getShape()); a = amd.getAxis(1); Assert.assertEquals(2, a.length); Assert.assertEquals("y", a[0].getName()); Assert.assertArrayEquals(new int[] {5, 6, 1, 1}, a[0].getShape()); Assert.assertEquals("temp", a[1].getName()); Assert.assertArrayEquals(new int[] {5, 6, 1, 1}, a[1].getShape()); } private static final double TOL = 1e-14; @Test public void testNXDetectorCreationAndParsing() { DetectorProperties det = DetectorProperties.getDefaultDetectorProperties(new int[] {200,100}); det.setHPxSize(det.getHPxSize() * 2); det.setOrientationEulerZYZ(Math.toRadians(10), Math.toRadians(20), Math.toRadians(25)); System.out.println("Fast pixel direction = " + det.getPixelRow()); System.out.println("Slow pixel direction = " + det.getPixelColumn()); GroupNode nxd = NexusTreeUtils.createNXDetector(det); GroupNode instr = TreeFactory.createGroupNode(0); instr.addGroupNode("detector", nxd); Tree tree = TreeFactory.createTree(0, null); tree.setGroupNode(instr); DetectorProperties dp = NexusTreeUtils.parseDetector("/detector", tree, 0)[0]; MatrixUtils.isClose(det.getBeamVector(), dp.getBeamVector(), TOL, TOL); MatrixUtils.isClose(det.getOrigin(), dp.getOrigin(), TOL, TOL); MatrixUtils.isClose(det.getOrientation(), dp.getOrientation(), TOL, TOL); Assert.assertEquals(det.getPx(), dp.getPx()); Assert.assertEquals(det.getPy(), dp.getPy()); Assert.assertEquals(det.getHPxSize(), dp.getHPxSize(), TOL); Assert.assertEquals(det.getVPxSize(), dp.getVPxSize(), TOL); } }