/*- * Copyright 2016 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 uk.ac.diamond.scisoft.analysis.diffraction.powder; import java.util.Arrays; import javax.vecmath.Vector3d; import org.eclipse.dawnsci.analysis.api.metadata.IDiffractionMetadata; import org.eclipse.january.dataset.Dataset; import org.eclipse.january.dataset.DatasetFactory; import org.eclipse.january.dataset.DoubleDataset; import org.eclipse.january.dataset.Maths; import uk.ac.diamond.scisoft.analysis.diffraction.QSpace; public class SurfacePixelIntegrationCache implements IPixelIntegrationCache { private IDiffractionMetadata dMeta; private Dataset[] yArray; private Dataset[] xArray; private Dataset yAxis; private Dataset xAxis; private DoubleDataset binEdgesY = null; private DoubleDataset binEdgesX = null; private double[] xRange; private double[] yRange; private int[] shape; private int binsPara, binsPerp; public SurfacePixelIntegrationCache(IDiffractionMetadata dMeta, int[] shape, double pitchDegrees, double rollDegrees, int binsPara, int binsPerp, double[] paraRange, double[] perpRange) { this.dMeta = dMeta; this.shape = shape; if (paraRange != null) { paraRange = paraRange.clone(); Arrays.sort(paraRange); this.xRange = paraRange; } if (perpRange != null) { perpRange = perpRange.clone(); Arrays.sort(perpRange); this.yRange = perpRange; } this.binsPara = binsPara; this.binsPerp = binsPerp; initialize(Math.toRadians(pitchDegrees), Math.toRadians(rollDegrees)); } private void initialize(double pitch, double roll) { SurfaceQ sq = new SurfaceQ(); //perpendicular[0,1] parrallel[2,3] Dataset[] arrays = SurfaceQ.generateMinMaxParallelPerpendicularArrays(shape, new QSpace(dMeta.getDetector2DProperties(), dMeta.getDiffractionCrystalEnvironment()), new Vector3d(-Math.sin(roll), Math.cos(roll)*Math.cos(pitch), -Math.sin(pitch))); // xArray is ±q∥ xArray = new Dataset[]{arrays[2], arrays[3]}; // yArray is q⊥ yArray = new Dataset[]{arrays[0], arrays[1]}; binEdgesX = calculateBins(xArray, this.binsPara, xRange); binEdgesY = calculateBins(yArray, this.binsPerp, yRange); xAxis = calculateAxis(binEdgesX, "q_par"); yAxis = calculateAxis(binEdgesY, "q_per"); } @Override public Dataset[] getXAxisArray() { return xArray; } @Override public Dataset[] getYAxisArray() { return yArray; } @Override public double getXBinEdgeMax() { return binEdgesX.getAbs(binEdgesX.getSize()-1); } @Override public double getXBinEdgeMin() { return binEdgesX.getAbs(0); } @Override public double getYBinEdgeMax() { return binEdgesY.getAbs(binEdgesY.getSize()-1); } @Override public double getYBinEdgeMin() { return binEdgesY.getAbs(0); } @Override public int getNumberOfBinsXAxis() { return this.binsPara; } @Override public int getNumberOfBinsYAxis() { return this.binsPerp; } @Override public double[] getYAxisRange() { return yRange; } @Override public double[] getXAxisRange() { return xRange; } @Override public Dataset getXAxis() { return xAxis; } @Override public Dataset getYAxis() { return yAxis; } @Override public boolean isPixelSplitting() { return true; } @Override public boolean isTo1D() { return false; } @Override public boolean sanitise() { return true; } @Override public boolean provideLookup() { return false; } private static Dataset calculateAxis(DoubleDataset binEdges, String name){ Dataset axis = null; axis = Maths.add(binEdges.getSlice(new int[]{1}, null ,null), binEdges.getSlice(null, new int[]{-1},null)); axis.idivide(2); axis.setName(name); return axis; } private static DoubleDataset calculateBins(Dataset[] arrays, int numBins, double[] binRange) { if (binRange != null) { double shift = 0; // range corresponds to bin centres shift = (binRange[1]- binRange[0])/(2*numBins); return (DoubleDataset) DatasetFactory.createLinearSpace(binRange[0]-shift, binRange[1]+shift, numBins + 1, Dataset.FLOAT64); } double min = Double.MAX_VALUE; double max = -Double.MAX_VALUE; for (Dataset a : arrays) { Dataset data = a; double n = data.min(true).doubleValue(); double x = data.max(true).doubleValue(); min = n < min ? n : min; max = x > max ? x : max; } //default range corresponds to bin edges return (DoubleDataset) DatasetFactory.createLinearSpace(min, max, numBins + 1, Dataset.FLOAT64); } }