/*- * Copyright 2016 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.roiprofile; import org.eclipse.dawnsci.analysis.api.processing.Atomic; import org.eclipse.dawnsci.analysis.api.processing.OperationData; import org.eclipse.dawnsci.analysis.api.processing.OperationException; import org.eclipse.dawnsci.analysis.api.processing.OperationRank; import org.eclipse.dawnsci.analysis.dataset.operations.AbstractOperation; import org.eclipse.january.DatasetException; import org.eclipse.january.IMonitor; import org.eclipse.january.MetadataException; import org.eclipse.january.dataset.BooleanDataset; import org.eclipse.january.dataset.Comparisons; 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.ILazyDataset; import org.eclipse.january.dataset.Maths; import org.eclipse.january.dataset.SliceND; import org.eclipse.january.metadata.AxesMetadata; import org.eclipse.january.metadata.MaskMetadata; import org.eclipse.january.metadata.MetadataFactory; @Atomic public class SubtractIntegratedXRegionsOperation extends AbstractOperation<SubtractIntegratedXRegionsModel, OperationData> { @Override public String getId() { return "uk.ac.diamond.scisoft.analysis.processing.operations.roiprofile.SubtractIntegratedXRegionsOperation"; } @Override public OperationRank getInputRank() { return OperationRank.TWO; } @Override public OperationRank getOutputRank() { return OperationRank.ONE; } @Override protected OperationData process(IDataset input, IMonitor monitor) throws OperationException { double[] signalRange = model.getSignal(); double[] backGroundRange0 = model.getBackground0(); double[] backGroundRange1 = model.getBackground1(); if (signalRange == null || backGroundRange0 == null || backGroundRange1 == null) throw new OperationException(this, "Signal and background regions must be defined!"); AxesMetadata axm = input.getFirstMetadata(AxesMetadata.class); Dataset signal = null; Dataset b0 = null; Dataset b1 = null; ILazyDataset[] axis1 = null; int[] nSignal = new int[1]; int[] nOther = new int[1]; if (axm == null || axm.getAxis(1) == null || axm.getAxis(1)[0] == null) { signal = getMean(input,(int)Math.round(signalRange[0]), (int)Math.round(signalRange[1]),nSignal); b0 = getMean(input,(int)Math.round(backGroundRange0[0]), (int)Math.round(backGroundRange0[1]),nOther); b1 = getMean(input,(int)Math.round(backGroundRange1[0]), (int)Math.round(backGroundRange1[1]),nOther); } else { Dataset x; try { x = DatasetUtils.sliceAndConvertLazyDataset(axm.getAxis(1)[0]); } catch (DatasetException e) { throw new OperationException(this, e); } x.squeeze(); signal = getMean(input,x,signalRange,nSignal); b0 = getMean(input,x,backGroundRange0,nOther); b1 = getMean(input,x,backGroundRange1,nOther); ILazyDataset[] axis = axm.getAxis(0); axis1 = axis.clone(); for (int i = 0; i < axis1.length; i++) axis1[i] = axis1[i] == null ? null : axis1[i].getSliceView().squeezeEnds(); } if (signal == null || b0 == null || b1 == null) throw new OperationException(this, "Could not get sections of data!"); Dataset ds = DatasetUtils.convertToDataset(input); double m = model.isUseFullFrameForRatio() ? (double)ds.sum(true) : (double)signal.sum(true); signal.isubtract((b0.iadd(b1).idivide(2))); double m2 = (double)signal.sum(true); if (model.isUseFullFrameForRatio()) m2 = m2*nSignal[0]; if (axis1 != null) { AxesMetadata ax; try { ax = MetadataFactory.createMetadata(AxesMetadata.class, 1); } catch (MetadataException e) { throw new OperationException(this, e); } ax.setAxis(0, axis1); signal.addMetadata(ax); } System.out.println(m2/m); Dataset ratio = DatasetFactory.createFromObject(new Double(m2/m)); ratio.setName("ratio"); return new OperationData(signal, ratio); } private Dataset getMean(IDataset input, Dataset x, double[] vals, int[] number) { int x0 = Maths.abs(Maths.subtract(x, vals[0])).argMin(); int x1 = Maths.abs(Maths.subtract(x, vals[1])).argMin(); return getMean(input, x0, x1, number); } private Dataset getMean(IDataset input, int i0, int i1, int[] number) { int[] startStop = i0 < i1 ? new int[] {i0,i1} : new int[] {i1,i0}; number[0] = startStop[1]-startStop[0]; SliceND s = new SliceND(input.getShape()); s.setSlice(1, startStop[0], startStop[1], 1); Dataset d = DatasetUtils.convertToDataset(input.getSlice(s)); MaskMetadata mmd = d.getFirstMetadata(MaskMetadata.class); if (mmd != null) { Dataset m; try { m = DatasetUtils.sliceAndConvertLazyDataset(mmd.getMask()); } catch (DatasetException e) { throw new OperationException(this, e); } if (m instanceof BooleanDataset) { d.setByBoolean(Double.NaN, Comparisons.logicalNot(m)); } } Dataset mean = d.mean(1,true); DatasetUtils.makeFinite(mean); return mean; } }