/*-
*******************************************************************************
* Copyright (c) 2011, 2014 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
*
* Contributors:
* Peter Chang - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.dawnsci.analysis.dataset.impl.function;
import java.util.ArrayList;
import java.util.List;
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;
import org.eclipse.january.dataset.Maths;
/**
* Sample along line and return list of one 1D dataset
*
* When mapping from image to data, the array value is assumed to be
* associated with the centre of the pixel, i.e. pixel co-ord - 0.5 = data co-ord.
*
* This half pixel offset is handled in this class so does not need to be accounted for else where.
*
*/
public class LineSample implements DatasetToDatasetFunction {
double sx, sy, ex, ey;
double step;
private double rad;
private double sp;
private double cp;
/**
* Set up line sampling
*
* @param sx
* @param sy
* @param ex
* @param ey
* @param step
*/
public LineSample(double sx, double sy, double ex, double ey, double step) {
this.sx = sx - 0.5;
this.sy = sy - 0.5;
this.ex = ex - 0.5;
this.ey = ey - 0.5;
this.step = step;
rad = Math.hypot(ex - sx, ey - sy);
double phi = Math.atan2(ey - sy, ex - sx);
cp = Math.cos(phi);
sp = Math.sin(phi);
}
/**
* @param i
* @return position of indexed point on line
*/
public int[] getPoint(int i) {
final double r = step * i;
return new int[] {(int) (sy + r * sp), (int) (sx + r * cp)};
}
/**
* The class implements pointwise sampling along a given line
*
* @param datasets input 2D datasets
* @return one 1D dataset
*/
@Override
public List<Dataset> value(IDataset... datasets) {
if (datasets.length == 0)
return null;
List<Dataset> result = new ArrayList<Dataset>();
for (IDataset ids : datasets) {
if (ids == null || ids.getRank() != 2)
return null;
Dataset ds = DatasetUtils.convertToDataset(ids);
int nr = ((int) Math.floor(rad / step)) + 1;
Dataset linsample = DatasetFactory.zeros(new int[] { nr },
DTypeUtils.getBestFloatDType(ds.getDType()));
double x, y;
for (int i = 0; i < nr; i++) {
final double r = step * i;
x = sx + r * cp;
y = sy + r * sp;
linsample.setObjectAbs(i, Maths.interpolate(ds, y, x));
}
result.add(linsample);
}
return result;
}
}