package org.dawnsci.surfacescatter; import java.util.Arrays; import org.eclipse.dawnsci.analysis.api.processing.OperationData; import org.eclipse.dawnsci.analysis.api.processing.OperationRank; import org.eclipse.dawnsci.analysis.dataset.operations.AbstractOperation; import org.eclipse.january.IMonitor; 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.LinearAlgebra; import org.eclipse.january.dataset.Maths; public class RefinedTwoDExponentialFittingUsingIOperation extends AbstractOperation<TwoDFittingModel, OperationData> { private static Dataset output; private static int DEBUG = 0; @Override public String getId() { return "uk.ac.diamond.scisoft.surfacescatter.TwoDExponentialFittingUsingIOperation"; } @Override public OperationRank getInputRank() { return OperationRank.TWO; } @Override public OperationRank getOutputRank() { return OperationRank.TWO; } @Override protected OperationData process(IDataset input, IMonitor monitor) { int[] len = model.getLenPt()[0]; int[] pt = model.getLenPt()[1]; Dataset in1 = BoxSlicerRodScanUtilsForDialog.rOIBox(input, len, pt); if (Arrays.equals(in1.getShape(), new int[] { len[1], len[0] }) == false) { IDataset location = DatasetFactory.ones(new int[] {2,2}); Dataset errorDat = DatasetFactory.zeros(new int[] { 2, 2 }); return new OperationData(errorDat, location); } Dataset[] fittingBackground = BoxSlicerRodScanUtilsForDialog.LeftRightTopBottomBoxes(input, len, pt, model.getBoundaryBox()); if (Arrays.equals(fittingBackground[0].getShape(), (new int[] { 2, 2 }))) { IDataset location = DatasetFactory.ones(new int[] {2,2}); return new OperationData(fittingBackground[0], location); } /////////////Exponential Fitting Dataset matrixExp = LinearLeastSquaresServicesForDialog.exponential2DLinearLeastSquaresMatrixGenerator( fittingBackground[0], fittingBackground[1], fittingBackground[2]); Dataset loggedZ = Maths.log(fittingBackground[2]); for(int u = 0; u<fittingBackground[2].getSize(); u++){ if(Double.isInfinite(loggedZ.getDouble(u))){ loggedZ.set(-1000000, u); } if(Double.isNaN(loggedZ.getDouble(u))){ loggedZ.set(0, u); } } DoubleDataset testExp = (DoubleDataset)LinearAlgebra.solveSVD(matrixExp, loggedZ); double[] paramsExp = testExp.getData(); /////////////////////////// // ///////////////Linear Fit if (Arrays.equals(fittingBackground[0].getShape(), (new int[] { 2, 2 }))) { IDataset location = DatasetFactory.ones(new int[] {2,2}); return new OperationData(fittingBackground[0], location); } Dataset matrixPoly = LinearLeastSquaresServicesForDialog.polynomial2DLinearLeastSquaresMatrixGenerator( 1, fittingBackground[0], fittingBackground[1]); DoubleDataset testPoly = (DoubleDataset) LinearAlgebra.solveSVD(matrixPoly, fittingBackground[2]); double[] paramsPoly = testPoly.getData(); /////////////////////////// // ///////////////Mixed Fit Dataset matrixRef = LinearLeastSquaresServicesForDialog. refinedExponential2DLinearLeastSquaresMatrixGenerator( fittingBackground[0], fittingBackground[1], fittingBackground[2], paramsPoly, paramsExp); DoubleDataset testRef = (DoubleDataset) LinearAlgebra.solveSVD(matrixRef, fittingBackground[2]); double[] paramsRef = testRef.getData(); IDataset in1Background = getRefinedExponentialOutputValues(paramsPoly, paramsExp, paramsRef, model.getBoundaryBox(), len[0], len[1]); Dataset pBackgroundSubtracted = DatasetFactory.createFromObject(in1); try{ pBackgroundSubtracted = Maths.subtract(in1, in1Background, null); } catch(Exception b){ System.out.println(b.getMessage()); } output = DatasetUtils.cast(pBackgroundSubtracted, Dataset.FLOAT64); output.setName("Region of Interest, 2D Exponential background removed"); return new OperationData(output, (IDataset) in1Background); } public IDataset getExponentialOutputValues (double[] a, int boundaryBox, int len0, int len1) { IDataset output = DatasetFactory.zeros(new int[] {len1, len0});//new DoubleDataset(len[1], len[0]); for (int i=boundaryBox; i<len1+boundaryBox; i++){ for (int j=boundaryBox; j<len0+boundaryBox; j++){ double value = -Math.exp(a[0]) + Math.exp(a[1])*Math.exp(a[2]* i + a[3]* j); output.set(value, i-boundaryBox, j-boundaryBox); } } for(int u = 0; u<output.getShape()[0]; u++){ for(int v = 0; v<output.getShape()[1]; v++){ if(Double.isInfinite(output.getDouble(u, v))){ output.set(-1000000, u, v); } if(Double.isNaN(output.getDouble(u, v))){ output.set(0, u, v); } } } return output; } public IDataset getRefinedExponentialOutputValues (double[] paramsPoly, double[] paramsExp, double[] paramsRef, int boundaryBox, int len0, int len1) { double[] a = paramsExp; double[] b = paramsPoly; double[] c = paramsRef; IDataset output = DatasetFactory.zeros(new int[] {len1, len0});//new DoubleDataset(len[1], len[0]); for (int i=boundaryBox; i<len1+boundaryBox; i++){ for (int j=boundaryBox; j<len0+boundaryBox; j++){ double valueExp = -Math.exp(a[0]) + Math.exp(a[1])*Math.exp(a[2]*i + a[3]*j); if(Double.isNaN(valueExp)){ valueExp = 0; } else if(Double.isInfinite(valueExp)){ valueExp = -1000000000; } double valuePoly = b[0] + b[1]*i + b[2]*j + b[3]*i*j; double valueRef = c[0]*valuePoly + c[1]*valueExp; output.set(valueRef, i-boundaryBox, j-boundaryBox); } } for(int u = 0; u<output.getShape()[0]; u++){ for(int v = 0; v<output.getShape()[1]; v++){ if(Double.isInfinite(output.getDouble(u, v))){ output.set(-1000000, u, v); } if(Double.isNaN(output.getDouble(u, v))){ output.set(0, u, v); } } } return output; } private void debug(String output) { if (DEBUG == 1) { System.out.println(output); } } }