/*- * Copyright 2017 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.fitting; import java.util.Arrays; import java.util.List; 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.dawnsci.analysis.dataset.roi.ROISliceUtils; import org.eclipse.dawnsci.analysis.dataset.slicer.SliceViewIterator; import org.eclipse.january.DatasetException; import org.eclipse.january.IMonitor; import org.eclipse.january.MetadataException; 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.SliceND; import org.eclipse.january.metadata.AxesMetadata; import org.eclipse.january.metadata.MetadataFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.ac.diamond.scisoft.analysis.fitting.Generic1DFitter; import uk.ac.diamond.scisoft.analysis.fitting.functions.Add; import uk.ac.diamond.scisoft.analysis.fitting.functions.Gaussian; import uk.ac.diamond.scisoft.analysis.fitting.functions.IdentifiedPeak; import uk.ac.diamond.scisoft.analysis.fitting.functions.StraightLine; import uk.ac.diamond.scisoft.analysis.optimize.ApacheOptimizer; import uk.ac.diamond.scisoft.analysis.optimize.ApacheOptimizer.Optimizer; import uk.ac.diamond.scisoft.analysis.optimize.IOptimizer; @Atomic public class FitPeakToRowsOperation extends AbstractOperation<FitPeakToRowsModel, OperationData> { private static final Logger logger = LoggerFactory .getLogger(FitPeakToRowsOperation.class); @Override public String getId() { return "uk.ac.diamond.scisoft.analysis.processing.operations.fitting.FitPeakToRowsOperation"; } @Override public OperationRank getInputRank() { return OperationRank.TWO; } @Override public OperationRank getOutputRank() { return OperationRank.ONE; } @Override protected OperationData process(IDataset input, IMonitor monitor) throws OperationException { ILazyDataset[] firstAxes = getFirstAxes(input); IDataset axis = null; if (firstAxes == null || firstAxes[1] == null) { axis = DatasetFactory.createRange(input.getShape()[1], Dataset.INT32); //Add back in as metadata } else { try { axis = firstAxes[1].getSlice().squeeze(); } catch (DatasetException e) { throw new OperationException(this, e); } } double[] fitRange = model.getFitRange(); int[] indexes = new int[2]; if (fitRange != null) { fitRange = fitRange.clone(); Arrays.sort(fitRange); indexes = new int[2]; indexes[0]= ROISliceUtils.findPositionOfClosestValueInAxis(axis, fitRange[0]); indexes[1]= ROISliceUtils.findPositionOfClosestValueInAxis(axis, fitRange[1]); Arrays.sort(indexes); } else { indexes[0] = 0; indexes[1] = axis.getSize()-1; } SliceND s = new SliceND(input.getShape()); s.setSlice(1, indexes[0], indexes[1], 1); SliceViewIterator it = new SliceViewIterator(input, s, new int[]{1}); Dataset position = DatasetFactory.zeros(new int[]{input.getShape()[0]},Dataset.FLOAT64); position.fill(Double.NaN); position.setName("Position"); int count = 0; IOptimizer op = new ApacheOptimizer(Optimizer.LEVENBERG_MARQUARDT); Add f = null; while (it.hasNext()) { try { Dataset next = DatasetUtils.convertToDataset(it.next().getSlice()).squeeze(); Dataset ax = DatasetUtils.convertToDataset(getFirstAxes(next)[0].getSlice()); if (f == null) { IdentifiedPeak foundPeak = Generic1DFitter.parseDataDerivative(ax, next, 1).get(0); Gaussian g = new Gaussian(foundPeak.getPos(),foundPeak.getFWHM(),foundPeak.getArea()); StraightLine st = new StraightLine(); f = new Add(); f.addFunction(g); f.addFunction(st); } op.optimize(new IDataset[]{ax}, next, f); position.set(f.getFunctions()[0].getParameter(0).getValue(), count++); } catch (Exception e) { //no logging required, the NaN value shows the fit has failed } } if (firstAxes != null && firstAxes[0] != null) { AxesMetadata m; try { m = MetadataFactory.createMetadata(AxesMetadata.class,1); m.setAxis(0, firstAxes[0].getSlice().squeeze()); position.setMetadata(m); } catch (Exception e) { logger.error("Metadata building failed"); } } return new OperationData(position); } }