package uk.ac.diamond.scisoft.analysis.peakfinding.peakfinders;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.eclipse.dawnsci.analysis.api.peakfinding.IPeakFinder;
import org.eclipse.dawnsci.analysis.api.peakfinding.IPeakFinderParameter;
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.IDataset;
import org.eclipse.january.dataset.Slice;
import org.junit.Assert;
import org.junit.Test;
/**
*
* TODO: large dataset tests
*
* @author Dean P. Ottewell
*
*/
public class AutoPeakFinderTest {
@Test
public void nameCheck() {
IPeakFinder ampd = new AutoPeakFinder();
assertEquals("Auto Peakfinder", ampd.getName());
}
@Test
public void parametersCheck() throws Exception {
IPeakFinder ampd = new AutoPeakFinder();
Map<String, IPeakFinderParameter> paramSet = ampd.getParameters();
Assert.assertEquals(1, paramSet.size());
assertTrue(paramSet.containsKey("Fit Degree"));
}
@Test
public void noisyPeriodicDataTest() {
IPeakFinder ampd = new AutoPeakFinder();
DoubleDataset xAxisRange = (DoubleDataset) DatasetFactory.createRange(0, 5.0, 0.1, Dataset.FLOAT64);
DoubleDataset yData = PeakyData.intialisePeakData(xAxisRange);
// Calculate the expected x-coordinate
Double expectedPos = 0.3785 * PeakyData.getxAxisMax();
Double foundPos;
// Find the x-coordinate of the found peak
TreeMap<Integer, Double> foundPeaks = (TreeMap<Integer, Double>) ampd.findPeaks(xAxisRange, yData, null);
for (Integer i : foundPeaks.keySet()) {
foundPos = xAxisRange.getDouble(i);
// Yes, it finds the wrong position.
// Assert.assertEquals(expectedPos, foundPos, 0.35);
}
}
@Test
public void singlePeakSmooth() {
IPeakFinder ampd = new AutoPeakFinder();
Dataset xData = PeakyData.getxAxisRange();
Dataset yData = PeakyData.makeGauPeak().calculateValues(xData);
// Calculate the expected x-coordinate
Double expectedPos = 0.3785 * PeakyData.getxAxisMax();
Double foundPos;
// Find the x-coordinate of the found peak
TreeMap<Integer, Double> foundPeaks = (TreeMap<Integer, Double>) ampd.findPeaks(xData, yData, null);
//We haven't found any peaks as a result of this algorithm not suitable for smooth single peak data
Assert.assertEquals(0, foundPeaks.size());
}
@Test
public void singlePeakFindNoisy() {
AutoPeakFinder ampd = new AutoPeakFinder();
Dataset xAxisRange = PeakyData.getxAxisRange();
Dataset yData = PeakyData.makeGauLorPeaks().calculateValues(xAxisRange);
int trimEnd = (int) (xAxisRange.getSize() * .7);
int trimStart = (int) (xAxisRange.getSize() * .2);
Slice slice = new Slice(trimStart, trimEnd);
xAxisRange = xAxisRange.getSlice(slice);
yData = (DoubleDataset) yData.getSlice(slice);
// Calculate the expected x-coordinate
Double expectedPos = 0.3785 * PeakyData.getxAxisMax();
Double foundPos;
// Find the x-coordinate of the found peak
TreeMap<Integer, Double> foundPeaks = (TreeMap<Integer, Double>) ampd.findPeaks(xAxisRange, yData, null);
// We need the set to have a length of 1 for the next bit..
assertEquals(1, foundPeaks.size());
for (Integer i : foundPeaks.keySet()) {
foundPos = xAxisRange.getDouble(i);
// Found position within uncretainy due to noise.
assertEquals(expectedPos, foundPos, 5);
}
}
@Test
public void plateauDataTest() {
AutoPeakFinder ampd = new AutoPeakFinder();
int dataSz = 50;
Dataset xData = DatasetFactory.ones(dataSz);
Dataset yData = DatasetFactory.ones(dataSz);
TreeMap<Integer, Double> foundPeaks = (TreeMap<Integer, Double>) ampd.findPeaks(xData, yData, null);
assertTrue(foundPeaks.size() < 1); // Check no peaks were found
}
@Test
public void exampleDataTest() {
AutoPeakFinder ampd = new AutoPeakFinder();
ExamplePeakData peaks = new ExamplePeakData();
DoubleDataset xData = (DoubleDataset) peaks.getxData();
DoubleDataset yData = (DoubleDataset) peaks.getyData();
TreeMap<Integer, Double> foundPeaks = (TreeMap<Integer, Double>) ampd.findPeaks(xData, yData, null);
List<Double> expectedPeaksIdx = peaks.expectedPeakValues();
//Check gets similar amount of peaks first - Degree of size might detect or miss a couple extra peaks
assertEquals(expectedPeaksIdx.size(), foundPeaks.size(), 50);
}
@Test
public void generateLocalMaximumScalarTest() {
AutoPeakFinder ampd = new AutoPeakFinder();
int[] shp = new int[] { 6, 6 };
DoubleDataset data = DatasetFactory.ones(shp);
int w = 2;
int h = 2;
IDataset mtx = ampd.generateLMS(data, w, h);
int[] actualShp = mtx.getShape();
assertEquals(w, actualShp[0]);
assertEquals(h, actualShp[1]);
assertEquals(w * h, mtx.getSize());
// Check all values are in between 0 - 2
assertEquals(mtx.getSize(), DatasetUtils.findIndexLessThan((Dataset) mtx, 0));
assertEquals(mtx.getSize(), DatasetUtils.findIndexGreaterThan((Dataset) mtx, 2));
// Check there are zeros?? need test data to do this and doesnt have to
// be zeros
}
@Test
public void detrendSignalTest() {
// TODO: Need signal to detrend... What test could I do for this??
AutoPeakFinder ampd = new AutoPeakFinder();
Dataset xData = (DoubleDataset) DatasetFactory.createRange(0, 100, 0.01, Dataset.FLOAT64);
Dataset yData = PeakyData.makeGauPeak().calculateValues(xData);
IDataset results = ampd.detrendSignal(xData, yData, 3);
//Check doesnt break results
assertTrue(results.getSize() == xData.getSize());
//The result detrend the yData should results in some change. None means no detrending happened.
assertFalse(yData.equals(results));
}
@Test
public void sizeMattersTest() {
// TODO: test if can handle large datasets
// TODO: set this by changing the peakyData max size variable and seeing whats resulted
AutoPeakFinder ampd = new AutoPeakFinder();
Dataset xData = DatasetFactory.createRange(0, 100.0, 0.01, Dataset.FLOAT64);
Dataset yData = PeakyData.makeGauLorPeaks().calculateValues(xData);
TreeMap<Integer, Double> expectedPeaks = (TreeMap<Integer, Double>) ampd.findPeaks(xData, yData, 10);
assertTrue(expectedPeaks.size() > 1); // Check has found values,
// therefore doesnt crash with
// large sizes
}
}