/*
* 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.dataset.function;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.dawnsci.analysis.dataset.impl.function.DatasetToDatasetFunction;
import org.eclipse.january.dataset.CompoundDataset;
import org.eclipse.january.dataset.DTypeUtils;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetFactory;
import org.eclipse.january.dataset.DatasetUtils;
import org.eclipse.january.dataset.IDataset;
/**
* Integrate 2D dataset and return list of two 1D datasets for individual sums over the two dimensions
*
*/
public class Integrate2D implements DatasetToDatasetFunction {
int sx, sy, ex, ey;
boolean full = false;
/**
* Set up integration over whole 2D dataset
*
*/
public Integrate2D() {
full = true;
}
/**
* Set up integration over rectangular subset of 2D dataset
*
* @param sx
* @param sy
* @param ex
* @param ey
*/
public Integrate2D(int sx, int sy, int ex, int ey) {
this.sx = sx;
this.sy = sy;
this.ex = ex;
this.ey = ey;
}
/**
* The class implements integrations along each axis of 2D dataset
*
* @param datasets input 2D datasets (only first used)
* @return two 1D datasets which are sums over x and y
*/
@Override
public List<Dataset> value(IDataset... datasets) {
if (datasets.length == 0)
return null;
List<Dataset> result = new ArrayList<Dataset>();
for (IDataset ids : datasets) {
int[] shape = ids.getShape();
if (shape.length != 2)
return null;
Dataset ds = DatasetUtils.convertToDataset(ids);
if (full) {
sx = 0;
sy = 0;
ex = shape[1] - 1;
ey = shape[0] - 1;
} else {
if (sx < 0)
sx = 0;
if (sx >= shape[1])
sx = shape[1] - 1;
if (ex < 0)
ex = 0;
if (ex >= shape[1])
ex = shape[1] - 1;
if (sy < 0)
sy = 0;
if (sy >= shape[0])
sy = shape[0] - 1;
if (ey < 0)
ey = 0;
if (ey >= shape[0])
ey = shape[0] - 1;
}
int nx = ex - sx + 1;
int ny = ey - sy + 1;
if (nx == 0)
nx = 1;
if (ny == 0)
ny = 1;
final int dtype = DTypeUtils.getBestFloatDType(ds.getDType());
final int is = ds.getElementsPerItem();
Dataset sumy = DatasetFactory.zeros(is, new int[] { nx }, dtype);
Dataset sumx = DatasetFactory.zeros(is, new int[] { ny }, dtype);
if (is == 1) {
double csum;
for (int b = 0; b < ny; b++) {
csum = 0.0;
for (int a = 0; a < nx; a++) {
final double v = ds.getDouble(b + sy, a + sx);
if (Double.isNaN(v)) continue;
csum += v;
sumy.set(v + sumy.getDouble(a), a);
}
sumx.set(csum, b);
}
} else {
final double[] csums = new double[is];
final double[] xvalues = new double[is];
final double[] yvalues = new double[is];
for (int b = 0; b < ny; b++) {
Arrays.fill(csums, 0.);
for (int a = 0; a < nx; a++) {
((CompoundDataset) ds).getDoubleArray(xvalues, b + sy, a + sx);
((CompoundDataset) sumy).getDoubleArray(yvalues, a);
for (int j = 0; j < is; j++) {
csums[j] += xvalues[j];
yvalues[j] += xvalues[j];
}
sumy.set(yvalues, a);
}
sumx.set(csums, b);
}
}
result.add(sumx);
result.add(sumy);
}
return result;
}
}