/*
* 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 uk.ac.diamond.scisoft.analysis.diffraction.powder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetFactory;
import org.eclipse.january.dataset.DatasetUtils;
import org.eclipse.january.dataset.FloatDataset;
import org.eclipse.january.dataset.IDataset;
import org.eclipse.january.dataset.IndexIterator;
import org.eclipse.dawnsci.analysis.api.metadata.IDiffractionMetadata;
public class PixelSplittingIntegration2D extends AbstractPixelIntegration2D {
public PixelSplittingIntegration2D(IDiffractionMetadata metadata) {
super(metadata);
}
public PixelSplittingIntegration2D(IDiffractionMetadata metadata, int numBinsQ, int numBinsChi) {
super(metadata, numBinsQ, numBinsChi);
}
@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 = DatasetFactory.zeros(FloatDataset.class, nBinsChi, nbins);
FloatDataset intensity = DatasetFactory.zeros(FloatDataset.class, 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;
}
}