/*- * 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 org.eclipse.dawnsci.analysis.dataset; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import org.eclipse.dawnsci.analysis.dataset.impl.Signal; import org.eclipse.january.asserts.TestUtils; import org.eclipse.january.dataset.Dataset; import org.eclipse.january.dataset.DatasetFactory; import org.eclipse.january.dataset.DoubleDataset; import org.eclipse.january.dataset.Slice; import org.junit.Test; public class SignalTest { /** * Comes from the Ticket SCI#1275 */ @Test public void testSimpleConvolveFilters() { Dataset f = DatasetFactory.zeros(new int[] {10,10}, Dataset.ARRAYFLOAT64); Dataset g = DatasetFactory.zeros(new int[] {3,3}, Dataset.ARRAYFLOAT64); // test against a null filter f.iadd(2); g.set(1, 1, 1); Dataset result = Signal.convolve(f, g, null); assertEquals("Arrays are not equal area", (Double) f.sum(), (Double) result.sum(), 0.1); // set against a zeroed filter g.set(0, 1, 1); result = Signal.convolve(f, g, null); assertEquals("Array not zero size", 0.0, (Double) result.sum(), 0.1); // set against a doubling filter g.set(2, 1, 1); result = Signal.convolve(f, g, null); assertEquals("convolved array not twice the size", (Double)f.sum()*2.0, (Double) result.sum(), 0.1); } /** * Comes from the Ticket SCI#1275 */ @Test public void testConvolveFilters() { Dataset f = DatasetFactory.zeros(new int[] {10,10}, Dataset.ARRAYFLOAT64); Dataset g = DatasetFactory.zeros(new int[] {3,3}, Dataset.ARRAYFLOAT64); // test against a null filter f.iadd(1); g.set(1, 1, 1); g.set(1, 0, 1); g.set(1, 2, 1); g.set(1, 1, 0); g.set(1, 1, 2); Dataset result = Signal.convolve(f, g, null); assertEquals("Element (0,0) is not correct", 0, result.getDouble(0,0), 0.1); assertEquals("Element (1,1) is not correct", 3, result.getDouble(1,1), 0.1); assertEquals("Element (2,2) is not correct", 5, result.getDouble(2,2), 0.1); assertEquals("Element (3,3) is not correct", 5, result.getDouble(3,3), 0.1); assertEquals("Element (6,6) is not correct", 5, result.getDouble(6,6), 0.1); assertEquals("Element (9,9) is not correct", 5, result.getDouble(9,9), 0.1); assertEquals("Element (10,10) is not correct", 3, result.getDouble(10,10), 0.1); assertEquals("Element (11,11) is not correct", 0, result.getDouble(11,11), 0.1); } @Test public void testConvolutionFilter() { Dataset ds = DatasetFactory.createRange(DoubleDataset.class, 1000); Dataset kernel = DatasetFactory.ones(DoubleDataset.class, 27); Dataset result = Signal.convolveToSameShape(ds, kernel, null); assertEquals(120, result.getDouble(2), 0.001); ds = ds.reshape(new int[] {10,100}); kernel = kernel.reshape(3,9); result = Signal.convolveToSameShape(ds, kernel, null); assertEquals(ds.getDouble(5,5)*27, result.getDouble(5,5), 0.001); ds = ds.reshape(new int[] {10,10,10}); kernel = kernel.reshape(3,3,3); result = Signal.convolveToSameShape(ds, kernel, null); assertEquals(ds.getDouble(5,5,5)*27, result.getDouble(5,5,5), 0.001); } /** * Comes from the Ticket SCI#1275 */ @Test public void testConvolve() { Dataset one_d = DatasetFactory.zeros(new int[] {10}, Dataset.ARRAYFLOAT64); Dataset two_d = DatasetFactory.zeros(new int[] {10,10}, Dataset.ARRAYFLOAT64); Dataset three_d = DatasetFactory.zeros(new int[] {10,10,10}, Dataset.ARRAYFLOAT64); @SuppressWarnings("unused") Dataset result; try { result = Signal.convolve(one_d, one_d, null); } catch (Exception e) { fail("Should be able to convolve 2 1D arrays"); } try { result = Signal.convolve(three_d, three_d, null); } catch (Exception e) { fail("Should be able to convolve 2 3D arrays"); } try { result = Signal.convolve(one_d, two_d, null); } catch (IllegalArgumentException e) { // this is the correct exception in this case } catch (Exception e) { e.printStackTrace(); fail("convolving 2 differnt shaped arrays should raise an IllegalArgumentException"); } try { result = Signal.convolve(one_d, three_d, null); } catch (IllegalArgumentException e) { // this is the correct exception in this case } catch (Exception e) { e.printStackTrace(); fail("convolving 2 differnt shaped arrays should raise an IllegalArgumentException"); } try { result = Signal.convolve(two_d, three_d, null); } catch (IllegalArgumentException e) { // this is the correct exception in this case } catch (Exception e) { e.printStackTrace(); fail("convolving 2 differnt shaped arrays should raise an IllegalArgumentException"); } try { result = Signal.convolve(three_d, two_d, null); } catch (IllegalArgumentException e) { // this is the correct exception in this case } catch (Exception e) { e.printStackTrace(); fail("convolving 2 differnt shaped arrays should raise an IllegalArgumentException"); } try { result = Signal.convolve(three_d, one_d, null); } catch (IllegalArgumentException e) { // this is the correct exception in this case } catch (Exception e) { e.printStackTrace(); fail("convolving 2 differnt shaped arrays should raise an IllegalArgumentException"); } } @Test public void testConvolveAll() { Dataset d = DatasetFactory.createRange(20, Dataset.FLOAT64); Dataset k = DatasetFactory.ones(new int[] {5}, Dataset.FLOAT64); Dataset c; Dataset e = DatasetFactory.createFromObject(new double[] {0, 1, 3, 6, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 70, 54, 37, 19}); c = Signal.convolve(d, k, null); TestUtils.assertDatasetEquals(e, c, 1e-7, 1e-9); c = Signal.convolve(k, d, null); TestUtils.assertDatasetEquals(e, c, 1e-7, 1e-9); c = Signal.convolveToSameShape(d, k, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(2, 22)), c, 1e-7, 1e-9); c = Signal.convolveToSameShape(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(2, 22)), c, 1e-7, 1e-9); c = Signal.convolveForOverlap(d, k, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(4, 20)), c, 1e-7, 1e-9); c = Signal.convolveForOverlap(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(4, 20)), c, 1e-7, 1e-9); d = DatasetFactory.createRange(19, Dataset.FLOAT64); e = DatasetFactory.createFromObject(new double[] {0, 1, 3, 6, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 66, 51, 35, 18}); c = Signal.convolve(d, k, null); TestUtils.assertDatasetEquals(e, c, 1e-7, 1e-9); c = Signal.convolve(k, d, null); TestUtils.assertDatasetEquals(e, c, 1e-7, 1e-9); c = Signal.convolveToSameShape(d, k, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(2, 21)), c, 1e-7, 1e-9); c = Signal.convolveToSameShape(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(2, 21)), c, 1e-7, 1e-9); c = Signal.convolveForOverlap(d, k, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(4, 19)), c, 1e-7, 1e-9); c = Signal.convolveForOverlap(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(4, 19)), c, 1e-7, 1e-9); } @Test public void testCorrelateAll() { Dataset d = DatasetFactory.createRange(20, Dataset.FLOAT64); Dataset k = DatasetFactory.ones(new int[] {5}, Dataset.FLOAT64); Dataset c; Dataset e = DatasetFactory.createFromObject(new double[] {0, 1, 3, 6, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 70, 54, 37, 19}); c = Signal.correlate(d, k, null); TestUtils.assertDatasetEquals(e, c, 1e-7, 1e-9); c = Signal.correlateToSameShape(d, k, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(2, 22)), c, 1e-7, 1e-9); c = Signal.correlateForOverlap(d, k, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(4, 20)), c, 1e-7, 1e-9); c = Signal.correlate(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(null, null, new int[] {-1}), c, 1e-7, 1e-9); c = Signal.correlateToSameShape(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(21, 1, -1)), c, 1e-7, 1e-9); c = Signal.correlateForOverlap(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(19, 3, -1)), c, 1e-7, 1e-9); d = DatasetFactory.createRange(19, Dataset.FLOAT64); e = DatasetFactory.createFromObject(new double[] {0, 1, 3, 6, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 66, 51, 35, 18}); c = Signal.correlate(d, k, null); TestUtils.assertDatasetEquals(e, c, 1e-7, 1e-9); c = Signal.correlateToSameShape(d, k, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(2, 21)), c, 1e-7, 1e-9); c = Signal.correlateForOverlap(d, k, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(4, 19)), c, 1e-7, 1e-9); c = Signal.correlate(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(null, null, new int[] {-1}), c, 1e-7, 1e-9); c = Signal.correlateToSameShape(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(20, 1, -1)), c, 1e-7, 1e-9); c = Signal.correlateForOverlap(k, d, null); TestUtils.assertDatasetEquals(e.getSlice(new Slice(18, 3, -1)), c, 1e-7, 1e-9); } @Test public void testWindows() { Dataset w; w = Signal.hammingWindow(10); TestUtils.assertDatasetEquals(DatasetFactory.createFromObject(new double[] { 0.080000, 0.187620, 0.460122, 0.770000, 0.972259, 0.972259, 0.770000, 0.460122, 0.187620, 0.080000 }), w, 1e-5, 1e-6); w = Signal.hammingWindow(11); TestUtils.assertDatasetEquals(DatasetFactory.createFromObject(new double[] { 0.08, 0.16785218, 0.39785218, 0.68214782, 0.91214782, 1., 0.91214782, 0.68214782, 0.39785218, 0.16785218, 0.08 }), w, 1e-5, 1e-6); } }