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 = oldx.getDouble(0); for (int i = 1; i < ((Dataset) oldx).count(); i++) { if (maxtest > oldx.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); IDataset newy = newx.clone(); newy.setName(oldy.getName() + "_interpolated"); for (int i = 0; i < ((Dataset) newx).count(); i++) { newy.set(poly.value(newx.getDouble(i)), i); } return newy; }
@Override public List<Dataset> integrate(IDataset dataset) { // Generate radial and azimuthal look-up arrays as required // TODO test shape of axis array if (radialArray == null) { generateRadialArray(dataset.getShape(), false); } if (azimuthalArray == null) { generateMinMaxAzimuthalArray( qSpace.getDetectorProperties().getBeamCentreCoords(), dataset.getShape()); } Dataset mt = mask; if (mask != null && !Arrays.equals(mask.getShape(), dataset.getShape())) throw new IllegalArgumentException("Mask shape does not match dataset shape"); List<Dataset> result = new ArrayList<Dataset>(); if (binEdges == null) { binEdges = calculateBins(radialArray, mt, radialRange, nbins); binsChi = calculateBins(azimuthalArray, mt, azimuthalRange, nBinsChi); } final double[] edgesQ = binEdges.getData(); final double loQ = edgesQ[0]; final double hiQ = edgesQ[nbins]; final double spanQ = (hiQ - loQ) / nbins; final double[] edgesChi = binsChi.getData(); final double loChi = edgesChi[0]; final double hiChi = edgesChi[nBinsChi]; final double spanChi = (hiChi - loChi) / nBinsChi; FloatDataset histo = new FloatDataset(nBinsChi, nbins); FloatDataset intensity = new FloatDataset(nBinsChi, nbins); // final double[] h = histo.getData(); // final double[] in = intensity.getData(); // if (spanQ <= 0) { // h[0] = ds.getSize(); // result.add(histo); // result.add(bins); // continue; // } Dataset a = DatasetUtils.convertToDataset(radialArray[0]); Dataset b = DatasetUtils.convertToDataset(dataset); // PositionIterator iter = b.getPositionIterator(); // // int[] pos = iter.getPos(); // int[] posStop = pos.clone(); IndexIterator iter = a.getIterator(); while (iter.hasNext()) { // posStop[0] = pos[0]+2; // posStop[1] = pos[1]+2; // Dataset qrange = a.getSlice(pos, posStop, null); // Dataset chirange = azimuthalArray.getSlice(pos, posStop, null); if (mt != null && !mt.getElementBooleanAbs(iter.index)) continue; final double qMax = radialArray[1].getElementDoubleAbs(iter.index); final double qMin = radialArray[0].getElementDoubleAbs(iter.index); final double chiMax = azimuthalArray[1].getElementDoubleAbs(iter.index); final double chiMin = azimuthalArray[0].getElementDoubleAbs(iter.index); final double sig = b.getElementDoubleAbs(iter.index); if (qMax < loQ || qMin > hiQ) { continue; } if (chiMax < loChi || chiMin > hiChi) { continue; } // losing something here? is flooring (int cast best?) double minBinExactQ = (qMin - loQ) / spanQ; double maxBinExactQ = (qMax - loQ) / spanQ; int minBinQ = (int) minBinExactQ; int maxBinQ = (int) maxBinExactQ; double minBinExactChi = (chiMin - loChi) / spanChi; double maxBinExactChi = (chiMax - loChi) / spanChi; int minBinChi = (int) minBinExactChi; int maxBinChi = (int) maxBinExactChi; // FIXME potentially may need to deal with azimuthal arrays with discontinuities (+180/-180 // degress etc) double iPerPixel = 1 / ((maxBinExactQ - minBinExactQ) * (maxBinExactChi - minBinExactChi)); double minFracQ = 1 - (minBinExactQ - minBinQ); double maxFracQ = maxBinExactQ - maxBinQ; double minFracChi = 1 - (minBinExactChi - minBinChi); double maxFracChi = maxBinExactChi - maxBinChi; for (int i = minBinQ; i <= maxBinQ; i++) { if (i < 0 || i >= binEdges.getSize() - 1) continue; for (int j = minBinChi; j <= maxBinChi; j++) { if (j < 0 || j >= binsChi.getSize() - 1) continue; int[] setPos = new int[] {j, i}; double val = histo.get(setPos); double modify = 1; if (i == minBinQ && minBinQ != maxBinQ) modify *= minFracQ; if (i == maxBinQ && minBinQ != maxBinQ) modify *= maxFracQ; if (i == minBinChi && minBinChi != maxBinChi) modify *= minFracChi; if (i == maxBinChi && minBinChi != maxBinChi) modify *= maxFracChi; histo.set(val + iPerPixel * modify, setPos); double inVal = intensity.get(setPos); intensity.set(inVal + sig * iPerPixel * modify, setPos); } } } processAndAddToResult(intensity, histo, result, radialRange, dataset.getName()); return result; }