package org.dawnsci.surfacescatter; import java.util.ArrayList; 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 uk.ac.diamond.scisoft.analysis.dataset.function.Interpolation1D; import uk.ac.diamond.scisoft.analysis.fitting.Fitter; import uk.ac.diamond.scisoft.analysis.fitting.functions.Polynomial; public class SplineInterpolationTracker { public static ArrayList<double[][]> interpolatedTrackerLenPtArray (ArrayList<double[][]> boxes, Dataset xValues ){ Dataset xpts = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); Dataset ypts = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); Dataset xlens = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); Dataset ylens = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); Dataset xVals = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); for(int ty = 0; ty<boxes.size(); ty++){ double[][] consideredBox = boxes.get(ty); xpts.set(consideredBox[1][0], ty); ypts.set(consideredBox[1][1], ty); xlens.set(consideredBox[0][0], ty); ylens.set(consideredBox[0][1], ty); xVals.set(consideredBox[2][1], ty); } ArrayList<double[][]> output =new ArrayList<>(); Dataset calculatedXptsDat = Interpolation1D.splineInterpolation(xVals, xpts, xValues); Dataset calculatedYptsDat = Interpolation1D.splineInterpolation(xVals, ypts, xValues); Dataset calculatedXlenDat = Interpolation1D.splineInterpolation(xVals, xlens, xValues); Dataset calculatedYlenDat = Interpolation1D.splineInterpolation(xVals, ylens, xValues); for(int lj = 0; lj<xValues.getSize(); lj++){ double[][] localOutput = new double[2][]; localOutput[0] = new double[2]; localOutput[1] = new double[2]; localOutput[0][0] = calculatedXlenDat.getDouble(lj); localOutput[0][1] = calculatedYlenDat.getDouble(lj); localOutput[1][0] = calculatedXptsDat.getDouble(lj); localOutput[1][1] = calculatedYptsDat.getDouble(lj); output.add(localOutput); } return output; } public ArrayList<double[][]> interpolatedTrackerLenPtArray1 (ArrayList<double[][]> boxes, Dataset xValues ){ Dataset xpts = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); Dataset ypts = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); Dataset xlens = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); Dataset ylens = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); Dataset xVals = DatasetFactory.zeros(new int[] {boxes.size()}, Dataset.ARRAYFLOAT64); for(int ty = 0; ty<boxes.size(); ty++){ double[][] consideredBox = boxes.get(ty); xpts.set(consideredBox[1][0], ty); ypts.set(consideredBox[1][1], ty); xlens.set(consideredBox[0][0], ty); ylens.set(consideredBox[0][1], ty); xVals.set(consideredBox[2][1], ty); } ArrayList<double[][]> output =new ArrayList<>(); Dataset calculatedXptsDat = splineInterpolationExtrapolation(xVals, xpts, xValues); Dataset calculatedYptsDat = splineInterpolationExtrapolation(xVals, ypts, xValues); Dataset calculatedXlenDat = splineInterpolationExtrapolation(xVals, xlens, xValues); Dataset calculatedYlenDat = splineInterpolationExtrapolation(xVals, ylens, xValues); for(int lj = 0; lj<xValues.getSize(); lj++){ double[][] localOutput = new double[2][]; localOutput[0] = new double[2]; localOutput[1] = new double[2]; localOutput[0][0] = calculatedXlenDat.getDouble(lj); localOutput[0][1] = calculatedYlenDat.getDouble(lj); localOutput[1][0] = calculatedXptsDat.getDouble(lj); localOutput[1][1] = calculatedYptsDat.getDouble(lj); output.add(localOutput); } return output; } public Dataset splineInterpolationExtrapolation (Dataset xValues, Dataset yValues, Dataset targetValues){ ////targetValues may contain values outside of the range of xValues. We need to sort them out. ArrayList<Double> aboveRangeValues = new ArrayList<>(); ArrayList<Double> belowRangeValues = new ArrayList<>(); ArrayList<Double> inRangeValues = new ArrayList<>(); Dataset output = DatasetFactory.zeros(DoubleDataset.class, new int[] {targetValues.getSize()}); double lowestValueOfXValues = findDatasetMin(xValues); System.out.println( "lowestValueOfXValues: " + lowestValueOfXValues); double highestValueOfXValues = findDatasetMax(xValues); System.out.println( "highestValueOfXValues: " + highestValueOfXValues); double secondLowestValueOfXValues = findDataset2ndToMin(xValues); System.out.println( "secondLowestValueOfXValues: " + secondLowestValueOfXValues); double secondHighestValueOfXValues = findDataset2ndToMax(xValues); System.out.println( "secondHighestValueOfXValues: " + secondHighestValueOfXValues); double highEndLastStep = highestValueOfXValues - secondHighestValueOfXValues; double highEndLastStepIncrement = highEndLastStep/100; double lowEndLastStep = secondLowestValueOfXValues - lowestValueOfXValues; double lowEndLastStepIncrement = lowEndLastStep/100; for(int i =0 ; i < targetValues.getSize(); i++){ if(targetValues.getDouble(i) <= lowestValueOfXValues){ belowRangeValues.add(targetValues.getDouble(i)); } else if(targetValues.getDouble(i) >= highestValueOfXValues){ aboveRangeValues.add(targetValues.getDouble(i)); } else{ inRangeValues.add(targetValues.getDouble(i)); } } Dataset inRangeInput = DatasetFactory.createFromList(inRangeValues); Dataset aboveRangeInput = DatasetFactory.createFromList(aboveRangeValues); Dataset belowRangeInput = DatasetFactory.createFromList(belowRangeValues); inRangeInput.sort(0); try{ aboveRangeInput.sort(0); belowRangeInput.sort(0); } catch(Exception d){ } Dataset inRangeOutput = DatasetFactory.zeros(inRangeInput, Dataset.ARRAYFLOAT64); try{ inRangeOutput = Interpolation1D.splineInterpolation( xValues, yValues, inRangeInput); } catch(Exception h){ System.out.println(h.getMessage()); System.out.println(h.getStackTrace()); } try{ @SuppressWarnings("deprecation") Dataset higherExtrapolationRange = DatasetFactory.createRange(DoubleDataset.class, (highestValueOfXValues - (20*highEndLastStepIncrement)), highestValueOfXValues, highEndLastStepIncrement ); higherExtrapolationRange.sort(0); Dataset[] higherExtrapolationRangeArray = new Dataset[] {higherExtrapolationRange}; Polynomial polyFitAboveRange = Fitter.polyFit(higherExtrapolationRangeArray, Interpolation1D.splineInterpolation(xValues, yValues, higherExtrapolationRange), 1e-30, 1); Dataset test = Interpolation1D.splineInterpolation(xValues, yValues, higherExtrapolationRange); Dataset calculatedAboveRangeValues = polyFitAboveRange.calculateValues(aboveRangeInput); DoubleDataset lowerExtrapolationRange = DatasetFactory.createRange(DoubleDataset.class, lowestValueOfXValues, lowestValueOfXValues + (20*lowEndLastStepIncrement), lowEndLastStepIncrement ); // lowerExtrapolationRange.sort(0); Dataset[] lowerExtrapolationRangeArray = new Dataset[] {lowerExtrapolationRange}; // Dataset test1 = Interpolation1D.splineInterpolation(xValues, yValues, lowerExtrapolationRange); Polynomial polyFitBelowRange = Fitter.polyFit(lowerExtrapolationRangeArray, Interpolation1D.splineInterpolation(xValues, yValues, lowerExtrapolationRange), 1e-30, 1); // Polynomial Test = Fitter. Dataset calculatedBelowRangeValues = polyFitBelowRange.calculateValues(belowRangeInput); Dataset[] fullRange = new Dataset[] {calculatedBelowRangeValues, inRangeOutput, calculatedAboveRangeValues }; output = DatasetUtils.concatenate(fullRange, 0); return output; } catch(Exception o){ System.out.println(o.getMessage()); System.out.println(o.getStackTrace()); return null; } } public double findDatasetMin(Dataset input){ double min = input.getDouble(0); for(int i= 0; i <input.getSize(); i++){ if(input.getDouble(i) <= min){ min = input.getDouble(i); } } return min; } public double findDatasetMax(Dataset input){ double max = input.getDouble(0); for(int i= 0; i <input.getSize(); i++){ if(input.getDouble(i) >= max){ max = input.getDouble(i); } } return max; } public double findDataset2ndToMin(Dataset input){ double smallest = input.getDouble(0); double secondSmallest = input.getDouble(1); for (int i = 0; i < input.getSize(); i++) { if(input.getDouble(i)==smallest){ // secondSmallest=smallest; } else if (input.getDouble(i) < smallest) { secondSmallest = smallest; smallest = input.getDouble(i); // return secondSmallest; } else if (input.getDouble(i) < secondSmallest) { secondSmallest = input.getDouble(i); } } return secondSmallest; } public double findDataset2ndToMax(Dataset input){ double largest = input.getDouble(0); double secondLargest = input.getDouble(1); for (int i = 0; i < input.getSize(); i++) { if(input.getDouble(i)==largest){ // secondLargest=largest; } else if (input.getDouble(i) > largest) { secondLargest = largest; largest = input.getDouble(i); // return secondLargest; } else if (input.getDouble(i) > secondLargest) { secondLargest = input.getDouble(i); } } return secondLargest; } }