/* * 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.dawnsci.surfacescatter; import java.util.Arrays; import java.util.Comparator; import org.apache.commons.math3.analysis.interpolation.SplineInterpolator; import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction; import org.eclipse.dawnsci.analysis.dataset.roi.ROISliceUtils; 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.IntegerDataset; public class PolynomialInterpolator1D { public static IDataset interpolate(IDataset oldx, IDataset oldy, IDataset newx) { //TODO more sanity checks on inputs DoubleDataset dx = (DoubleDataset)DatasetUtils.cast(oldx,Dataset.FLOAT64); DoubleDataset dy = (DoubleDataset)DatasetUtils.cast(oldy,Dataset.FLOAT64); boolean sorted = true; double maxtest = dx.getDouble(0); int count = dx.getSize(); for (int i = 1; i < count; i++) { if (maxtest > dx.getDouble(i)) { sorted = false; break; } maxtest = dx.getDouble(i); } double[] sortedx = null; double[] sortedy = null; if (!sorted) { IntegerDataset sIdx = getIndiciesOfSorted(dx); sortedx = new double[dx.getData().length]; sortedy = new double[dy.getData().length]; for (int i = 0 ; i < sIdx.getSize(); i++) { sortedx[i] = dx.getDouble(sIdx.get(i)); sortedy[i] = dy.getDouble(sIdx.get(i)); } } else { sortedx = dx.getData(); sortedy = dy.getData(); } SplineInterpolator si = new SplineInterpolator(); PolynomialSplineFunction poly = si.interpolate(sortedx,sortedy); Dataset newy = DatasetFactory.zeros(newx.getShape(), Dataset.FLOAT64); count = newy.getSize(); newy.setName(oldy.getName()+"_interpolated"); for (int i = 0; i < count; i++) { newy.set(poly.value(newx.getDouble(i)),i); } return newy; } public static IntegerDataset getIndiciesOfSorted(final IDataset d) { Integer[] dBox = new Integer[d.getSize()]; for (int i = 0; i < dBox.length; i++) dBox[i] = i; Arrays.sort(dBox, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { double dif = d.getDouble(o1)-d.getDouble(o2); return dif > 0 ? (int)Math.ceil(dif) : (int)Math.floor(dif); } }); int[] dint = new int[d.getSize()]; for (int i = 0; i < dBox.length; i++) dint[i] = dBox[i]; return DatasetFactory.createFromObject(IntegerDataset.class, dint, null); } public static int[] getCommonRangeIndicies(IDataset x1, IDataset x2) { //TODO checks for no overlap etc double max1 = x1.max().doubleValue(); double min1 = x1.min().doubleValue(); double max2 = x2.max().doubleValue(); double min2 = x2.min().doubleValue(); double max = max1 < max2 ? max1 : max2; double min = min1 > min2 ? min1 : min2; //TODO max needs to be 1 lower, min needs to be 1 higher int maxpos = ROISliceUtils.findPositionOfClosestValueInAxis(x1, max); int minpos = ROISliceUtils.findPositionOfClosestValueInAxis(x1, min); return new int[]{minpos+1, maxpos-1}; } }