package uk.ac.diamond.scisoft.analysis.processing.operations.backgroundsubtraction;
import java.util.Arrays;
import org.eclipse.dawnsci.analysis.api.processing.OperationData;
import org.eclipse.dawnsci.analysis.api.processing.OperationException;
import org.eclipse.dawnsci.analysis.dataset.slicer.SliceFromSeriesMetadata;
import org.eclipse.january.DatasetException;
import org.eclipse.january.IMonitor;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetUtils;
import org.eclipse.january.dataset.IDataset;
import org.eclipse.january.dataset.ILazyDataset;
import org.eclipse.january.dataset.PositionIterator;
import org.eclipse.january.dataset.ShapeUtils;
public class SubtractBlankFrameOperation extends AbstractImageSubtrationOperation<SubtractBlankFrameModel> {
private ILazyDataset parent = null;
@Override
public String getId() {
return "uk.ac.diamond.scisoft.analysis.processing.operations.backgroundsubtraction.SubtractBlankFrameOperation";
}
protected OperationData process(IDataset input, IMonitor monitor) throws OperationException {
// check file is the same
SliceFromSeriesMetadata ssm = getSliceSeriesMetadata(input);
if (ssm == null) throw new OperationException(this, "No origin metadata!");
if (parent != ssm.getSourceInfo().getParent()) {
parent = ssm.getSourceInfo().getParent();
image = null;
}
return super.process(input, monitor);
}
@Override
protected Dataset getImage(IDataset input) throws OperationException {
SliceFromSeriesMetadata ssm = getSliceSeriesMetadata(input);
if (ssm == null) throw new OperationException(this, "No origin metadata!");
ILazyDataset lzBg = ssm.getSourceInfo().getParent();
int[] dd = ssm.getDataDimensions().clone();
Arrays.sort(dd);
int startFrame = model.getStartFrame();
int end = model.getStartFrame()+1;
if (model.getEndFrame() != null) {
end = model.getEndFrame();
}
if (end <= startFrame) throw new OperationException(this,"End cannot be before or the same as start");
ILazyDataset bg = lzBg.getSliceView();
int[] ss = ShapeUtils.squeezeShape(bg.getShape(), false);
if (ss.length == 2) {
try {
image = DatasetUtils.sliceAndConvertLazyDataset(bg).squeeze();
} catch (DatasetException e) {
throw new OperationException(this, e);
}
} else {
image = mean(startFrame, end, bg, dd).squeeze();
}
return image;
}
private Dataset mean(int start, int stop, ILazyDataset data, int... ignoreAxes) {
int[] shape = data.getShape();
PositionIterator iter = new PositionIterator(shape, ignoreAxes);
int[] pos = iter.getPos();
boolean[] omit = iter.getOmit();
int rank = shape.length;
int[] st = new int[rank];
Arrays.fill(st, 1);
int[] end = new int[rank];
Dataset average = null;
int count = 1;
int c = 0;
while (iter.hasNext() && count < stop +1) {
if (c++ < start) continue;
for (int i = 0; i < rank; i++) {
end[i] = omit[i] ? shape[i] : pos[i] + 1;
}
Dataset ds;
try {
ds = DatasetUtils.cast(data.getSlice(pos, end, st), Dataset.FLOAT64);
} catch (DatasetException e) {
throw new OperationException(this, e);
}
if (average == null) {
average = ds;
count++;
} else {
ds.isubtract(average);
ds.idivide(count++);
average.iadd(ds);
}
}
if (average != null)
average.squeeze();
return average;
}
}