/*- * Copyright 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 */ package uk.ac.diamond.scisoft.analysis.processing.operations; import org.eclipse.dawnsci.analysis.api.processing.OperationData; import org.eclipse.dawnsci.analysis.api.processing.OperationException; import org.eclipse.dawnsci.analysis.api.processing.model.IOperationModel; import org.eclipse.dawnsci.analysis.dataset.operations.AbstractOperation; import org.eclipse.january.DatasetException; import org.eclipse.january.IMonitor; import org.eclipse.january.dataset.IDataset; import org.eclipse.january.dataset.ILazyDataset; import org.eclipse.january.dataset.Maths; import org.eclipse.january.dataset.Slice; public abstract class AbstractCropOperation<T extends IOperationModel> extends AbstractOperation<T, OperationData> { /** * Take the user's selected range and determine if axis or raw values should be used. * Thus, set the indices to either the the raw values, shape of data or axis indices. * If user values null return the a slice with the same shape. * @param input * @param monitor * @throws OperationException * @return OperationData (slice) */ protected OperationData process(IDataset input, IMonitor monitor) throws OperationException { //Determine the operation rank int cropRank = getOutputRank().getRank(); //Get the user crop limits from the model Double[][] userVals = getUserVals(); //Return: array of arrays [[min/max][dimension]] int[][] indices = new int[2][cropRank]; //Get the axes and also the shape of the data int[] dataShape = input.getShape(); ILazyDataset[] axes = getFirstAxes(input); //As the axes are picked up in reverse order (i.e. z,y,x) have to get crop values using (cropRank-1)-dim for (int dim = 0; dim < cropRank; dim++) { //If no axes come back, use the raw user values if ((axes == null) || (axes[0] == null)) { indices[0][dim] = userVals[(cropRank-1)-dim][0] == null ? 0 : (int)userVals[(cropRank-1)-dim][0].doubleValue(); indices[1][dim] = userVals[(cropRank-1)-dim][1] == null ? dataShape[dim] : (int)userVals[(cropRank-1)-dim][1].doubleValue(); }else { //We do have axes, so get the indices of the user values indices[0][dim] = userVals[(cropRank-1)-dim][0] == null ? 0 : getAxisIndex(axes[dim], userVals[(cropRank-1)-dim][0]); indices[1][dim] = userVals[(cropRank-1)-dim][1] == null ? dataShape[dim] : getAxisIndex(axes[dim], userVals[(cropRank-1)-dim][1]); } if (indices[0][dim] == indices[1][dim]) { throw new OperationException(this, "Selected crop range outside axis range"); } //Correct for reversed axes/inputs if (indices[0][dim] > indices[1][dim]) { int tmp = indices[0][dim]; indices[0][dim] = indices[1][dim]; indices[1][dim] = tmp; } } return new OperationData(input.getSlice(indices[0], indices[1], null)); } protected int getAxisIndex(ILazyDataset theAxis, Double value) { try { return Maths.abs(Maths.subtract(theAxis.getSlice((Slice) null), value)).argMin(); } catch (DatasetException e) { throw new OperationException(this, e); } } /** * Returns user defined crop values from the model. * @return userVals */ protected abstract Double[][] getUserVals(); }