/*
* Copyright (c) 2012 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.fitting;
import java.util.List;
import org.eclipse.dawnsci.analysis.api.fitting.functions.IPeak;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetFactory;
import org.eclipse.january.dataset.DoubleDataset;
import org.eclipse.january.dataset.Maths;
import uk.ac.diamond.scisoft.analysis.fitting.functions.Polynomial;
public class CalibrationUtils {
/**
* Function to take an axis along with some peaked data with approximately known positions, and re-map it to another
* axis with know peak positions
*
* @param data
* The actual collected calibration data
* @param originalAxis
* The Axis on which the original data was collected
* @param originalAxisApproximatePeakPositions
* The approximate positions where characteristic peaks should appear in the data in the old axis
* coordinates
* @param newAxisExactPeakPositions
* The exact positions where the peaks should appear on the new Axis
* @param peakClass
* The class with which to fit the individual peaks
* @param polynomialOrder
* The order of the polynomial with which to fit the mapping process from the old axis to the new
* @return The new Axis with the same dimensionality as the original data
*/
public static Dataset mapAxis(Dataset data, Dataset originalAxis,
Dataset originalAxisApproximatePeakPositions, Dataset newAxisExactPeakPositions, Class<? extends IPeak> peakClass,
int polynomialOrder) {
Dataset peakPositions = refinePeakPositions(data, originalAxis, originalAxisApproximatePeakPositions,
peakClass);
// fit the data with a polynomial
Polynomial fitResult = Fitter.polyFit(new Dataset[] {peakPositions} ,newAxisExactPeakPositions, 1e-15, polynomialOrder);
// convert the dataset
Dataset newAxis = fitResult.calculateValues(originalAxis);
return newAxis;
}
/**
* Takes an approximate set of peak positions and refines them
*
* @param originalAxis
* The Axis on which the original data was collected
* @param originalAxisApproximatePeakPositions
* The approximate positions where characteristic peaks should appear in the data in the old axis
* coordinates
* @param peakClass
* The class with which to fit the individual peaks
* @return val
*/
public static Dataset refinePeakPositions(Dataset data, Dataset originalAxis,
Dataset originalAxisApproximatePeakPositions, Class<? extends IPeak> peakClass) {
int numPeaks = originalAxisApproximatePeakPositions.getSize();
List<IPeak> fitResult = Generic1DFitter.fitPeaks(originalAxis, data, peakClass, numPeaks );
Dataset refinedPositions = selectSpecifiedPeaks(originalAxisApproximatePeakPositions, fitResult);
return refinedPositions;
}
/**
* Given a list of APeak functions, find the ones which most closely match a set of input positions
* @param originalAxisApproximatePeakPositions the positions to match peaks to
* @param peakList the list of APeaks containing all the peaks to try to match
* @return the closest real peak position matches to the original positions.
*/
public static Dataset selectSpecifiedPeaks(Dataset originalAxisApproximatePeakPositions,
List<IPeak> peakList) {
Dataset peakPositions = getPeakList(peakList);
Dataset resultPositions = DatasetFactory.zeros(DoubleDataset.class, originalAxisApproximatePeakPositions.getShape());
for (int i = 0; i < originalAxisApproximatePeakPositions.getSize(); i++) {
Dataset compare = Maths.subtract(peakPositions, originalAxisApproximatePeakPositions.getDouble(i));
compare = Maths.abs(compare);
resultPositions.set(peakPositions.getDouble(compare.minPos()),i);
}
return resultPositions;
}
/**
* Gets a dataset of peak positions out of a list of APeaks
* @param peakList a list of APeak functions
* @return the dataset of peak positions.
*/
public static Dataset getPeakList(List<IPeak> peakList) {
int n = peakList.size();
Dataset peakPositons = DatasetFactory.zeros(DoubleDataset.class, n);
for (int i = 0; i < n; i++) {
peakPositons.set(peakList.get(i).getPosition(), i);
}
return peakPositons;
}
}