io.fair_acc.sample.dataset.legacy.DoubleErrorDataSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of samples Show documentation
Show all versions of samples Show documentation
Small sample applications to showcase the features of the chart-fx library.
The newest version!
package io.fair_acc.sample.dataset.legacy;
import java.util.Arrays;
import io.fair_acc.dataset.*;
import io.fair_acc.dataset.events.ChartBits;
import io.fair_acc.dataset.spi.AbstractErrorDataSet;
import io.fair_acc.dataset.spi.DoubleDataSet;
import io.fair_acc.dataset.utils.AssertUtils;
/**
* Implementation of the DataSetError
interface which stores x,y, +eyn, -eyn values in separate double
* arrays. It provides methods allowing easily manipulate of data points.
* User provides X and Y coordinates or only Y coordinates. In the former case X coordinates have value of data point
* index. This version being optimised for native double arrays.
*
* @see DoubleDataSet for an equivalent implementation without errors
* @author rstein
* @deprecated this is kept for reference/performance comparisons only
*/
@SuppressWarnings("PMD")
public class DoubleErrorDataSet extends AbstractErrorDataSet
implements DataSetError, EditableDataSet, DataSet2D {
protected double[] xValues;
protected double[] yValues;
protected double[] yErrorsPos;
protected double[] yErrorsNeg;
protected int dataMaxIndex; // <= xValues.length, stores the actually used
// data array size
/**
* Creates a new instance of DoubleDataSet
as copy of another (deep-copy).
*
* @param another name of this DataSet.
*/
public DoubleErrorDataSet(final DataSet2D another) {
this("");
lock().writeLockGuard(() -> another.lock().writeLockGuard(() -> {
this.setName(another.getName());
this.set(another); // NOPMD by rstein on 25/06/19 07:42
}));
}
/**
* Creates a new instance of DoubleErrorDataSet
.
*
* @param name name of this DataSet.
* @throws IllegalArgumentException if name
is null
*/
public DoubleErrorDataSet(final String name) {
this(name, 0);
}
/**
*
* Creates a new instance of DoubleErrorDataSet
.
*
*
* @param name name of this data set.
* @param xValues X coordinates
* @param yValues Y coordinates
* @param yErrorsNeg Y negative coordinate error
* @param yErrorsPos Y positive coordinate error
* @param nData how many data points are relevant to be taken
* @param deepCopy if true, the input array is copied
* @throws IllegalArgumentException if any of parameters is null
or if arrays with coordinates have
* different lengths
*/
public DoubleErrorDataSet(final String name, final double[] xValues, final double[] yValues,
final double[] yErrorsNeg, final double[] yErrorsPos, final int nData, boolean deepCopy) {
this(name, Math.min(xValues.length, Math.min(yValues.length, nData)));
AssertUtils.notNull("X data", xValues);
AssertUtils.notNull("Y data", yValues);
AssertUtils.notNull("Y error pos", yErrorsPos);
AssertUtils.notNull("Y error neg", yErrorsNeg);
final int errorMin = Math.min(Math.min(yErrorsPos.length, yErrorsNeg.length), nData);
dataMaxIndex = Math.min(xValues.length, Math.min(yValues.length, errorMin));
AssertUtils.equalDoubleArrays(xValues, yValues, dataMaxIndex);
AssertUtils.equalDoubleArrays(xValues, yErrorsPos, dataMaxIndex);
AssertUtils.equalDoubleArrays(xValues, yErrorsNeg, dataMaxIndex);
if (dataMaxIndex != 0 && deepCopy) {
System.arraycopy(xValues, 0, this.xValues, 0, dataMaxIndex);
System.arraycopy(yValues, 0, this.yValues, 0, dataMaxIndex);
System.arraycopy(yErrorsPos, 0, this.yErrorsPos, 0, dataMaxIndex);
System.arraycopy(yErrorsNeg, 0, this.yErrorsNeg, 0, dataMaxIndex);
} else {
this.xValues = xValues;
this.yValues = yValues;
this.yErrorsPos = yErrorsPos;
this.yErrorsNeg = yErrorsNeg;
}
recomputeLimits(DIM_X);
recomputeLimits(DIM_Y);
}
/**
* Creates a new instance of DoubleErrorDataSet
.
*
* @param name name of this DataSet.
* @param initalSize maximum capacity of buffer
* @throws IllegalArgumentException if name
is null
*/
public DoubleErrorDataSet(final String name, final int initalSize) {
super(name, 2, ErrorType.NO_ERROR, ErrorType.ASYMMETRIC);
AssertUtils.gtEqThanZero("initalSize", initalSize);
xValues = new double[initalSize];
yValues = new double[initalSize];
yErrorsPos = new double[initalSize];
yErrorsNeg = new double[initalSize];
dataMaxIndex = 0;
}
/**
* Add point to the DoublePoints object. Errors in y are assumed 0.
*
* @param x the new x coordinate
* @param y the new y coordinate
* @return itself
*/
public DoubleErrorDataSet add(final double x, final double y) {
return add(x, y, 0.0, 0.0);
}
/**
* Add point to the DoublePoints object
*
* @param x the new x coordinate
* @param y the new y coordinate
* @param yErrorNeg the +dy error
* @param yErrorPos the -dy error
* @return itself
*/
public DoubleErrorDataSet add(final double x, final double y, final double yErrorNeg, final double yErrorPos) {
lock().writeLockGuard(() -> {
// enlarge array if necessary
if (dataMaxIndex > (xValues.length - 1)) {
final double[] xValuesNew = new double[xValues.length + 1];
final double[] yValuesNew = new double[yValues.length + 1];
final double[] yErrorsNegNew = new double[yValues.length + 1];
final double[] yErrorsPosNew = new double[yValues.length + 1];
System.arraycopy(xValues, 0, xValuesNew, 0, xValues.length);
System.arraycopy(yValues, 0, yValuesNew, 0, yValues.length);
System.arraycopy(yErrorsNeg, 0, yErrorsNegNew, 0, yValues.length);
System.arraycopy(yErrorsPos, 0, yErrorsPosNew, 0, yValues.length);
xValues = xValuesNew;
yValues = yValuesNew;
yErrorsPos = yErrorsPosNew;
yErrorsNeg = yErrorsNegNew;
}
xValues[dataMaxIndex] = x;
yValues[dataMaxIndex] = y;
yErrorsPos[dataMaxIndex] = yErrorPos;
yErrorsNeg[dataMaxIndex] = yErrorNeg;
dataMaxIndex++;
getAxisDescription(DIM_X).add(x);
getAxisDescription(DIM_Y).add(y - yErrorNeg);
getAxisDescription(DIM_Y).add(y + yErrorPos);
});
fireInvalidated(ChartBits.DataSetDataAdded);
return getThis();
}
/**
*
* Initialises the data set with specified data.
*
* Note: The method copies values from specified double arrays.
*
* @param xValues X coordinates
* @param yValues Y coordinates
* @param yErrorsNeg the +dy errors
* @param yErrorsPos the -dy errors
* @return itself (fluent design)
*/
public DoubleErrorDataSet add(final double[] xValues, final double[] yValues, final double[] yErrorsNeg,
final double[] yErrorsPos) {
AssertUtils.notNull("X coordinates", xValues);
AssertUtils.notNull("Y coordinates", yValues);
AssertUtils.notNull("Y error neg", yErrorsNeg);
AssertUtils.notNull("Y error pos", yErrorsPos);
AssertUtils.equalDoubleArrays(xValues, yValues);
AssertUtils.equalDoubleArrays(xValues, yErrorsNeg);
AssertUtils.equalDoubleArrays(xValues, yErrorsPos);
lock().writeLockGuard(() -> {
final int newLength = this.getDataCount() + xValues.length;
// need to allocate new memory
if (newLength > this.xValues.length) {
final double[] xValuesNew = new double[newLength];
final double[] yValuesNew = new double[newLength];
final double[] yErrorsNegNew = new double[newLength];
final double[] yErrorsPosNew = new double[newLength];
// copy old data
System.arraycopy(this.xValues, 0, xValuesNew, 0, getDataCount());
System.arraycopy(this.yValues, 0, yValuesNew, 0, getDataCount());
System.arraycopy(yErrorsNeg, 0, yErrorsNegNew, 0, getDataCount());
System.arraycopy(yErrorsPos, 0, yErrorsPosNew, 0, getDataCount());
this.xValues = xValuesNew;
this.yValues = yValuesNew;
this.yErrorsNeg = yErrorsNegNew;
this.yErrorsPos = yErrorsPosNew;
}
// N.B. getDataCount() should equal dataMaxIndex here
System.arraycopy(xValues, 0, this.xValues, getDataCount(), newLength - getDataCount());
System.arraycopy(yValues, 0, this.yValues, getDataCount(), newLength - getDataCount());
System.arraycopy(yErrorsNeg, 0, this.yErrorsNeg, getDataCount(), newLength - getDataCount());
System.arraycopy(yErrorsPos, 0, this.yErrorsPos, getDataCount(), newLength - getDataCount());
dataMaxIndex = Math.max(0, dataMaxIndex + xValues.length);
recomputeLimits(DIM_X);
recomputeLimits(DIM_Y);
});
fireInvalidated(ChartBits.DataSetDataAdded);
return getThis();
}
@Override
public EditableDataSet add(int index, double... newValue) {
return null;
}
/**
* clears all data
*
* @return itself (fluent design)
*/
public DoubleErrorDataSet clearData() {
lock().writeLockGuard(() -> {
dataMaxIndex = 0;
Arrays.fill(xValues, 0.0);
Arrays.fill(yValues, 0.0);
Arrays.fill(yErrorsPos, 0.0);
Arrays.fill(yErrorsNeg, 0.0);
getDataLabelMap().clear();
getDataStyleMap().clear();
getAxisDescription(DIM_X).clear();
getAxisDescription(DIM_Y).clear();
});
fireInvalidated(ChartBits.DataSetDataRemoved);
return getThis();
}
@Override
public double get(final int dimIndex, final int index) {
return dimIndex == DIM_X ? xValues[index] : yValues[index];
}
@Override
public int getDataCount() {
return Math.min(dataMaxIndex, xValues.length);
}
@Override
public double getErrorNegative(final int dimIndex, final int index) {
return dimIndex == DIM_X ? 0.0 : yErrorsNeg[index];
}
@Override
public double getErrorPositive(final int dimIndex, final int index) {
return dimIndex == DIM_X ? 0.0 : yErrorsPos[index];
}
@Override
public double[] getErrorsNegative(final int dimIndex) {
return dimIndex == DIM_Y ? yErrorsNeg : super.getErrorsPositive(dimIndex);
}
@Override
public double[] getErrorsPositive(final int dimIndex) {
return dimIndex == DIM_Y ? yErrorsPos : super.getErrorsPositive(dimIndex);
}
@Override
public double[] getXValues() {
return xValues;
}
@Override
public double[] getYValues() {
return yValues;
}
@Override
public EditableDataSet remove(int index) {
return remove(index, index + 1);
}
/**
* remove sub-range of data points
*
* @param fromIndex start index
* @param toIndex stop index
* @return itself (fluent design)
*/
public DoubleErrorDataSet remove(final int fromIndex, final int toIndex) {
lock().writeLockGuard(() -> {
AssertUtils.indexInBounds(fromIndex, getDataCount(), "fromIndex");
AssertUtils.indexInBounds(toIndex, getDataCount(), "toIndex");
AssertUtils.indexOrder(fromIndex, "fromIndex", toIndex, "toIndex");
final int diffLength = toIndex - fromIndex;
// check whether this really needed (keeping the data and reducing just
// the dataMaxIndex costs some memory but saves new allocation
final int newLength = xValues.length - diffLength;
final double[] xValuesNew = new double[newLength];
final double[] yValuesNew = new double[newLength];
final double[] yErrorsNegNew = new double[newLength];
final double[] yErrorsPosNew = new double[newLength];
System.arraycopy(xValues, 0, xValuesNew, 0, fromIndex);
System.arraycopy(yValues, 0, yValuesNew, 0, fromIndex);
System.arraycopy(yErrorsNeg, 0, yErrorsNegNew, 0, fromIndex);
System.arraycopy(yErrorsPos, 0, yErrorsPosNew, 0, fromIndex);
System.arraycopy(xValues, toIndex, xValuesNew, fromIndex, newLength - fromIndex);
System.arraycopy(yValues, toIndex, yValuesNew, fromIndex, newLength - fromIndex);
System.arraycopy(yErrorsNeg, toIndex, yErrorsNegNew, fromIndex, newLength - fromIndex);
System.arraycopy(yErrorsPos, toIndex, yErrorsPosNew, fromIndex, newLength - fromIndex);
xValues = xValuesNew;
yValues = yValuesNew;
yErrorsPos = yErrorsPosNew;
yErrorsNeg = yErrorsNegNew;
dataMaxIndex = Math.max(0, dataMaxIndex - diffLength);
getAxisDescriptions().forEach(AxisDescription::clear);
});
fireInvalidated(ChartBits.DataSetDataRemoved);
return getThis();
}
/**
* clear old data and overwrite with data from 'other' data set (deep copy)
*
* @param other the other data set
* @return itself (fluent design)
*/
public DoubleErrorDataSet set(final DataSet2D other) {
lock().writeLockGuard(() -> other.lock().writeLockGuard(() -> {
// deep copy data point labels and styles
getDataLabelMap().clear();
for (int index = 0; index < other.getDataCount(); index++) {
final String label = other.getDataLabel(index);
if (label != null && !label.isEmpty()) {
this.addDataLabel(index, label);
}
}
getDataStyleMap().clear();
for (int index = 0; index < other.getDataCount(); index++) {
final String style = other.getStyle(index);
if (style != null && !style.isEmpty()) {
this.addDataStyle(index, style);
}
}
this.setStyle(other.getStyle());
// copy data
if (other instanceof DataSetError) {
this.set(other.getXValues(), other.getYValues(), ((DataSetError) other).getErrorsNegative(DIM_Y),
((DataSetError) other).getErrorsPositive(DIM_Y), true);
} else {
final int count = other.getDataCount();
this.set(other.getXValues(), other.getYValues(), new double[count], new double[count], true);
}
}));
return getThis();
}
/**
*
* Initialises the data set with specified data.
*
* Note: The method copies values from specified double arrays.
*
* @param xValues X coordinates
* @param yValues Y coordinates
* @param yErrorsNeg the +dy errors
* @param yErrorsPos the -dy errors
* @return itself (fluent design)
*/
public DoubleErrorDataSet set(final double[] xValues, final double[] yValues, final double[] yErrorsNeg,
final double[] yErrorsPos) {
return set(xValues, yValues, yErrorsNeg, yErrorsPos, true);
}
/**
*
* Initialises the data set with specified data.
*
* Note: The method copies values from specified double arrays.
*
* @param xValues X coordinates
* @param yValues Y coordinates
* @param yErrorsNeg the +dy errors
* @param yErrorsPos the -dy errors
* @param copy true: makes an internal copy, false: use the pointer as is (saves memory allocation)
* @return itself (fluent design)
*/
public DoubleErrorDataSet set(final double[] xValues, final double[] yValues, final double[] yErrorsNeg,
final double[] yErrorsPos, final boolean copy) {
AssertUtils.notNull("X coordinates", xValues);
AssertUtils.notNull("Y coordinates", yValues);
AssertUtils.notNull("Y error neg", yErrorsNeg);
AssertUtils.notNull("Y error pos", yErrorsPos);
final int errorMin = Math.min(yErrorsPos.length, yErrorsNeg.length);
dataMaxIndex = Math.min(xValues.length, Math.min(yValues.length, errorMin));
AssertUtils.equalDoubleArrays(xValues, yValues, dataMaxIndex);
AssertUtils.equalDoubleArrays(xValues, yErrorsNeg, dataMaxIndex);
AssertUtils.equalDoubleArrays(xValues, yErrorsPos, dataMaxIndex);
lock().writeLockGuard(() -> {
if (!copy) {
this.xValues = xValues;
this.yValues = yValues;
this.yErrorsNeg = yErrorsNeg;
this.yErrorsPos = yErrorsPos;
recomputeLimits(DIM_X);
recomputeLimits(DIM_Y);
return;
}
if (xValues.length == this.xValues.length) {
System.arraycopy(xValues, 0, this.xValues, 0, getDataCount());
System.arraycopy(yValues, 0, this.yValues, 0, getDataCount());
System.arraycopy(yErrorsNeg, 0, this.yErrorsNeg, 0, getDataCount());
System.arraycopy(yErrorsPos, 0, this.yErrorsPos, 0, getDataCount());
} else {
/*
* copy into new arrays, forcing array length to be equal to the xValues length
*/
this.xValues = Arrays.copyOf(xValues, xValues.length);
this.yValues = Arrays.copyOf(yValues, xValues.length);
this.yErrorsNeg = Arrays.copyOf(yErrorsNeg, xValues.length);
this.yErrorsPos = Arrays.copyOf(yErrorsPos, xValues.length);
}
recomputeLimits(DIM_X);
recomputeLimits(DIM_Y);
});
fireInvalidated(ChartBits.DataSetData);
return getThis();
}
/**
* replaces point coordinate of existing data point
*
* @param index the index of the data point
* @param newValue new point coordinates
* @return itself (fluent design)
*/
@Override
public DoubleErrorDataSet set(int index, double... newValue) {
return set(index, newValue[0], newValue[1], 0.0, 0.0);
}
/**
* replaces point coordinate of existing data point
*
* @param index the index of the data point
* @param x new horizontal coordinate
* @param y new vertical coordinate
* @param yErrorNeg new vertical negative error of y (can be asymmetric)
* @param yErrorPos new vertical positive error of y (can be asymmetric)
* @return itself (fluent design)
*/
public DoubleErrorDataSet set(final int index, final double x, final double y, final double yErrorNeg,
final double yErrorPos) {
lock().writeLockGuard(() -> {
if (index < dataMaxIndex) {
xValues[index] = x;
yValues[index] = y;
yErrorsPos[index] = yErrorPos;
yErrorsNeg[index] = yErrorNeg;
} else {
this.add(x, y, yErrorNeg, yErrorPos);
}
getAxisDescription(DIM_X).add(x);
getAxisDescription(DIM_Y).add(y - yErrorNeg);
getAxisDescription(DIM_Y).add(y + yErrorPos);
});
fireInvalidated(ChartBits.DataSetData);
return getThis();
}
@Override
public EditableDataSet set(final DataSet other, final boolean copy) {
throw new UnsupportedOperationException("Copy setter not implemented");
}
}