diff --git a/pom.xml b/pom.xml
index e511886..557f9f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
kotik-coderPULsE
- 1.97
+ 1.98PULsEProcessing Unit for Laser flash Experiments
@@ -18,20 +18,19 @@
The Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0.txt
-
-
+
org.jfreejfreechart
- 1.5.0
+ 1.5.4
- com.weblookandfeel
- weblaf-ui
- 1.2.13
+ com.formdev
+ flatlaf
+ 3.0
-
+ org.apache.commonscommons-math33.6.1
diff --git a/src/main/java/pulse/AbstractData.java b/src/main/java/pulse/AbstractData.java
index a1d276c..58fbceb 100644
--- a/src/main/java/pulse/AbstractData.java
+++ b/src/main/java/pulse/AbstractData.java
@@ -258,7 +258,7 @@ public void remove(int i) {
public boolean ignoreSiblings() {
return true;
}
-
+
public boolean isFull() {
return actualNumPoints() >= count;
}
@@ -306,4 +306,4 @@ public boolean equals(Object o) {
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/DiscreteInput.java b/src/main/java/pulse/DiscreteInput.java
index c6bb8d8..3b29c1f 100644
--- a/src/main/java/pulse/DiscreteInput.java
+++ b/src/main/java/pulse/DiscreteInput.java
@@ -1,45 +1,48 @@
package pulse;
import java.awt.geom.Point2D;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import pulse.input.IndexRange;
import pulse.math.Segment;
-public interface DiscreteInput {
-
+public interface DiscreteInput extends Serializable {
+
public List getX();
+
public List getY();
+
public IndexRange getIndexRange();
-
+
public static List convert(double[] x, double[] y) {
-
+
var ps = new ArrayList();
-
- for(int i = 0, size = x.length; i < size; i++) {
+
+ for (int i = 0, size = x.length; i < size; i++) {
ps.add(new Point2D.Double(x[i], y[i]));
}
-
+
return ps;
-
+
}
-
+
public static List convert(List x, List y) {
-
+
var ps = new ArrayList();
-
- for(int i = 0, size = x.size(); i < size; i++) {
+
+ for (int i = 0, size = x.size(); i < size; i++) {
ps.add(new Point2D.Double(x.get(i), y.get(i)));
}
-
+
return ps;
-
+
}
-
+
public default Segment bounds() {
var ir = getIndexRange();
var x = getX();
return new Segment(x.get(ir.getLowerBound()), x.get(ir.getUpperBound()));
}
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/HeatingCurve.java b/src/main/java/pulse/HeatingCurve.java
index 86e1462..f682306 100644
--- a/src/main/java/pulse/HeatingCurve.java
+++ b/src/main/java/pulse/HeatingCurve.java
@@ -1,6 +1,8 @@
package pulse;
-import static java.util.Collections.max;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import static java.util.stream.Collectors.toList;
import static pulse.input.listeners.CurveEventType.RESCALED;
import static pulse.input.listeners.CurveEventType.TIME_ORIGIN_CHANGED;
@@ -17,12 +19,14 @@
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.interpolation.SplineInterpolator;
import org.apache.commons.math3.analysis.interpolation.UnivariateInterpolator;
+import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
import pulse.baseline.Baseline;
import pulse.input.ExperimentalData;
import pulse.input.listeners.CurveEvent;
import pulse.properties.NumericProperty;
import pulse.properties.NumericPropertyKeyword;
+import pulse.util.FunctionSerializer;
/**
* The {@code HeatingCurve} represents a time-temperature profile (a
@@ -42,20 +46,30 @@
*/
public class HeatingCurve extends AbstractData {
- private final List adjustedSignal;
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7071147065094996971L;
+ private List adjustedSignal;
private List lastCalculation;
private double startTime;
- private final List listeners
- = new ArrayList<>();
+ private List listeners;
- private UnivariateInterpolator interpolator;
- private UnivariateFunction interpolation;
+ private transient UnivariateInterpolator interpolator;
+ private transient UnivariateFunction interpolation;
protected HeatingCurve(List time, List signal, final double startTime, String name) {
super(time, name);
this.adjustedSignal = signal;
this.startTime = startTime;
+ initListeners();
+ }
+
+ @Override
+ public void initListeners() {
+ super.initListeners();
+ listeners = new ArrayList<>();
}
/**
@@ -167,7 +181,7 @@ public void scale(double scale) {
for (int i = 0, max = Math.min(count, signal.size()); i < max; i++) {
signal.set(i, signal.get(i) * scale);
}
- var dataEvent = new CurveEvent(RESCALED, this);
+ var dataEvent = new CurveEvent(RESCALED);
fireCurveEvent(dataEvent);
}
@@ -195,14 +209,13 @@ private void refreshInterpolation() {
}
final double alpha = -1.0;
- adjustedSignalExtended[0] = alpha * adjustedSignalExtended[2]
+ adjustedSignalExtended[0] = alpha * adjustedSignalExtended[2]
- (1.0 - alpha) * adjustedSignalExtended[1]; // extrapolate
// linearly
/*
* Submit to spline interpolation
*/
-
interpolation = interpolator.interpolate(timeExtended, adjustedSignalExtended);
}
@@ -343,7 +356,7 @@ public NumericProperty getTimeShift() {
public void setTimeShift(NumericProperty startTime) {
requireType(startTime, TIME_SHIFT);
this.startTime = (double) startTime.getValue();
- var dataEvent = new CurveEvent(TIME_ORIGIN_CHANGED, this);
+ var dataEvent = new CurveEvent(TIME_ORIGIN_CHANGED);
fireCurveEvent(dataEvent);
firePropertyChanged(this, startTime);
}
@@ -357,11 +370,14 @@ public List getBaselineCorrectedData() {
}
public void addHeatingCurveListener(HeatingCurveListener l) {
+ if (listeners == null) {
+ listeners = new ArrayList<>();
+ }
this.listeners.add(l);
}
@Override
- public void removeHeatingCurveListeners() {
+ public void removeListeners() {
listeners.clear();
}
@@ -379,7 +395,7 @@ public boolean equals(Object o) {
return super.equals(o) && adjustedSignal.containsAll(((HeatingCurve) o).adjustedSignal);
}
-
+
public double interpolateSignalAt(double x) {
double min = this.timeAt(0);
double max = timeLimit();
@@ -387,4 +403,23 @@ public double interpolateSignalAt(double x) {
: (x < min ? signalAt(0) : signalAt(actualNumPoints() - 1));
}
-}
\ No newline at end of file
+ /*
+ * Serialization
+ */
+ private void writeObject(ObjectOutputStream oos)
+ throws IOException {
+ // default serialization
+ oos.defaultWriteObject();
+ // write the object
+ FunctionSerializer.writeSplineFunction((PolynomialSplineFunction) interpolation, oos);
+ }
+
+ private void readObject(ObjectInputStream ois)
+ throws ClassNotFoundException, IOException {
+ // default deserialization
+ ois.defaultReadObject();
+ this.interpolation = FunctionSerializer.readSplineFunction(ois);
+ this.interpolator = new SplineInterpolator();
+ }
+
+}
diff --git a/src/main/java/pulse/HeatingCurveListener.java b/src/main/java/pulse/HeatingCurveListener.java
index 7dd972c..12d8064 100644
--- a/src/main/java/pulse/HeatingCurveListener.java
+++ b/src/main/java/pulse/HeatingCurveListener.java
@@ -1,15 +1,17 @@
package pulse;
+import java.io.Serializable;
import pulse.input.listeners.CurveEvent;
/**
* An interface used to listen to data events related to {@code HeatingCurve}.
*
*/
-public interface HeatingCurveListener {
+public interface HeatingCurveListener extends Serializable {
/**
* Signals that a {@code CurveEvent} has occurred.
+ *
* @param event
*/
public void onCurveEvent(CurveEvent event);
diff --git a/src/main/java/pulse/Response.java b/src/main/java/pulse/Response.java
index cc4f23c..e138950 100644
--- a/src/main/java/pulse/Response.java
+++ b/src/main/java/pulse/Response.java
@@ -1,25 +1,27 @@
package pulse;
+import java.io.Serializable;
import pulse.math.Segment;
import pulse.problem.schemes.solvers.SolverException;
import pulse.search.GeneralTask;
import pulse.search.statistics.OptimiserStatistic;
-public interface Response {
-
+public interface Response extends Serializable {
+
public double evaluate(double t);
+
public Segment accessibleRange();
-
+
/**
- * Calculates the value of the objective function used to identify
- * the current state of the optimiser.
+ * Calculates the value of the objective function used to identify the
+ * current state of the optimiser.
+ *
* @param task
* @return the value of the objective function in the current state
* @throws pulse.problem.schemes.solvers.SolverException
*/
-
public double objectiveFunction(GeneralTask task) throws SolverException;
-
+
public OptimiserStatistic getOptimiserStatistic();
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/baseline/Baseline.java b/src/main/java/pulse/baseline/Baseline.java
index d42c31d..29a8886 100644
--- a/src/main/java/pulse/baseline/Baseline.java
+++ b/src/main/java/pulse/baseline/Baseline.java
@@ -1,5 +1,6 @@
package pulse.baseline;
+import java.util.ArrayList;
import java.util.List;
import pulse.DiscreteInput;
@@ -24,7 +25,7 @@
public abstract class Baseline extends PropertyHolder implements Reflexive, Optimisable {
public final static int MIN_BASELINE_POINTS = 15;
-
+
public abstract Baseline copy();
/**
@@ -60,19 +61,24 @@ public abstract class Baseline extends PropertyHolder implements Reflexive, Opti
* @see fitTo(ExperimentalData,double,double)
*/
public void fitTo(DiscreteInput data) {
- var filtered = Range.NEGATIVE.filter(data);
- if(filtered[0].size() > MIN_BASELINE_POINTS) {
+ var filtered = Range.NEGATIVE.filter(data);
+ if (filtered[0].size() > MIN_BASELINE_POINTS) {
doFit(filtered[0], filtered[1]);
- }
+ }
}
-
+
public void fitTo(List x, List y) {
- int index = IndexRange.closestLeft(0, x);
- var xx = x.subList(0, index + 1);
- var yy = y.subList(0, index + 1);
- if(xx.size() > MIN_BASELINE_POINTS) {
+ int index = IndexRange.closestLeft(0, x);
+ var xx = new ArrayList<>(x.subList(0, index + 1));
+ var yy = new ArrayList<>(y.subList(0, index + 1));
+ if (xx.size() > MIN_BASELINE_POINTS) {
doFit(xx, yy);
- }
+ }
}
-
-}
\ No newline at end of file
+
+ @Override
+ public String getDescriptor() {
+ return "Baseline";
+ }
+
+}
diff --git a/src/main/java/pulse/baseline/FlatBaseline.java b/src/main/java/pulse/baseline/FlatBaseline.java
index 9500c8f..1ca0743 100644
--- a/src/main/java/pulse/baseline/FlatBaseline.java
+++ b/src/main/java/pulse/baseline/FlatBaseline.java
@@ -8,10 +8,11 @@
/**
* A flat baseline.
*/
-
public class FlatBaseline extends AdjustableBaseline {
-
- /**
+
+ private static final long serialVersionUID = -4867631788950622739L;
+
+ /**
* A primitive constructor, which initialises a {@code CONSTANT} baseline
* with zero intercept and slope.
*/
@@ -27,8 +28,7 @@ public FlatBaseline() {
public FlatBaseline(double intercept) {
super(intercept, 0.0);
}
-
-
+
@Override
protected void doFit(List x, List y) {
double intercept = mean(y);
@@ -37,12 +37,12 @@ protected void doFit(List x, List y) {
@Override
public Baseline copy() {
- return new FlatBaseline((double)getIntercept().getValue());
+ return new FlatBaseline((double) getIntercept().getValue());
}
@Override
public String toString() {
return getClass().getSimpleName() + " = " + format("%3.2f", getIntercept().getValue());
}
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/baseline/LinearBaseline.java b/src/main/java/pulse/baseline/LinearBaseline.java
index d3d899e..a04354d 100644
--- a/src/main/java/pulse/baseline/LinearBaseline.java
+++ b/src/main/java/pulse/baseline/LinearBaseline.java
@@ -29,6 +29,8 @@
*/
public class LinearBaseline extends AdjustableBaseline {
+ private static final long serialVersionUID = -7334390731462268504L;
+
/**
* A primitive constructor, which initialises a {@code CONSTANT} baseline
* with zero intercept and slope.
@@ -36,19 +38,19 @@ public class LinearBaseline extends AdjustableBaseline {
public LinearBaseline() {
super(0.0, 0.0);
}
-
+
public LinearBaseline(double intercept, double slope) {
super(intercept, slope);
}
-
- public LinearBaseline(LinearBaseline baseline) {
- super( (double) baseline.getIntercept().getValue(),
- (double) baseline.getSlope().getValue()
- );
+
+ public LinearBaseline(AdjustableBaseline baseline) {
+ super((double) baseline.getIntercept().getValue(),
+ (double) baseline.getSlope().getValue()
+ );
}
@Override
- protected void doFit(List x, List y) {
+ protected void doFit(List x, List y) {
double meanx = mean(x);
double meany = mean(y);
@@ -63,7 +65,7 @@ protected void doFit(List x, List y) {
xxbar += (x1 - meanx) * (x1 - meanx);
xybar += (x1 - meanx) * (y1 - meany);
}
-
+
double slope = xybar / xxbar;
double intercept = meany - slope * meanx;
@@ -74,8 +76,8 @@ protected void doFit(List x, List y) {
@Override
public String toString() {
var slope = getSlope().getValue();
- return getClass().getSimpleName() + " = " +
- format("%3.2f + t * ( %3.2f )", getIntercept().getValue(), slope);
+ return getClass().getSimpleName() + " = "
+ + format("%3.2f + t * ( %3.2f )", getIntercept().getValue(), slope);
}
@Override
@@ -121,9 +123,9 @@ public void assign(ParameterVector params) {
for (Parameter p : params.getParameters()) {
var key = p.getIdentifier().getKeyword();
-
+
if (key == BASELINE_SLOPE) {
- setSlope( derive(BASELINE_SLOPE, p.inverseTransform() ));
+ setSlope(derive(BASELINE_SLOPE, p.inverseTransform()));
}
}
diff --git a/src/main/java/pulse/baseline/SinusoidalBaseline.java b/src/main/java/pulse/baseline/SinusoidalBaseline.java
index 9074cdc..94b92c9 100644
--- a/src/main/java/pulse/baseline/SinusoidalBaseline.java
+++ b/src/main/java/pulse/baseline/SinusoidalBaseline.java
@@ -46,6 +46,7 @@
*/
public class SinusoidalBaseline extends LinearBaseline {
+ private static final long serialVersionUID = -6858521208790195992L;
private List hiFreq;
private List loFreq;
private List active;
@@ -87,10 +88,10 @@ public Baseline copy() {
newH.setParent(baseline);
}
for (Harmonic h : hiFreq) {
- baseline.hiFreq.add(new Harmonic(h));
+ baseline.hiFreq.add(new Harmonic(h));
}
for (Harmonic h : loFreq) {
- baseline.loFreq.add(new Harmonic(h));
+ baseline.loFreq.add(new Harmonic(h));
}
return baseline;
}
@@ -98,7 +99,7 @@ public Baseline copy() {
@Override
public void optimisationVector(ParameterVector output) {
super.optimisationVector(output);
- active.forEach(h -> h.optimisationVector(output) );
+ active.forEach(h -> h.optimisationVector(output));
}
@Override
@@ -124,7 +125,7 @@ private void guessHarmonics(double[] x, double[] y) {
double maxAmp = 0;
hiFreq = new ArrayList<>();
-
+
double span = x[x.length - 1] - x[0];
double lowerFrequency = 4.0 / span;
@@ -146,7 +147,7 @@ private List sort(List hs, int limit) {
tmp.sort(null);
Collections.reverse(tmp);
//leave out a maximum of n harmonics
- return tmp.subList(0, Math.min(tmp.size(), limit));
+ return new ArrayList<>(tmp.subList(0, Math.min(tmp.size(), limit)));
}
private void labelActive() {
@@ -237,25 +238,25 @@ public NumericProperty getHiFreqMax() {
public void setHiFreqMax(NumericProperty maxHarmonics) {
NumericProperty.requireType(maxHarmonics, MAX_HIGH_FREQ_WAVES);
int oldValue = this.maxHighFreqHarmonics;
-
+
if ((int) maxHarmonics.getValue() != oldValue) {
-
+
var lowFreq = new ArrayList();
int size = active.size();
-
- if(maxHighFreqHarmonics < size) {
+
+ if (maxHighFreqHarmonics < size) {
lowFreq = new ArrayList<>(active.subList(maxHighFreqHarmonics, size));
}
-
+
this.maxHighFreqHarmonics = (int) maxHarmonics.getValue();
active.clear();
active.addAll(sort(hiFreq, maxHighFreqHarmonics));
active.addAll(lowFreq);
this.labelActive();
this.firePropertyChanged(this, maxHarmonics);
-
+
}
-
+
}
public NumericProperty getLowFreqMax() {
@@ -267,7 +268,7 @@ public void setLowFreqMax(NumericProperty maxHarmonics) {
int oldValue = this.maxLowFreqHarmonics;
if ((int) maxHarmonics.getValue() != oldValue) {
this.maxLowFreqHarmonics = (int) maxHarmonics.getValue();
- active = active.subList(0, maxHighFreqHarmonics);
+ active = new ArrayList<>(active.subList(0, maxHighFreqHarmonics));
active.addAll(this.sort(loFreq, maxLowFreqHarmonics));
this.labelActive();
this.firePropertyChanged(this, maxHarmonics);
@@ -279,7 +280,7 @@ public void set(NumericPropertyKeyword type, NumericProperty property) {
super.set(type, property);
switch (type) {
-
+
case MAX_HIGH_FREQ_WAVES:
setHiFreqMax(property);
break;
@@ -346,12 +347,11 @@ private void addLowFreq(DiscreteInput input) {
/*
These harmonics are inaccessible by FFT
*/
-
for (double f = freq; f > 1.0 / (2.0 * span); f /= 2.0) {
loFreq.add(new Harmonic(amp, f, 0.0));
}
- active.addAll(loFreq.subList(0, Math.min(loFreq.size(), maxLowFreqHarmonics)));
+ active.addAll(loFreq.subList(0, Math.min(loFreq.size(), maxLowFreqHarmonics)));
}
@Override
diff --git a/src/main/java/pulse/input/ExperimentalData.java b/src/main/java/pulse/input/ExperimentalData.java
index f38a8e0..4be76e7 100644
--- a/src/main/java/pulse/input/ExperimentalData.java
+++ b/src/main/java/pulse/input/ExperimentalData.java
@@ -27,11 +27,15 @@
*/
public class ExperimentalData extends AbstractData implements DiscreteInput {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7950893319753173094L;
private HalfTimeCalculator calculator;
private Metadata metadata;
private IndexRange indexRange;
private Range range;
- private List dataListeners;
+ private transient List dataListeners;
/**
* This is the cutoff factor which is used as a criterion for data
@@ -49,10 +53,16 @@ public class ExperimentalData extends AbstractData implements DiscreteInput {
*/
public ExperimentalData() {
super();
- dataListeners = new ArrayList<>();
setPrefix("RawData");
setNumPoints(derive(NUMPOINTS, 0));
- indexRange = new IndexRange(0,0);
+ indexRange = new IndexRange(0, 0);
+ initListeners();
+ }
+
+ @Override
+ public void initListeners() {
+ super.initListeners();
+ dataListeners = new ArrayList<>();
this.addDataListener((DataEvent e) -> {
if (e.getType() == DataEventType.DATA_LOADED) {
preprocess();
@@ -61,6 +71,9 @@ public ExperimentalData() {
}
public final void addDataListener(DataListener listener) {
+ if(dataListeners == null) {
+ dataListeners = new ArrayList<>();
+ }
dataListeners.add(listener);
}
@@ -298,4 +311,4 @@ public List getY() {
return this.getSignalData();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/input/IndexRange.java b/src/main/java/pulse/input/IndexRange.java
index 93a9280..cb19490 100644
--- a/src/main/java/pulse/input/IndexRange.java
+++ b/src/main/java/pulse/input/IndexRange.java
@@ -1,5 +1,6 @@
package pulse.input;
+import java.io.Serializable;
import static java.util.Objects.requireNonNull;
import java.util.List;
@@ -15,8 +16,9 @@
* @see pulse.input.Range
*
*/
-public class IndexRange {
+public class IndexRange implements Serializable {
+ private static final long serialVersionUID = 7983756487957427969L;
private int iStart;
private int iEnd;
@@ -24,7 +26,7 @@ public IndexRange(IndexRange other) {
iStart = other.iStart;
iEnd = other.iEnd;
}
-
+
public IndexRange(int start, int end) {
this.iStart = start;
this.iEnd = end;
diff --git a/src/main/java/pulse/input/InterpolationDataset.java b/src/main/java/pulse/input/InterpolationDataset.java
index 45f244e..4e0ec64 100644
--- a/src/main/java/pulse/input/InterpolationDataset.java
+++ b/src/main/java/pulse/input/InterpolationDataset.java
@@ -1,20 +1,18 @@
package pulse.input;
-import static pulse.properties.NumericPropertyKeyword.CONDUCTIVITY;
-import static pulse.properties.NumericPropertyKeyword.DENSITY;
-import static pulse.properties.NumericPropertyKeyword.SPECIFIC_HEAT;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
import java.util.ArrayList;
-import java.util.EnumMap;
import java.util.List;
-import java.util.Map;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.interpolation.AkimaSplineInterpolator;
+import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
-import pulse.input.listeners.ExternalDatasetListener;
-import pulse.properties.NumericPropertyKeyword;
-import static pulse.properties.NumericPropertyKeyword.EMISSIVITY;
+import pulse.util.FunctionSerializer;
import pulse.util.ImmutableDataEntry;
/**
@@ -27,19 +25,19 @@
*
* @see pulse.input.listeners.ExternalDatasetListener
*/
-public class InterpolationDataset {
+public class InterpolationDataset implements Serializable {
- private UnivariateFunction interpolation;
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7439474910490135034L;
+ private transient UnivariateFunction interpolation;
private final List> dataset;
- private static final Map standartDatasets
- = new EnumMap(StandartType.class);
- private static final List listeners = new ArrayList<>();
- /**
- * Creates an empty {@code InterpolationDataset}.
- */
-
- public InterpolationDataset() {
+ /**
+ * Creates an empty {@code InterpolationDataset}.
+ */
+ public InterpolationDataset() {
dataset = new ArrayList<>();
}
@@ -66,7 +64,7 @@ public void add(ImmutableDataEntry entry) {
}
/**
- * Constructs a new spline interpolator and uses the available dataset to
+ * Constructs a new Akima spline interpolator and uses the available dataset to
* produce a {@code SplineInterpolation}.
*/
public void doInterpolation() {
@@ -84,65 +82,22 @@ public List> getData() {
return dataset;
}
- /**
- * Retrieves a standard dataset previously loaded by the respective reader.
- *
- * @param type the standard dataset type
- * @return an {@code InterpolationDataset} corresponding to {@code type}
- */
- public static InterpolationDataset getDataset(StandartType type) {
- return standartDatasets.get(type);
- }
-
- /**
- * Puts a datset specified by {@code type} into the static hash map of this
- * class, using {@code type} as key. Triggers {@code onDensityDataLoaded}
- *
- * @param dataset a dataset to be appended to the static hash map
- * @param type the dataset type
+ /*
+ * Serialization
*/
- public static void setDataset(InterpolationDataset dataset, StandartType type) {
- standartDatasets.put(type, dataset);
- listeners.stream().forEach(l -> l.onDataLoaded(type));
+ private void writeObject(ObjectOutputStream oos)
+ throws IOException {
+ // default serialization
+ oos.defaultWriteObject();
+ // write the object
+ FunctionSerializer.writeSplineFunction((PolynomialSplineFunction) interpolation, oos);
}
- /**
- * Creates a list of property keywords that can be derived with help of the
- * loaded data. For example, if heat capacity and density data is available,
- * the returned list will contain {@code CONDUCTIVITY}.
- *
- * @return
- */
- public static List derivableProperties() {
- var list = new ArrayList();
- if (standartDatasets.containsKey(StandartType.HEAT_CAPACITY)) {
- list.add(SPECIFIC_HEAT);
- }
- if (standartDatasets.containsKey(StandartType.DENSITY)) {
- list.add(DENSITY);
- }
- if (list.contains(SPECIFIC_HEAT) && list.contains(DENSITY)) {
- list.add(CONDUCTIVITY);
- list.add(EMISSIVITY);
- }
- return list;
- }
-
- public static void addListener(ExternalDatasetListener l) {
- listeners.add(l);
- }
-
- public enum StandartType {
-
- /**
- * A keyword for the heat capacity dataset (in J/kg/K).
- */
- HEAT_CAPACITY,
- /**
- * A keyword for the density dataset (in kg/m3).
- */
- DENSITY;
-
+ private void readObject(ObjectInputStream ois)
+ throws ClassNotFoundException, IOException {
+ // default deserialization
+ ois.defaultReadObject();
+ this.interpolation = FunctionSerializer.readSplineFunction(ois);
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/pulse/input/Metadata.java b/src/main/java/pulse/input/Metadata.java
index cd9369c..6840ff5 100644
--- a/src/main/java/pulse/input/Metadata.java
+++ b/src/main/java/pulse/input/Metadata.java
@@ -42,11 +42,12 @@
*/
public class Metadata extends PropertyHolder implements Reflexive {
+ private static final long serialVersionUID = -7954252611294551707L;
private Set data;
private SampleName sampleName;
private int externalID;
- private InstanceDescriptor extends PulseTemporalShape> pulseDescriptor
+ private InstanceDescriptor extends PulseTemporalShape> pulseDescriptor
= new InstanceDescriptor<>("Pulse Shape Selector", PulseTemporalShape.class);
private NumericPulseData pulseData;
@@ -61,7 +62,7 @@ public class Metadata extends PropertyHolder implements Reflexive {
* experimental setup.
*/
public Metadata(NumericProperty temperature, int externalId) {
- sampleName = new SampleName();
+ sampleName = new SampleName(null);
setExternalID(externalId);
pulseDescriptor.setSelectedDescriptor(RectangularPulse.class.getSimpleName());
data = new TreeSet<>();
@@ -117,13 +118,14 @@ public void setSampleName(SampleName sampleName) {
public final void setPulseData(NumericPulseData pulseData) {
this.pulseData = pulseData;
- this.set(PULSE_WIDTH, derive(PULSE_WIDTH, pulseData.pulseWidth()) );
+ this.set(PULSE_WIDTH, derive(PULSE_WIDTH, pulseData.pulseWidth()));
}
/**
* If a Numerical Pulse has been loaded (for example, when importing from
* Proteus), this will return an object describing this data.
- * @return
+ *
+ * @return
*/
public final NumericPulseData getPulseData() {
return pulseData;
@@ -186,7 +188,7 @@ public void set(NumericPropertyKeyword type, NumericProperty property) {
@Override
public List listedTypes() {
List list = super.listedTypes();
- list.add(new SampleName());
+ list.add(new SampleName(""));
list.add(pulseDescriptor);
return list;
}
@@ -272,4 +274,4 @@ public boolean equals(Object o) {
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/input/Range.java b/src/main/java/pulse/input/Range.java
index fd6e4e9..09b247d 100644
--- a/src/main/java/pulse/input/Range.java
+++ b/src/main/java/pulse/input/Range.java
@@ -18,7 +18,6 @@
import pulse.math.Segment;
import pulse.math.transforms.StickTransform;
import pulse.problem.schemes.solvers.SolverException;
-import pulse.properties.Flag;
import pulse.properties.NumericProperty;
import pulse.properties.NumericPropertyKeyword;
import pulse.search.Optimisable;
@@ -32,12 +31,14 @@
*/
public class Range extends PropertyHolder implements Optimisable {
- private Segment segment;
-
- public final static Range UNLIMITED = new Range (Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
+ private static final long serialVersionUID = 5326569416384623525L;
+
+ private final Segment segment;
+
+ public final static Range UNLIMITED = new Range(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
public final static Range NEGATIVE = new Range(Double.NEGATIVE_INFINITY, -1E-16);
public final static Range POSITIVE = new Range(1e-16, Double.POSITIVE_INFINITY);
-
+
/**
* Constructs a {@code Range} from the minimum and maximum values of
* {@code data}.
@@ -60,44 +61,43 @@ public Range(List data) {
public Range(double a, double b) {
this.segment = new Segment(a, b);
}
-
+
/**
- * Contains a data double array ([0] - x, [1] - y),
- * where the data points have been filtered so that
- * each x fits into this range.
+ * Contains a data double array ([0] - x, [1] - y), where the data points
+ * have been filtered so that each x fits into this range.
+ *
* @param input
* @return a [2][...] array containing filtered x and y values
*/
-
public List[] filter(DiscreteInput input) {
- var x = input.getX();
- var y = input.getY();
-
- if(x.size() != y.size()) {
- throw new IllegalArgumentException("x.length != y.length");
- }
-
- var xf = new ArrayList();
- var yf = new ArrayList();
-
- double min = segment.getMinimum();
- double max = segment.getMaximum();
-
- final double eps = 1E-10;
-
- for(int i = 0, size = x.size(); i < size; i++) {
-
- if(x.get(i) > min && x.get(i) < max + eps) {
-
- xf.add(x.get(i));
- yf.add(y.get(i));
-
- }
-
- }
-
- return new List[]{xf, yf};
-
+ var x = input.getX();
+ var y = input.getY();
+
+ if (x.size() != y.size()) {
+ throw new IllegalArgumentException("x.length != y.length");
+ }
+
+ var xf = new ArrayList();
+ var yf = new ArrayList();
+
+ double min = segment.getMinimum();
+ double max = segment.getMaximum();
+
+ final double eps = 1E-10;
+
+ for (int i = 0, size = x.size(); i < size; i++) {
+
+ if (x.get(i) > min && x.get(i) < max + eps) {
+
+ xf.add(x.get(i));
+ yf.add(y.get(i));
+
+ }
+
+ }
+
+ return new List[]{xf, yf};
+
}
/**
@@ -139,12 +139,12 @@ public NumericProperty getUpperBound() {
*/
public void setLowerBound(NumericProperty p) {
requireType(p, LOWER_BOUND);
-
- if( boundLimits(false).contains( ((Number)p.getValue()).doubleValue())) {
+
+ if (boundLimits(false).contains(((Number) p.getValue()).doubleValue())) {
segment.setMinimum((double) p.getValue());
firePropertyChanged(this, p);
}
-
+
}
/**
@@ -154,12 +154,12 @@ public void setLowerBound(NumericProperty p) {
*/
public void setUpperBound(NumericProperty p) {
requireType(p, UPPER_BOUND);
-
- if( boundLimits(true).contains( ((Number)p.getValue()).doubleValue()) ) {
+
+ if (boundLimits(true).contains(((Number) p.getValue()).doubleValue())) {
segment.setMaximum((double) p.getValue());
firePropertyChanged(this, p);
}
-
+
}
/**
@@ -215,26 +215,28 @@ public Set listedKeywords() {
set.add(LOWER_BOUND);
set.add(UPPER_BOUND);
return set;
- }
-
+ }
+
/**
* Calculates the allowed range for either the upper or lower bound.
- * @param isUpperBound if {@code true}, will calculate the range for the upper bound, otherwise -- for the lower one.,
+ *
+ * @param isUpperBound if {@code true}, will calculate the range for the
+ * upper bound, otherwise -- for the lower one.,
* @return a Segment range of limits for the specific bound
*/
-
public Segment boundLimits(boolean isUpperBound) {
-
+
var curve = (ExperimentalData) this.getParent();
var seq = curve.getTimeSequence();
double tHalf = curve.getHalfTimeCalculator().getHalfTime();
-
+
Segment result = null;
- if(isUpperBound)
+ if (isUpperBound) {
result = new Segment(2.5 * tHalf, seq.get(seq.size() - 1));
- else
- result = new Segment( Math.max(-0.15 * tHalf, seq.get(0)), 0.75 * tHalf);
-
+ } else {
+ result = new Segment(Math.max(-0.15 * tHalf, seq.get(0)), 0.75 * tHalf);
+ }
+
return result;
}
@@ -250,14 +252,14 @@ public Segment boundLimits(boolean isUpperBound) {
*/
@Override
public void optimisationVector(ParameterVector output) {
-
+
Segment bounds;
-
+
for (Parameter p : output.getParameters()) {
var key = p.getIdentifier().getKeyword();
double value;
-
+
switch (key) {
case UPPER_BOUND:
bounds = boundLimits(true);
@@ -270,7 +272,7 @@ public void optimisationVector(ParameterVector output) {
default:
continue;
}
-
+
var transform = new StickTransform(bounds);
p.setBounds(bounds);
@@ -292,7 +294,7 @@ public void assign(ParameterVector params) throws SolverException {
for (Parameter p : params.getParameters()) {
var key = p.getIdentifier().getKeyword();
- var np = derive( key, p.inverseTransform() );
+ var np = derive(key, p.inverseTransform());
switch (key) {
case UPPER_BOUND:
@@ -313,4 +315,4 @@ public String toString() {
return "Range given by: " + segment.toString();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/input/listeners/CurveEvent.java b/src/main/java/pulse/input/listeners/CurveEvent.java
index a0b69f9..61413bf 100644
--- a/src/main/java/pulse/input/listeners/CurveEvent.java
+++ b/src/main/java/pulse/input/listeners/CurveEvent.java
@@ -1,6 +1,6 @@
package pulse.input.listeners;
-import pulse.HeatingCurve;
+import java.io.Serializable;
/**
* A {@code CurveEvent} is associated with an {@code HeatingCurve} object.
@@ -8,21 +8,18 @@
* @see pulse.HeatingCurve
*
*/
-public class CurveEvent {
+public class CurveEvent implements Serializable {
private CurveEventType type;
- private HeatingCurve data;
/**
* Constructs a {@code CurveEvent} object, combining the {@code type} and
* associated {@code data}
*
* @param type the type of this event
- * @param data the source of the event
*/
- public CurveEvent(CurveEventType type, HeatingCurve data) {
+ public CurveEvent(CurveEventType type) {
this.type = type;
- this.data = data;
}
/**
@@ -34,14 +31,4 @@ public CurveEventType getType() {
return type;
}
- /**
- * Used to get the {@code HeatingCurve} object that has undergone certain
- * changes specified by this event type.
- *
- * @return the associated data
- */
- public HeatingCurve getData() {
- return data;
- }
-
}
diff --git a/src/main/java/pulse/input/listeners/CurveEventType.java b/src/main/java/pulse/input/listeners/CurveEventType.java
index 3dcb5d0..40a55d3 100644
--- a/src/main/java/pulse/input/listeners/CurveEventType.java
+++ b/src/main/java/pulse/input/listeners/CurveEventType.java
@@ -19,12 +19,10 @@ public enum CurveEventType {
* procedure.
*/
TIME_ORIGIN_CHANGED,
-
/**
- * A calculation associated with this curve has finished and
- * the required arrays have been filled.
+ * A calculation associated with this curve has finished and the required
+ * arrays have been filled.
*/
-
CALCULATION_FINISHED;
}
diff --git a/src/main/java/pulse/input/listeners/DataEvent.java b/src/main/java/pulse/input/listeners/DataEvent.java
index d42c1a2..7fefe1c 100644
--- a/src/main/java/pulse/input/listeners/DataEvent.java
+++ b/src/main/java/pulse/input/listeners/DataEvent.java
@@ -1,5 +1,6 @@
package pulse.input.listeners;
+import java.io.Serializable;
import pulse.AbstractData;
/**
@@ -7,7 +8,7 @@
* {@code ExperimentalData}.
*
*/
-public class DataEvent {
+public class DataEvent implements Serializable {
private DataEventType type;
private AbstractData data;
diff --git a/src/main/java/pulse/input/listeners/DataEventType.java b/src/main/java/pulse/input/listeners/DataEventType.java
index da2160c..52c8085 100644
--- a/src/main/java/pulse/input/listeners/DataEventType.java
+++ b/src/main/java/pulse/input/listeners/DataEventType.java
@@ -15,11 +15,9 @@ public enum DataEventType {
*/
RANGE_CHANGED,
-
/**
* All data points loaded and are ready for processing.
*/
-
DATA_LOADED;
}
diff --git a/src/main/java/pulse/input/listeners/DataListener.java b/src/main/java/pulse/input/listeners/DataListener.java
index cb1f3d4..28170c5 100644
--- a/src/main/java/pulse/input/listeners/DataListener.java
+++ b/src/main/java/pulse/input/listeners/DataListener.java
@@ -1,11 +1,13 @@
package pulse.input.listeners;
+import java.io.Serializable;
+
/**
* A listener interface, which is used to listen to {@code DataEvent}s occurring
* with an {@code ExperimentalData} object.
*
*/
-public interface DataListener {
+public interface DataListener extends Serializable {
/**
* Triggered when a certain {@code DataEvent} specified by its
diff --git a/src/main/java/pulse/input/listeners/ExternalDatasetListener.java b/src/main/java/pulse/input/listeners/ExternalDatasetListener.java
index 1bb8539..a73d3d1 100644
--- a/src/main/java/pulse/input/listeners/ExternalDatasetListener.java
+++ b/src/main/java/pulse/input/listeners/ExternalDatasetListener.java
@@ -1,7 +1,6 @@
package pulse.input.listeners;
-import pulse.input.InterpolationDataset.StandartType;
-
+import java.io.Serializable;
/**
* A listener associated with the {@code InterpolationDataset} static repository
* of interpolations.
@@ -9,11 +8,7 @@
*/
public interface ExternalDatasetListener {
- /**
- * Triggered when a data {@code type} has been loaded.
- *
- * @param type a type of the dataset, for which an interpolation is created.
- */
- public void onDataLoaded(StandartType type);
+ public void onSpecificHeatDataLoaded();
+ public void onDensityDataLoaded();
-}
+}
\ No newline at end of file
diff --git a/src/main/java/pulse/io/export/ExportManager.java b/src/main/java/pulse/io/export/ExportManager.java
index 2064c50..892402c 100644
--- a/src/main/java/pulse/io/export/ExportManager.java
+++ b/src/main/java/pulse/io/export/ExportManager.java
@@ -21,7 +21,7 @@
*
*/
public class ExportManager {
-
+
//current working dir
private static File cwd = null;
diff --git a/src/main/java/pulse/io/export/LogPaneExporter.java b/src/main/java/pulse/io/export/TextLogPaneExporter.java
similarity index 67%
rename from src/main/java/pulse/io/export/LogPaneExporter.java
rename to src/main/java/pulse/io/export/TextLogPaneExporter.java
index ade0e0f..317af50 100644
--- a/src/main/java/pulse/io/export/LogPaneExporter.java
+++ b/src/main/java/pulse/io/export/TextLogPaneExporter.java
@@ -4,22 +4,23 @@
import java.io.FileOutputStream;
import java.io.IOException;
+import javax.swing.JEditorPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.html.HTMLEditorKit;
-import pulse.ui.components.LogPane;
+import pulse.ui.components.TextLogPane;
/**
* Similar to a {@code LogExporter}, except that it works only on the contents
* of a {@code LogPane} currently being displayed to the user.
*
*/
-public class LogPaneExporter implements Exporter {
+public class TextLogPaneExporter implements Exporter {
- private static LogPaneExporter instance = new LogPaneExporter();
+ private static TextLogPaneExporter instance = new TextLogPaneExporter();
- private LogPaneExporter() {
+ private TextLogPaneExporter() {
// intentionally blank
}
@@ -29,10 +30,11 @@ private LogPaneExporter() {
* argument is ignored. After exporting, the stream is explicitly closed.
*/
@Override
- public void printToStream(LogPane pane, FileOutputStream fos, Extension extension) {
- var kit = (HTMLEditorKit) pane.getEditorKit();
+ public void printToStream(TextLogPane pane, FileOutputStream fos, Extension extension) {
+ var editorPane = (JEditorPane) pane.getGUIComponent();
+ var kit = (HTMLEditorKit) editorPane.getEditorKit();
try {
- kit.write(fos, pane.getDocument(), 0, pane.getDocument().getLength());
+ kit.write(fos, editorPane.getDocument(), 0, editorPane.getDocument().getLength());
} catch (IOException | BadLocationException e) {
System.err.println("Could not export the log pane!");
e.printStackTrace();
@@ -50,7 +52,7 @@ public void printToStream(LogPane pane, FileOutputStream fos, Extension extensio
*
* @return an instance of{@code LogPaneExporter}.
*/
- public static LogPaneExporter getInstance() {
+ public static TextLogPaneExporter getInstance() {
return instance;
}
@@ -58,8 +60,8 @@ public static LogPaneExporter getInstance() {
* @return {@code LogPane.class}.
*/
@Override
- public Class target() {
- return LogPane.class;
+ public Class target() {
+ return TextLogPane.class;
}
/**
diff --git a/src/main/java/pulse/io/readers/AbstractReader.java b/src/main/java/pulse/io/readers/AbstractReader.java
index d98036e..29bbc62 100644
--- a/src/main/java/pulse/io/readers/AbstractReader.java
+++ b/src/main/java/pulse/io/readers/AbstractReader.java
@@ -13,6 +13,7 @@
* lists, arrays and containers may (and usually will) change as a result of
* using the reader.
*
+ *
* @param
*/
public interface AbstractReader extends AbstractHandler {
diff --git a/src/main/java/pulse/io/readers/NetzschCSVReader.java b/src/main/java/pulse/io/readers/NetzschCSVReader.java
index 85c4f1c..d9837f1 100644
--- a/src/main/java/pulse/io/readers/NetzschCSVReader.java
+++ b/src/main/java/pulse/io/readers/NetzschCSVReader.java
@@ -23,6 +23,7 @@
import pulse.input.Metadata;
import pulse.input.Range;
import pulse.properties.NumericPropertyKeyword;
+import pulse.properties.SampleName;
import pulse.ui.Messages;
/**
@@ -49,6 +50,7 @@ public class NetzschCSVReader implements CurveReader {
private final static String DIAMETER = "Diameter";
private final static String L_PULSE_WIDTH = "Laser_pulse_width";
private final static String PULSE_WIDTH = "Pulse_width";
+ private final static String MATERIAL = "Material";
/**
* Note comma is included as a delimiter character here.
@@ -115,6 +117,9 @@ public List read(File file) throws IOException {
int shotId = determineShotID(reader, file);
+ String name = findLineByLabel(reader, MATERIAL, DETECTOR_SPOT_SIZE, true)
+ .substring(MATERIAL.length() + 1)
+ .replaceAll(delims, "");
String spot = findLineByLabel(reader, DETECTOR_SPOT_SIZE, THICKNESS, false);
double spotSize = 0;
@@ -164,6 +169,7 @@ public List read(File file) throws IOException {
if (pulseWidth > 1e-10) {
met.set(NumericPropertyKeyword.PULSE_WIDTH, derive(NumericPropertyKeyword.PULSE_WIDTH, pulseWidth));
}
+ met.setSampleName(new SampleName(name));
met.set(NumericPropertyKeyword.THICKNESS, derive(NumericPropertyKeyword.THICKNESS, thickness));
met.set(NumericPropertyKeyword.DIAMETER, derive(NumericPropertyKeyword.DIAMETER, diameter));
met.set(NumericPropertyKeyword.FOV_OUTER, derive(NumericPropertyKeyword.FOV_OUTER, spotSize != 0 ? spotSize : 0.85 * diameter));
diff --git a/src/main/java/pulse/io/readers/NetzschPulseCSVReader.java b/src/main/java/pulse/io/readers/NetzschPulseCSVReader.java
index 7d759e6..bfc07fe 100644
--- a/src/main/java/pulse/io/readers/NetzschPulseCSVReader.java
+++ b/src/main/java/pulse/io/readers/NetzschPulseCSVReader.java
@@ -55,8 +55,8 @@ public NumericPulseData read(File file) throws IOException {
Objects.requireNonNull(file, Messages.getString("DATReader.1"));
NumericPulseData data = null;
-
- ( (NetzschCSVReader) NetzschCSVReader.getInstance() )
+
+ ((NetzschCSVReader) NetzschCSVReader.getInstance())
.setDefaultLocale(); //always start with a default locale
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
diff --git a/src/main/java/pulse/io/readers/ReaderManager.java b/src/main/java/pulse/io/readers/ReaderManager.java
index 0f8201b..5d168a9 100644
--- a/src/main/java/pulse/io/readers/ReaderManager.java
+++ b/src/main/java/pulse/io/readers/ReaderManager.java
@@ -214,27 +214,28 @@ public static Set readDirectory(List> readers, File dir
}
var es = Executors.newSingleThreadExecutor();
-
+
var callableList = new ArrayList>();
-
+
for (File f : directory.listFiles()) {
Callable callable = () -> read(readers, f);
callableList.add(callable);
}
-
+
Set result = new HashSet<>();
-
+
try {
List> futures = es.invokeAll(callableList);
-
- for(Future f : futures)
+
+ for (Future f : futures) {
result.add(f.get());
-
+ }
+
} catch (InterruptedException ex) {
- Logger.getLogger(ReaderManager.class.getName()).log(Level.SEVERE,
+ Logger.getLogger(ReaderManager.class.getName()).log(Level.SEVERE,
"Reading interrupted when loading files from " + directory.toString(), ex);
} catch (ExecutionException ex) {
- Logger.getLogger(ReaderManager.class.getName()).log(Level.SEVERE,
+ Logger.getLogger(ReaderManager.class.getName()).log(Level.SEVERE,
"Error executing read operation using concurrency", ex);
}
diff --git a/src/main/java/pulse/math/AbstractIntegrator.java b/src/main/java/pulse/math/AbstractIntegrator.java
index 1fadb3a..b56c00e 100644
--- a/src/main/java/pulse/math/AbstractIntegrator.java
+++ b/src/main/java/pulse/math/AbstractIntegrator.java
@@ -1,5 +1,6 @@
package pulse.math;
+import java.io.Serializable;
import pulse.util.PropertyHolder;
import pulse.util.Reflexive;
@@ -10,7 +11,7 @@
* or more variables and the other to actually do the integration.
*
*/
-public abstract class AbstractIntegrator extends PropertyHolder implements Reflexive {
+public abstract class AbstractIntegrator extends PropertyHolder implements Reflexive, Serializable {
private Segment integrationBounds;
diff --git a/src/main/java/pulse/math/FFTTransformer.java b/src/main/java/pulse/math/FFTTransformer.java
index 7e5390d..dea0d65 100644
--- a/src/main/java/pulse/math/FFTTransformer.java
+++ b/src/main/java/pulse/math/FFTTransformer.java
@@ -1,15 +1,17 @@
package pulse.math;
+import java.io.Serializable;
import org.apache.commons.math3.complex.Complex;
import org.apache.commons.math3.transform.DftNormalization;
import org.apache.commons.math3.transform.FastFourierTransformer;
import org.apache.commons.math3.transform.TransformType;
-public class FFTTransformer {
+public class FFTTransformer implements Serializable {
+ private static final long serialVersionUID = -5424502578926616928L;
private double[] amplitudeSpec;
private double[] phaseSpec;
-
+
private int n; //number of input points
private Complex[] buffer;
@@ -18,7 +20,7 @@ public class FFTTransformer {
public FFTTransformer(double[] realInput) {
this(Window.HANN, realInput, new double[realInput.length]);
}
-
+
public FFTTransformer(Window window, double[] realInput) {
this(window, realInput, new double[realInput.length]);
}
@@ -68,7 +70,7 @@ public FFTTransformer(Window window, double[] realInput, double[] imagInput) {
public double[] sampling(double[] x) {
final double totalTime = x[n - 2] - x[0];
double[] sample = new double[buffer.length / 2];
- double fs = n/totalTime; //sampling rate
+ double fs = n / totalTime; //sampling rate
for (int i = 0; i < sample.length; i++) {
sample[i] = i * fs / buffer.length;
}
@@ -132,5 +134,5 @@ public double[] getAmpltiudeSpectrum() {
public double[] getPhaseSpectrum() {
return phaseSpec;
}
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/math/FixedIntervalIntegrator.java b/src/main/java/pulse/math/FixedIntervalIntegrator.java
index ac77ccb..8631efb 100644
--- a/src/main/java/pulse/math/FixedIntervalIntegrator.java
+++ b/src/main/java/pulse/math/FixedIntervalIntegrator.java
@@ -20,6 +20,7 @@
*/
public abstract class FixedIntervalIntegrator extends AbstractIntegrator {
+ private static final long serialVersionUID = -5304597610450009326L;
private int integrationSegments;
/**
diff --git a/src/main/java/pulse/math/FunctionWithInterpolation.java b/src/main/java/pulse/math/FunctionWithInterpolation.java
index 9cbf3d4..41971b7 100644
--- a/src/main/java/pulse/math/FunctionWithInterpolation.java
+++ b/src/main/java/pulse/math/FunctionWithInterpolation.java
@@ -1,18 +1,25 @@
package pulse.math;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.interpolation.SplineInterpolator;
+import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
+import pulse.util.FunctionSerializer;
/**
* An abstract class for univariate functions with the capacity of spline
* interpolation.
*
*/
-public abstract class FunctionWithInterpolation {
+public abstract class FunctionWithInterpolation implements Serializable {
+ private static final long serialVersionUID = -303222542756574714L;
private Segment tBounds;
private int lookupTableSize;
- private UnivariateFunction interpolation;
+ private transient UnivariateFunction interpolation;
public final static int NUM_PARTITIONS = 8192;
@@ -114,4 +121,26 @@ private void interpolate(double[] lookupTable) {
interpolation = splineInterpolation.interpolate(tArray, lookupTable);
}
+ /*
+ * Serialization
+ */
+ private void writeObject(ObjectOutputStream oos)
+ throws IOException {
+ // default serialization
+ oos.defaultWriteObject();
+ // write the object
+ oos.writeObject(tBounds);
+ oos.writeInt(lookupTableSize);
+ FunctionSerializer.writeSplineFunction((PolynomialSplineFunction) interpolation, oos);
+ }
+
+ private void readObject(ObjectInputStream ois)
+ throws ClassNotFoundException, IOException {
+ // default deserialization
+ ois.defaultReadObject();
+ this.tBounds = (Segment) ois.readObject();
+ this.lookupTableSize = ois.readInt();
+ this.interpolation = FunctionSerializer.readSplineFunction(ois);
+ }
+
}
diff --git a/src/main/java/pulse/math/Harmonic.java b/src/main/java/pulse/math/Harmonic.java
index 06e3604..b5207f3 100644
--- a/src/main/java/pulse/math/Harmonic.java
+++ b/src/main/java/pulse/math/Harmonic.java
@@ -30,6 +30,8 @@
*/
public class Harmonic extends PropertyHolder implements Optimisable, Comparable {
+ private static final long serialVersionUID = 3732379391172485157L;
+
private int rank = -1;
private double amplitude;
@@ -135,7 +137,7 @@ public void set(NumericPropertyKeyword type, NumericProperty property) {
public void optimisationVector(ParameterVector output) {
var params = output.getParameters();
-
+
for (int i = 0, size = params.size(); i < size; i++) {
var p = params.get(i);
@@ -182,13 +184,13 @@ public void optimisationVector(ParameterVector output) {
var newParam = new Parameter(newId, transform, bounds);
newParam.setValue(value);
params.add(newParam);
-
+
}
}
}
-
+
}
@Override
@@ -259,7 +261,7 @@ public int compareTo(Harmonic o) {
@Override
public String toString() {
- return String.format("[%1d]: f = %3.2f, A = %3.2f, phi = %3.2f",
+ return String.format("[%1d]: f = %3.2f, A = %3.2f, phi = %3.2f",
rank, frequency, amplitude, phaseShift);
}
diff --git a/src/main/java/pulse/math/LegendrePoly.java b/src/main/java/pulse/math/LegendrePoly.java
index b809507..29a82bf 100644
--- a/src/main/java/pulse/math/LegendrePoly.java
+++ b/src/main/java/pulse/math/LegendrePoly.java
@@ -1,5 +1,6 @@
package pulse.math;
+import java.io.Serializable;
import static pulse.math.MathUtils.fastPowInt;
import static pulse.math.MathUtils.fastPowLoop;
import static pulse.properties.NumericProperties.def;
@@ -21,8 +22,9 @@
* @see Wiki
* page
*/
-public class LegendrePoly {
+public class LegendrePoly implements Serializable {
+ private static final long serialVersionUID = -6859690814783610846L;
private double[] c;
private int n;
diff --git a/src/main/java/pulse/math/MidpointIntegrator.java b/src/main/java/pulse/math/MidpointIntegrator.java
index cc66763..6109de5 100644
--- a/src/main/java/pulse/math/MidpointIntegrator.java
+++ b/src/main/java/pulse/math/MidpointIntegrator.java
@@ -11,6 +11,8 @@
*/
public abstract class MidpointIntegrator extends FixedIntervalIntegrator {
+ private static final long serialVersionUID = -5434607461290096748L;
+
public MidpointIntegrator(Segment bounds, NumericProperty segments) {
super(bounds, segments);
}
diff --git a/src/main/java/pulse/math/Parameter.java b/src/main/java/pulse/math/Parameter.java
index 5556cd1..b46e02e 100644
--- a/src/main/java/pulse/math/Parameter.java
+++ b/src/main/java/pulse/math/Parameter.java
@@ -1,12 +1,14 @@
package pulse.math;
+import java.io.Serializable;
import pulse.math.transforms.Transformable;
/**
* Parameter class
*/
-public class Parameter {
+public class Parameter implements Serializable {
+ private static final long serialVersionUID = 3222166682943107207L;
private ParameterIdentifier index;
private Transformable transform;
private Segment bound;
@@ -17,9 +19,9 @@ public Parameter(ParameterIdentifier index, Transformable transform, Segment bou
this.transform = transform;
this.bound = bound;
}
-
+
public Parameter(ParameterIdentifier index) {
- if(index.getKeyword() != null) {
+ if (index.getKeyword() != null) {
bound = Segment.boundsFrom(index.getKeyword());
}
this.index = index;
@@ -80,8 +82,8 @@ public double getApparentValue() {
public void setValue(double value, boolean ignoreTransform) {
this.value = transform == null || ignoreTransform
- ? value
- : transform.transform(value);
+ ? value
+ : transform.transform(value);
}
public void setValue(double value) {
diff --git a/src/main/java/pulse/math/ParameterIdentifier.java b/src/main/java/pulse/math/ParameterIdentifier.java
index b96847d..31a66f7 100644
--- a/src/main/java/pulse/math/ParameterIdentifier.java
+++ b/src/main/java/pulse/math/ParameterIdentifier.java
@@ -1,53 +1,68 @@
package pulse.math;
+import java.io.Serializable;
+import java.util.Objects;
import pulse.properties.NumericPropertyKeyword;
-public class ParameterIdentifier {
-
+public class ParameterIdentifier implements Serializable {
+
+ private static final long serialVersionUID = 5288875329862605319L;
private NumericPropertyKeyword keyword;
private int index;
-
+
public ParameterIdentifier(NumericPropertyKeyword keyword, int index) {
this.keyword = keyword;
this.index = index;
}
-
+
public ParameterIdentifier(NumericPropertyKeyword keyword) {
this(keyword, 0);
}
-
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 29 * hash + Objects.hashCode(this.keyword);
+ hash = 29 * hash + this.index;
+ return hash;
+ }
+
public ParameterIdentifier(int index) {
this.index = index;
}
-
+
public NumericPropertyKeyword getKeyword() {
return keyword;
}
-
+
public int getIndex() {
return index;
}
-
+
@Override
public boolean equals(Object id) {
- if(!id.getClass().equals(ParameterIdentifier.class)) {
+ if (id.getClass() == null) {
return false;
}
-
+
+ var classA = id.getClass();
+ var classB = this.getClass();
+
+ if (classA != classB) {
+ return false;
+ }
+
var pid = (ParameterIdentifier) id;
-
- boolean result = true;
-
- if(keyword != pid.keyword || index != pid.index)
- result = false;
-
- return result;
-
- }
-
+ return keyword == pid.keyword && Math.abs(index - pid.index) < 1;
+ }
+
@Override
public String toString() {
- return keyword + " # " + index;
+ StringBuilder sb = new StringBuilder("").append(keyword);
+ if (index > 0) {
+ sb.append(" # ").append(index);
+ }
+ return sb.toString();
}
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/math/ParameterVector.java b/src/main/java/pulse/math/ParameterVector.java
index 6bd1737..f9d27fb 100644
--- a/src/main/java/pulse/math/ParameterVector.java
+++ b/src/main/java/pulse/math/ParameterVector.java
@@ -1,9 +1,8 @@
package pulse.math;
+import java.io.Serializable;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.stream.Collectors;
import pulse.math.linear.Vector;
@@ -15,9 +14,10 @@
* A wrapper subclass that assigns {@code ParameterIdentifier}s to specific
* components of the vector. Used when constructing the optimisation vector.
*/
-public class ParameterVector {
+public class ParameterVector implements Serializable {
- private List params;
+ private static final long serialVersionUID = -4678286597080149891L;
+ private final List params;
/**
* Constructs an {@code IndexedVector} with the specified list of keywords.
@@ -109,11 +109,11 @@ public void setValues(Vector v) {
throw new IllegalArgumentException("Illegal vector dimension: "
+ dim + " != " + this.dimension());
}
-
- for(int i = 0; i < dim; i++) {
+
+ for (int i = 0; i < dim; i++) {
params.get(i).setValue(v.get(i));
}
-
+
}
public int dimension() {
diff --git a/src/main/java/pulse/math/Segment.java b/src/main/java/pulse/math/Segment.java
index c1e0c76..95e6c23 100644
--- a/src/main/java/pulse/math/Segment.java
+++ b/src/main/java/pulse/math/Segment.java
@@ -1,5 +1,6 @@
package pulse.math;
+import java.io.Serializable;
import java.util.Random;
import pulse.properties.NumericPropertyKeyword;
import static pulse.properties.NumericProperties.def;
@@ -9,11 +10,15 @@
* that {@code a < b}.
*
*/
-public class Segment {
+public class Segment implements Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1373763811823628708L;
private double a;
private double b;
-
+
public final static Segment UNBOUNDED = new Segment(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
/**
@@ -36,17 +41,17 @@ public Segment(Segment segment) {
this.a = segment.a;
this.b = segment.b;
}
-
+
/**
- * Creates a segment representing the bounds of {@code p}, i.e. the range
- * in which the property value is allowed to change
+ * Creates a segment representing the bounds of {@code p}, i.e. the range in
+ * which the property value is allowed to change
+ *
* @param p a property keyword to extract default bounds
* @return a {@code Segment} with the bounds
*/
-
public static Segment boundsFrom(NumericPropertyKeyword p) {
- return new Segment(def(p).getMinimum().doubleValue(),
- def(p).getMaximum().doubleValue());
+ return new Segment(def(p).getMinimum().doubleValue(),
+ def(p).getMaximum().doubleValue());
}
/**
diff --git a/src/main/java/pulse/math/SimpsonIntegrator.java b/src/main/java/pulse/math/SimpsonIntegrator.java
index 55ddda7..8a367d6 100644
--- a/src/main/java/pulse/math/SimpsonIntegrator.java
+++ b/src/main/java/pulse/math/SimpsonIntegrator.java
@@ -11,6 +11,8 @@
*/
public abstract class SimpsonIntegrator extends FixedIntervalIntegrator {
+ private static final long serialVersionUID = -7800272372472765906L;
+
public SimpsonIntegrator(Segment bounds) {
super(bounds);
}
diff --git a/src/main/java/pulse/math/Window.java b/src/main/java/pulse/math/Window.java
index 48fbd4f..a230ccb 100644
--- a/src/main/java/pulse/math/Window.java
+++ b/src/main/java/pulse/math/Window.java
@@ -1,60 +1,58 @@
package pulse.math;
-public interface Window {
+import java.io.Serializable;
+
+public interface Window extends Serializable {
public final static Window NONE = (n, N) -> 1.0;
- public final static Window HANN = (n, N) -> Math.pow( Math.sin(Math.PI * n / ((double) N)), 2);
- public final static Window HAMMING = (n, N) -> 0.54 + 0.46*Math.cos(2.0 * Math.PI * n / ((double) N));
+ public final static Window HANN = (n, N) -> Math.pow(Math.sin(Math.PI * n / ((double) N)), 2);
+ public final static Window HAMMING = (n, N) -> 0.54 + 0.46 * Math.cos(2.0 * Math.PI * n / ((double) N));
public final static Window BLACKMANN_HARRIS = (n, N) -> {
- final double x = 2.0*Math.PI*n/ ((double)N);
- return 0.35875 - 0.48829*Math.cos(x) + 0.14128*Math.cos(2.0*x) - 0.01168*Math.cos(3.0*x);
- };
- public final static Window FLAT_TOP = (n, N) -> {
- final double x = 2.0*Math.PI*n/ ((double)N);
- return 0.21557895 - 0.41663158*Math.cos(x) + 0.277263158*Math.cos(2.0*x)
- - 0.083578947*Math.cos(3.0*x) + 0.006947368 * Math.cos(4.0 * x);
- };
+ final double x = 2.0 * Math.PI * n / ((double) N);
+ return 0.35875 - 0.48829 * Math.cos(x) + 0.14128 * Math.cos(2.0 * x) - 0.01168 * Math.cos(3.0 * x);
+ };
+ public final static Window FLAT_TOP = (n, N) -> {
+ final double x = 2.0 * Math.PI * n / ((double) N);
+ return 0.21557895 - 0.41663158 * Math.cos(x) + 0.277263158 * Math.cos(2.0 * x)
+ - 0.083578947 * Math.cos(3.0 * x) + 0.006947368 * Math.cos(4.0 * x);
+ };
public final static Window TUKEY = new Window() {
-
+
private final static double alpha = 0.6;
-
+
@Override
public double evaluate(int n, int N) {
-
+
double result = 0;
-
- if(n < 0.5*alpha*N) {
- result = 0.5 * ( 1 - Math.cos(2.0*Math.PI*n/(alpha*N)));
- }
-
- else if(n <= N/2) {
+
+ if (n < 0.5 * alpha * N) {
+ result = 0.5 * (1 - Math.cos(2.0 * Math.PI * n / (alpha * N)));
+ } else if (n <= N / 2) {
result = 1.0;
+ } else {
+ result = TUKEY.evaluate(N - n, N);
}
-
- else {
- result = TUKEY.evaluate(N - n,N);
- }
-
+
return result;
-
+
}
};
-
+
public final static Window HANN_POISSON = (n, N) -> {
-
+
final double alpha = 2.0;
- return HANN.evaluate(n, N) * Math.exp( - alpha * (N - 2 * n) / N);
-
+ return HANN.evaluate(n, N) * Math.exp(-alpha * (N - 2 * n) / N);
+
};
-
+
public default double[] apply(double[] input) {
double[] output = new double[input.length];
- for(int i = 0; i < output.length; i++) {
+ for (int i = 0; i < output.length; i++) {
output[i] = input[i] * evaluate(i, input.length);
}
return output;
}
-
+
public abstract double evaluate(int n, int N);
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/math/ZScore.java b/src/main/java/pulse/math/ZScore.java
index fa13fad..83be83a 100644
--- a/src/main/java/pulse/math/ZScore.java
+++ b/src/main/java/pulse/math/ZScore.java
@@ -17,23 +17,22 @@
* calculated as the difference of the current value and population mean divided
* by the population standard deviation.
*/
-
public class ZScore {
-
+
private double[] avgFilter;
private double[] stdFilter;
private int[] signals;
-
+
private int lag;
private double threshold;
private double influence;
-
+
public ZScore(int lag, double threshold, double influence) {
this.lag = lag;
this.threshold = threshold;
this.influence = influence;
}
-
+
public ZScore() {
this(40, 3.5, 0.3);
}
@@ -42,32 +41,32 @@ public void process(double[] input) {
signals = new int[input.length];
List filteredY = DoubleStream.of(input).boxed().collect(Collectors.toList());
-
- var initialWindow = filteredY.subList(input.length - lag, input.length - 1);
+
+ var initialWindow = new ArrayList<>(filteredY.subList(input.length - lag, input.length - 1));
avgFilter = new double[input.length];
stdFilter = new double[input.length];
-
+
avgFilter[input.length - lag + 1] = mean(initialWindow);
stdFilter[input.length - lag + 1] = stdev(initialWindow);
for (int i = input.length - lag; i > 0; i--) {
-
+
if (Math.abs(input[i] - avgFilter[i + 1]) > threshold * stdFilter[i + 1]) {
-
+
signals[i] = (input[i] > avgFilter[i + 1]) ? 1 : -1;
- filteredY.set(i, influence * input[i]
- + (1 - influence) * filteredY.get(i + 1));
-
+ filteredY.set(i, influence * input[i]
+ + (1 - influence) * filteredY.get(i + 1));
+
} else {
-
+
signals[i] = 0;
filteredY.set(i, input[i]);
-
+
}
// Update rolling average and deviation
- var slidingWindow = filteredY.subList(i, i + lag - 1);
+ var slidingWindow = new ArrayList<>(filteredY.subList(i, i + lag - 1));
avgFilter[i] = mean(slidingWindow);
stdFilter[i] = stdev(slidingWindow);
@@ -89,19 +88,19 @@ private static double stdev(List values) {
}
return ret;
}
-
+
public int[] getSignals() {
return signals;
}
-
+
public double[] getFilteredAverage() {
return avgFilter;
}
-
+
public double[] getFilteredStdev() {
return stdFilter;
}
-
+
/*
public static void main(String[] args) {
Scanner sc = null;
@@ -129,6 +128,5 @@ public static void main(String[] args) {
}
}
- */
-
-}
\ No newline at end of file
+ */
+}
diff --git a/src/main/java/pulse/math/filters/AssignmentListener.java b/src/main/java/pulse/math/filters/AssignmentListener.java
index 251884a..6020aa6 100644
--- a/src/main/java/pulse/math/filters/AssignmentListener.java
+++ b/src/main/java/pulse/math/filters/AssignmentListener.java
@@ -1,7 +1,9 @@
package pulse.math.filters;
-public interface AssignmentListener {
-
+import java.io.Serializable;
+
+public interface AssignmentListener extends Serializable {
+
public void onValueAssigned();
-
+
}
\ No newline at end of file
diff --git a/src/main/java/pulse/math/filters/Filter.java b/src/main/java/pulse/math/filters/Filter.java
index 067ab3e..0bba2ae 100644
--- a/src/main/java/pulse/math/filters/Filter.java
+++ b/src/main/java/pulse/math/filters/Filter.java
@@ -1,14 +1,16 @@
package pulse.math.filters;
import java.awt.geom.Point2D;
+import java.io.Serializable;
import java.util.List;
import pulse.DiscreteInput;
-public interface Filter {
+public interface Filter extends Serializable {
+
+ public List process(List input);
- public List process(List input);
public default List process(DiscreteInput input) {
return process(DiscreteInput.convert(input.getX(), input.getY()));
- }
-
-}
\ No newline at end of file
+ }
+
+}
diff --git a/src/main/java/pulse/math/filters/HalfTimeCalculator.java b/src/main/java/pulse/math/filters/HalfTimeCalculator.java
index e2ca9ce..7f98f3e 100644
--- a/src/main/java/pulse/math/filters/HalfTimeCalculator.java
+++ b/src/main/java/pulse/math/filters/HalfTimeCalculator.java
@@ -1,6 +1,7 @@
package pulse.math.filters;
import java.awt.geom.Point2D;
+import java.io.Serializable;
import static java.lang.Double.valueOf;
import static java.util.Collections.max;
import java.util.Comparator;
@@ -9,20 +10,21 @@
import pulse.baseline.FlatBaseline;
import pulse.input.IndexRange;
-public class HalfTimeCalculator {
-
+public class HalfTimeCalculator implements Serializable {
+
+ private static final long serialVersionUID = 8302980290467110065L;
private final Filter filter;
private final DiscreteInput data;
private Point2D max;
private double halfTime;
-
+
/**
* A fail-safe factor.
*/
public final static double FAIL_SAFE_FACTOR = 10.0;
- private static final Comparator pointComparator =
- (p1, p2) -> valueOf(p1.getY()).compareTo(valueOf(p2.getY()));
+ private static final Comparator pointComparator
+ = (p1, p2) -> valueOf(p1.getY()).compareTo(valueOf(p2.getY()));
public HalfTimeCalculator(DiscreteInput input) {
this.data = input;
@@ -40,56 +42,55 @@ public HalfTimeCalculator(DiscreteInput input) {
* The index corresponding to the closest temperature value available for
* that curve is used to retrieve the half-rise time (which also has the
* same index). If this fails, i.e. the associated index is less than 1,
- * this will print out a warning message and still assign a value to the
- * half-time variable equal to the acquisition time divided by a fail-safe factor
- * {@value FAIL_SAFE_FACTOR}.
- *
+ * this will print out a warning message and still assign a value to the
+ * half-time variable equal to the acquisition time divided by a fail-safe
+ * factor {@value FAIL_SAFE_FACTOR}.
+ *
+ *
* @see getHalfTime()
*/
public void calculate() {
var baseline = new FlatBaseline();
baseline.fitTo(data);
-
+
var filtered = filter.process(data);
-
+
max = max(filtered, pointComparator);
- double halfMax = (max.getY() + baseline.valueAt(0)) / 2.0;
-
+ double halfMax = (max.getY() + baseline.valueAt(0)) / 2.0;
+
int indexLeft = IndexRange.closestLeft(halfMax,
- filtered.stream().map(point -> point.getY())
- .collect(Collectors.toList()));
-
+ filtered.stream().map(point -> point.getY())
+ .collect(Collectors.toList()));
+
if (indexLeft < 1 || indexLeft > filtered.size() - 2) {
halfTime = filtered.get(filtered.size() - 1).getX() / FAIL_SAFE_FACTOR;
- }
- else {
+ } else {
//extrapolate
Point2D p1 = filtered.get(indexLeft);
Point2D p2 = filtered.get(indexLeft + 1);
-
- halfTime = (halfMax - p1.getY())/(p2.getY() - p1.getY())
- *(p2.getX() - p1.getX()) + p1.getX();
+
+ halfTime = (halfMax - p1.getY()) / (p2.getY() - p1.getY())
+ * (p2.getX() - p1.getX()) + p1.getX();
}
-
+
}
-
-
+
/**
- * Retrieves the half-time value of this dataset, which is equal to the
- * time needed to reach half of the signal maximum.
+ * Retrieves the half-time value of this dataset, which is equal to the time
+ * needed to reach half of the signal maximum.
+ *
* @return the half-time value.
*/
-
public final double getHalfTime() {
return halfTime;
}
-
+
public final Point2D getFilteredMaximum() {
return max;
}
-
+
public DiscreteInput getData() {
return data;
}
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/math/filters/OptimisablePolyline.java b/src/main/java/pulse/math/filters/OptimisablePolyline.java
index 4d7a8d6..4356b4f 100644
--- a/src/main/java/pulse/math/filters/OptimisablePolyline.java
+++ b/src/main/java/pulse/math/filters/OptimisablePolyline.java
@@ -14,9 +14,10 @@
public class OptimisablePolyline extends PropertyHolder implements Optimisable {
+ private static final long serialVersionUID = 418264754603533971L;
private final double[] x;
private final double[] y;
- private final List listeners;
+ private List listeners;
public OptimisablePolyline(List data) {
x = data.stream().mapToDouble(d -> d.getX()).toArray();
@@ -27,7 +28,7 @@ public OptimisablePolyline(List data) {
@Override
public void assign(ParameterVector input) throws SolverException {
var ps = input.getParameters();
- for(int i = 0, size = ps.size(); i < size; i++) {
+ for (int i = 0, size = ps.size(); i < size; i++) {
y[i] = ps.get(i).getApparentValue();
}
listeners.stream().forEach(l -> l.onValueAssigned());
@@ -37,7 +38,7 @@ public void assign(ParameterVector input) throws SolverException {
public void optimisationVector(ParameterVector output) {
output.setValues(new Vector(y));
}
-
+
public List points() {
return DiscreteInput.convert(x, y);
}
@@ -46,17 +47,17 @@ public List points() {
public void set(NumericPropertyKeyword type, NumericProperty property) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
-
+
public double[] getX() {
return x;
}
-
+
public double[] getY() {
return y;
}
-
+
public void addAssignmentListener(AssignmentListener listener) {
listeners.add(listener);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/math/filters/OptimisedRunningAverage.java b/src/main/java/pulse/math/filters/OptimisedRunningAverage.java
index 46c004b..0f9ce5a 100644
--- a/src/main/java/pulse/math/filters/OptimisedRunningAverage.java
+++ b/src/main/java/pulse/math/filters/OptimisedRunningAverage.java
@@ -6,6 +6,8 @@
public class OptimisedRunningAverage extends RunningAverage {
+ private static final long serialVersionUID = 1272276960302188392L;
+
public OptimisedRunningAverage() {
super();
}
@@ -17,10 +19,10 @@ public OptimisedRunningAverage(int reductionFactor) {
@Override
public List process(DiscreteInput input) {
var p = super.process(input);
- var optimisableCurve = new OptimisablePolyline(p);
+ var optimisableCurve = new OptimisablePolyline(p);
var task = new PolylineOptimiser(input, optimisableCurve);
task.run();
return optimisableCurve.points();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/math/filters/PolylineOptimiser.java b/src/main/java/pulse/math/filters/PolylineOptimiser.java
index dde0142..c2f7ffb 100644
--- a/src/main/java/pulse/math/filters/PolylineOptimiser.java
+++ b/src/main/java/pulse/math/filters/PolylineOptimiser.java
@@ -20,6 +20,7 @@
public class PolylineOptimiser extends SimpleOptimisationTask {
+ private static final long serialVersionUID = -9056678836812293655L;
private final OptimiserStatistic sos;
private final PolylineResponse response;
private final OptimisablePolyline optimisableCurve;
@@ -87,4 +88,4 @@ public double evaluate(double t) {
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/math/filters/Randomiser.java b/src/main/java/pulse/math/filters/Randomiser.java
index 3d15453..cfd6d71 100644
--- a/src/main/java/pulse/math/filters/Randomiser.java
+++ b/src/main/java/pulse/math/filters/Randomiser.java
@@ -4,23 +4,24 @@
import java.util.List;
public class Randomiser implements Filter {
-
+
+ private static final long serialVersionUID = 3390706390237573886L;
private final double amplitude;
-
+
public Randomiser(double amplitude) {
this.amplitude = amplitude;
}
@Override
- public List process(List input) {
- input.forEach(p ->
- ((Point2D.Double)p).y += (Math.random() - 0.5) * amplitude
+ public List process(List input) {
+ input.forEach(p
+ -> ((Point2D.Double) p).y += (Math.random() - 0.5) * amplitude
);
return input;
}
-
+
public double getAmplitude() {
return amplitude;
}
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/math/filters/RunningAverage.java b/src/main/java/pulse/math/filters/RunningAverage.java
index 37a08a2..2a2b82b 100644
--- a/src/main/java/pulse/math/filters/RunningAverage.java
+++ b/src/main/java/pulse/math/filters/RunningAverage.java
@@ -3,30 +3,29 @@
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
-import pulse.DiscreteInput;
public class RunningAverage implements Filter {
-
+
+ private static final long serialVersionUID = -6134297308468858848L;
+
private int bins;
-
- /**
+
+ /**
* The binning factor used to build a crude approximation of the heating
* curve. Described in Lunev, A., & Heymer, R. (2020). Review of
* Scientific Instruments, 91(6), 064902.
*/
-
public static final int DEFAULT_BINS = 16;
public final static int MIN_BINS = 4;
-
+
/**
* @param reductionFactor the factor, by which the number of points
* {@code count} will be reduced for this {@code ExperimentalData}.
*/
-
public RunningAverage(int reductionFactor) {
this.bins = reductionFactor;
}
-
+
public RunningAverage() {
this.bins = DEFAULT_BINS;
}
@@ -53,7 +52,6 @@ public RunningAverage() {
* @see halfRiseTime()
* @see pulse.AbstractData.maxTemperature()
*/
-
@Override
public List process(List points) {
var x = points.stream().mapToDouble(p -> p.getX()).toArray();
@@ -62,14 +60,14 @@ public List process(List points) {
int size = x.length;
int step = size / bins;
List movingAverage = new ArrayList<>(bins);
-
+
for (int i = 0; i < bins; i++) {
- int i1 = step*i;
- int i2 = step*(i+1);
+ int i1 = step * i;
+ int i2 = step * (i + 1);
double av = 0;
int j;
-
+
for (j = i1; j < i2 && j < size; j++) {
av += y[j];
}
@@ -77,55 +75,54 @@ public List process(List points) {
av /= j - i1;
i2 = j - 1;
- movingAverage.add(new Point2D.Double(
- (x[i1] + x[i2])/ 2.0, av));
+ movingAverage.add(new Point2D.Double(
+ (x[i1] + x[i2]) / 2.0, av));
}
-
+
addBoundaryPoints(movingAverage, x[0], x[size - 1]);
-
+
/*
for(int i = 0; i < movingAverage.size(); i++) {
System.err.println(movingAverage.get(i));
}
- */
-
+ */
return movingAverage;
- }
-
+ }
+
private static void addBoundaryPoints(List d, double minTime, double maxTime) {
int max = d.size();
-
+
d.add(
- extrapolate(d.get(max - 1),
- d.get(max - 2),
- maxTime)
- );
-
- d.add( 0,
- extrapolate(d.get(0),
- d.get(1),
- minTime)
- );
-
+ extrapolate(d.get(max - 1),
+ d.get(max - 2),
+ maxTime)
+ );
+
+ d.add(0,
+ extrapolate(d.get(0),
+ d.get(1),
+ minTime)
+ );
+
}
-
- private static Point2D extrapolate(Point2D a, Point2D b, double x) {
+
+ private static Point2D extrapolate(Point2D a, Point2D b, double x) {
double y1 = a.getY();
double y2 = b.getY();
double x1 = a.getX();
double x2 = b.getX();
-
- return new Point2D.Double(x, y1 + (x - x1)/(x2 - x1)*(y2 - y1));
+
+ return new Point2D.Double(x, y1 + (x - x1) / (x2 - x1) * (y2 - y1));
}
-
+
public final int getNumberOfBins() {
return bins;
}
-
+
public final void setNumberOfBins(int no) {
this.bins = no > MIN_BINS - 1 ? no : MIN_BINS;
}
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/math/linear/Matrix2.java b/src/main/java/pulse/math/linear/Matrix2.java
index aa57984..00cf409 100644
--- a/src/main/java/pulse/math/linear/Matrix2.java
+++ b/src/main/java/pulse/math/linear/Matrix2.java
@@ -6,6 +6,8 @@
*/
class Matrix2 extends SquareMatrix {
+ private static final long serialVersionUID = 6015187791989387058L;
+
protected Matrix2(double[][] args) {
super(args);
}
diff --git a/src/main/java/pulse/math/linear/Matrix3.java b/src/main/java/pulse/math/linear/Matrix3.java
index 09e799f..3835e32 100644
--- a/src/main/java/pulse/math/linear/Matrix3.java
+++ b/src/main/java/pulse/math/linear/Matrix3.java
@@ -6,6 +6,8 @@
*/
class Matrix3 extends SquareMatrix {
+ private static final long serialVersionUID = -2671066600560428989L;
+
protected Matrix3(double[][] args) {
super(args);
}
diff --git a/src/main/java/pulse/math/linear/Matrix4.java b/src/main/java/pulse/math/linear/Matrix4.java
index 970a7a9..cc34b17 100644
--- a/src/main/java/pulse/math/linear/Matrix4.java
+++ b/src/main/java/pulse/math/linear/Matrix4.java
@@ -6,6 +6,8 @@
*/
class Matrix4 extends SquareMatrix {
+ private static final long serialVersionUID = -1355372261335732541L;
+
protected Matrix4(double[][] args) {
super(args);
}
diff --git a/src/main/java/pulse/math/linear/RectangularMatrix.java b/src/main/java/pulse/math/linear/RectangularMatrix.java
index 8f325dc..8ac8470 100644
--- a/src/main/java/pulse/math/linear/RectangularMatrix.java
+++ b/src/main/java/pulse/math/linear/RectangularMatrix.java
@@ -1,5 +1,6 @@
package pulse.math.linear;
+import java.io.Serializable;
import static pulse.math.MathUtils.approximatelyEquals;
import static pulse.math.linear.ArithmeticOperations.DIFFERENCE;
import static pulse.math.linear.ArithmeticOperations.SUM;
@@ -7,8 +8,9 @@
import pulse.ui.Messages;
-public class RectangularMatrix {
+public class RectangularMatrix implements Serializable {
+ private static final long serialVersionUID = -8184303238440935851L;
protected final double[][] x;
protected RectangularMatrix(double[][] args) {
diff --git a/src/main/java/pulse/math/linear/Vector.java b/src/main/java/pulse/math/linear/Vector.java
index 39d0653..483cf0c 100644
--- a/src/main/java/pulse/math/linear/Vector.java
+++ b/src/main/java/pulse/math/linear/Vector.java
@@ -1,5 +1,6 @@
package pulse.math.linear;
+import java.io.Serializable;
import static java.lang.Math.abs;
import static java.lang.Math.sqrt;
import java.util.List;
@@ -16,8 +17,12 @@
* and ODE solvers.
*
*/
-public class Vector {
+public class Vector implements Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5560069982536341831L;
private double[] x;
/**
@@ -122,7 +127,7 @@ public static Vector random(int n, double min, double max) {
}
return v;
}
-
+
/**
* Component-wise vector multiplication
*/
diff --git a/src/main/java/pulse/math/transforms/AtanhTransform.java b/src/main/java/pulse/math/transforms/AtanhTransform.java
index b65577e..253fd0e 100644
--- a/src/main/java/pulse/math/transforms/AtanhTransform.java
+++ b/src/main/java/pulse/math/transforms/AtanhTransform.java
@@ -11,6 +11,8 @@
*/
public class AtanhTransform extends BoundedParameterTransform {
+ private static final long serialVersionUID = -6322775329000050307L;
+
/**
* Only the upper bound of the argument is used.
*
diff --git a/src/main/java/pulse/math/transforms/InvDiamTransform.java b/src/main/java/pulse/math/transforms/InvDiamTransform.java
index c881081..22345df 100644
--- a/src/main/java/pulse/math/transforms/InvDiamTransform.java
+++ b/src/main/java/pulse/math/transforms/InvDiamTransform.java
@@ -8,6 +8,7 @@
*/
public class InvDiamTransform implements Transformable {
+ private static final long serialVersionUID = 1809584085307619279L;
private double d;
public InvDiamTransform(ExtendedThermalProperties etp) {
diff --git a/src/main/java/pulse/math/transforms/PeriodicTransform.java b/src/main/java/pulse/math/transforms/PeriodicTransform.java
index 31cee06..c788a9b 100644
--- a/src/main/java/pulse/math/transforms/PeriodicTransform.java
+++ b/src/main/java/pulse/math/transforms/PeriodicTransform.java
@@ -4,6 +4,8 @@
public class PeriodicTransform extends BoundedParameterTransform {
+ private static final long serialVersionUID = 4564881912462997982L;
+
/**
* Only the upper bound of the argument is used.
*
@@ -23,7 +25,7 @@ public double transform(double a) {
double max = getBounds().getMaximum();
double min = getBounds().getMinimum();
double len = max - min;
-
+
return a > max ? transform(a - len) : (a < min ? transform(a + len) : a);
}
@@ -35,4 +37,4 @@ public double transform(double a) {
public double inverse(double t) {
return t;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/math/transforms/StickTransform.java b/src/main/java/pulse/math/transforms/StickTransform.java
index f548761..ce5fd4a 100644
--- a/src/main/java/pulse/math/transforms/StickTransform.java
+++ b/src/main/java/pulse/math/transforms/StickTransform.java
@@ -18,16 +18,18 @@
import pulse.math.Segment;
/**
- * A simple bounded transform which makes the parameter stick to the
- * boundaries upon reaching them. For insatnce, when a parameter
+ * A simple bounded transform which makes the parameter stick to the boundaries
+ * upon reaching them. For insatnce, when a parameter
* attempts to escape its bounds due to a larger increment then allowed, this
* transform will return it directly to the respective boundary, where it will
* "stick".
+ *
* @author Artem Lunev
*/
-
public class StickTransform extends BoundedParameterTransform {
+ private static final long serialVersionUID = -8709273330809657074L;
+
/**
* Only the upper bound of the argument is used.
*
@@ -57,5 +59,5 @@ public double transform(double a) {
public double inverse(double t) {
return transform(t);
}
-
+
}
diff --git a/src/main/java/pulse/math/transforms/Transformable.java b/src/main/java/pulse/math/transforms/Transformable.java
index 88e9d13..150f6c3 100644
--- a/src/main/java/pulse/math/transforms/Transformable.java
+++ b/src/main/java/pulse/math/transforms/Transformable.java
@@ -1,11 +1,13 @@
package pulse.math.transforms;
+import java.io.Serializable;
+
/**
* An interface for performing reversible one-to-one mapping of the model
* parameters.
*
*/
-public interface Transformable {
+public interface Transformable extends Serializable {
/**
* Performs the selected transform with {@code value}
diff --git a/src/main/java/pulse/problem/laser/DiscretePulse.java b/src/main/java/pulse/problem/laser/DiscretePulse.java
index e1a283f..5ec9be1 100644
--- a/src/main/java/pulse/problem/laser/DiscretePulse.java
+++ b/src/main/java/pulse/problem/laser/DiscretePulse.java
@@ -1,5 +1,6 @@
package pulse.problem.laser;
+import java.io.Serializable;
import java.util.Objects;
import pulse.input.ExperimentalData;
import pulse.math.MidpointIntegrator;
@@ -7,7 +8,10 @@
import pulse.problem.schemes.Grid;
import pulse.problem.statements.Problem;
import pulse.problem.statements.Pulse;
+import static pulse.properties.NumericProperties.derive;
+import static pulse.properties.NumericPropertyKeyword.TAU_FACTOR;
import pulse.tasks.SearchTask;
+import pulse.util.PropertyHolderListener;
/**
* A {@code DiscretePulse} is an object that acts as a medium between the
@@ -16,13 +20,15 @@
*
* @see pulse.problem.statements.Pulse
*/
-public class DiscretePulse {
+public class DiscretePulse implements Serializable {
+ private static final long serialVersionUID = 5826506918603729615L;
private final Grid grid;
private final Pulse pulse;
-
+ private final ExperimentalData data;
+
private double widthOnGrid;
- private double timeConversionFactor;
+ private double characteristicTime;
private double invTotalEnergy; //normalisation factor
/**
@@ -49,33 +55,28 @@ public class DiscretePulse {
*/
public DiscretePulse(Problem problem, Grid grid) {
this.grid = grid;
- timeConversionFactor = problem.getProperties().timeFactor();
+ characteristicTime = problem.getProperties().characteristicTime();
this.pulse = problem.getPulse();
Object ancestor
= Objects.requireNonNull(problem.specificAncestor(SearchTask.class),
"Problem has not been assigned to a SearchTask");
- ExperimentalData data =
- (ExperimentalData) ( ((SearchTask) ancestor).getInput() );
- init(data);
-
+ data = (ExperimentalData) (((SearchTask) ancestor).getInput());
+ init();
+
+ PropertyHolderListener phl = e -> {
+ characteristicTime = problem.getProperties().characteristicTime();
+ widthOnGrid = 0;
+ init();
+ };
+
pulse.addListener(e -> {
- timeConversionFactor = problem.getProperties().timeFactor();
- init(data);
+ widthOnGrid = 0;
+ init();
});
+ problem.addListener(phl);
- grid.addListener(e
- -> init(data)
- );
-
- }
-
- private void init(ExperimentalData data) {
- widthOnGrid = 0;
- recalculate();
- pulse.getPulseShape().init(data, this);
- invTotalEnergy = 1.0/totalEnergy();
}
/**
@@ -95,39 +96,77 @@ public double laserPowerAt(double time) {
*
* @see pulse.problem.schemes.Grid.gridTime(double,double)
*/
- public final void recalculate() {
- final double nominalWidth = ((Number) pulse.getPulseWidth().getValue()).doubleValue();
- final double resolvedWidth = timeConversionFactor / getWidthToleranceFactor();
+ public final void init() {
+ final double nominalWidth = ((Number) pulse.getPulseWidth().getValue()).doubleValue();
+ final double resolvedWidth = resolvedPulseWidthSeconds();
final double EPS = 1E-10;
-
+
+ double oldValue = widthOnGrid;
+ this.widthOnGrid = pulseWidthGrid();
+
/**
* The pulse is too short, which makes calculations too expensive. Can
* we replace it with a rectangular pulse shape instead?
*/
-
- if (nominalWidth < resolvedWidth - EPS && widthOnGrid < EPS) {
+ if (nominalWidth < resolvedWidth - EPS && oldValue < EPS) {
//change shape to rectangular
var shape = new RectangularPulse();
- pulse.setPulseShape(shape);
- //change pulse width
- setDiscreteWidth(resolvedWidth);
+ pulse.setPulseShape(shape);
shape.init(null, this);
- //adjust the pulse object to update the visualised pulse
- } else if(nominalWidth > resolvedWidth + EPS) {
- setDiscreteWidth(nominalWidth);
- }
-
- invTotalEnergy = 1.0/totalEnergy();
-
+ } else {
+ pulse.getPulseShape().init(data, this);
+ }
+
+ invTotalEnergy = 1.0 / totalEnergy();
}
-
+
/**
- * Calculates the total pulse energy using a numerical integrator.The
- * normalisation factor is then equal to the inverse total energy.
- * @return the total pulse energy, assuming sample area fully covered by the beam
+ * Optimises the {@code Grid} parameters so that the timestep is
+ * sufficiently small to enable accurate pulse correction.
+ *
+ * This can change the {@code tauFactor} and {@code tau} variables in the
+ * {@code Grid} object if {@code discretePulseWidth/(M - 1) < grid.tau},
+ * where M is the required number of pulse calculations.
+ *
+ *
+ * @see PulseTemporalShape.getRequiredDiscretisation()
*/
+ public double pulseWidthGrid() {
+ //minimum number of points for pulse calculation
+ int reqPoints = pulse.getPulseShape().getRequiredDiscretisation();
+ //physical pulse width in time units
+ double experimentalWidth = (double) pulse.getPulseWidth().getValue();
+
+ //minimum resolved pulse width in time units for that specific problem
+ double resolvedWidth = resolvedPulseWidthSeconds();
+
+ double pWidth = Math.max(experimentalWidth, resolvedWidth);
+
+ final double EPS = 1E-10;
+ double newTau = pWidth / characteristicTime / reqPoints;
+
+ double result = 0;
+
+ if (newTau < grid.getTimeStep() - EPS) {
+ double newTauFactor = (double) grid.getTimeFactor().getValue() / 2.0;
+ grid.setTimeFactor(derive(TAU_FACTOR, newTauFactor));
+ result = pulseWidthGrid();
+ } else {
+ result = grid.gridTime(pWidth, characteristicTime);
+ }
+
+ return result;
+ }
+
+ /**
+ * Calculates the total pulse energy using a numerical integrator.The
+ * normalisation factor is then equal to the inverse total energy.
+ *
+ * @return the total pulse energy, assuming sample area fully covered by the
+ * beam
+ */
public final double totalEnergy() {
var pulseShape = pulse.getPulseShape();
@@ -144,27 +183,22 @@ public double integrand(double... vars) {
}
/**
- * Gets the discrete dimensionless pulse width, which is a multiplier of the current
- * grid timestep. The pulse width is converted to the dimensionless pulse width by
- * dividing the real value by l2/a.
+ * Gets the discrete dimensionless pulse width, which is a multiplier of the
+ * current grid timestep. The pulse width is converted to the dimensionless
+ * pulse width by dividing the real value by l2/a.
*
* @return the dimensionless pulse width mapped to the grid.
*/
public double getDiscreteWidth() {
return widthOnGrid;
}
-
- private void setDiscreteWidth(double width) {
- widthOnGrid = grid.gridTime(width, timeConversionFactor);
- grid.adjustTimeStep(this);
- }
/**
* Gets the physical {@code Pulse}
*
* @return the {@code Pulse} object
*/
- public Pulse getPulse() {
+ public Pulse getPhysicalPulse() {
return pulse;
}
@@ -176,36 +210,38 @@ public Pulse getPulse() {
public Grid getGrid() {
return grid;
}
-
+
/**
- * Gets the dimensional factor required to convert real time variable into
- * a dimensional variable, defined in the {@code Problem} class
+ * Gets the dimensional factor required to convert real time variable into a
+ * dimensional variable, defined in the {@code Problem} class
+ *
* @return the conversion factor
*/
-
- public double getConversionFactor() {
- return timeConversionFactor;
+ public double getCharacteristicTime() {
+ return characteristicTime;
}
-
+
/**
- * Gets the minimal resolved pulse width defined by the {@code WIDTH_TOLERANCE_FACTOR}
- * and the characteristic time given by the {@code getConversionFactor}.
- * @return
+ * Gets the minimal resolved pulse width defined by the
+ * {@code WIDTH_TOLERANCE_FACTOR} and the characteristic time given by the
+ * {@code getConversionFactor}.
+ *
+ * @return
*/
-
- public double resolvedPulseWidth() {
- return timeConversionFactor / getWidthToleranceFactor();
+ public double resolvedPulseWidthSeconds() {
+ return characteristicTime / getWidthToleranceFactor();
}
-
- /**
- * Assuming a characteristic time is divided by the return value of this method
- * and is set to the minimal resolved pulse width, shows how small a pulse width
- * can be to enable finite pulse correction.
- * @return the smallest fraction of a characteristic time resolved as a finite pulse.
+
+ /**
+ * Assuming a characteristic time is divided by the return value of this
+ * method and is set to the minimal resolved pulse width, shows how small a
+ * pulse width can be to enable finite pulse correction.
+ *
+ * @return the smallest fraction of a characteristic time resolved as a
+ * finite pulse.
*/
-
public int getWidthToleranceFactor() {
return WIDTH_TOLERANCE_FACTOR;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/problem/laser/DiscretePulse2D.java b/src/main/java/pulse/problem/laser/DiscretePulse2D.java
index ab9fd0e..21be2b8 100644
--- a/src/main/java/pulse/problem/laser/DiscretePulse2D.java
+++ b/src/main/java/pulse/problem/laser/DiscretePulse2D.java
@@ -18,15 +18,15 @@
*/
public class DiscretePulse2D extends DiscretePulse {
+ private static final long serialVersionUID = 6203222036852037146L;
private double discretePulseSpot;
private double sampleRadius;
private double normFactor;
-
+
/**
* This had to be decreased for the 2d pulses.
*/
-
- private final static int WIDTH_TOLERANCE_FACTOR = 200;
+ private final static int WIDTH_TOLERANCE_FACTOR = 1000;
/**
* The constructor for {@code DiscretePulse2D}.
@@ -43,9 +43,9 @@ public DiscretePulse2D(ClassicalProblem2D problem, Grid2D grid) {
super(problem, grid);
var properties = (ExtendedThermalProperties) problem.getProperties();
calcPulseSpot(properties);
- properties.addListener(e -> calcPulseSpot(properties) );
+ properties.addListener(e -> calcPulseSpot(properties));
}
-
+
/**
* This calculates the dimensionless, discretised pulse function at a
* dimensionless radial coordinate {@code coord}.
@@ -61,58 +61,58 @@ public DiscretePulse2D(ClassicalProblem2D problem, Grid2D grid) {
* {@code coord > spotDiameter}.
* @see pulse.problem.laser.PulseTemporalShape.laserPowerAt(double)
*/
-
public double evaluateAt(double time, double radialCoord) {
- return laserPowerAt(time)
+ return laserPowerAt(time)
* (0.5 + 0.5 * signum(discretePulseSpot - radialCoord));
}
-
+
/**
- * Calculates the laser power at a give moment in time. The total laser
- * energy is normalised over a beam partially illuminating the sample surface.
+ * Calculates the laser power at a give moment in time. The total laser
+ * energy is normalised over a beam partially illuminating the sample
+ * surface.
+ *
* @param time a moment in time (in dimensionless units)
* @return the laser power in arbitrary units
*/
-
@Override
public double laserPowerAt(double time) {
return normFactor * super.laserPowerAt(time);
}
-
+
private void calcPulseSpot(ExtendedThermalProperties properties) {
- sampleRadius = (double) properties.getSampleDiameter().getValue() / 2.0;
+ sampleRadius = (double) properties.getSampleDiameter().getValue() / 2.0;
evalPulseSpot();
}
/**
- * Calculates the {@code discretePulseSpot} using the {@code gridRadialDistance} method.
+ * Calculates the {@code discretePulseSpot} using the
+ * {@code gridRadialDistance} method.
*
* @see pulse.problem.schemes.Grid2D.gridRadialDistance(double,double)
*/
public final void evalPulseSpot() {
- var pulse = (Pulse2D) getPulse();
+ var pulse = (Pulse2D) getPhysicalPulse();
var grid2d = (Grid2D) getGrid();
- final double spotRadius = (double) pulse.getSpotDiameter().getValue() / 2.0;
+ final double spotRadius = (double) pulse.getSpotDiameter().getValue() / 2.0;
discretePulseSpot = grid2d.gridRadialDistance(spotRadius, sampleRadius);
grid2d.adjustStepSize(this);
- normFactor = sampleRadius * sampleRadius / spotRadius / spotRadius;
+ normFactor = sampleRadius * sampleRadius / spotRadius / spotRadius;
}
public final double getDiscretePulseSpot() {
return discretePulseSpot;
}
-
+
public final double getRadialConversionFactor() {
return sampleRadius;
}
-
+
/**
* A smaller tolerance factor is set for 2D calculations
*/
-
@Override
public int getWidthToleranceFactor() {
return WIDTH_TOLERANCE_FACTOR;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/problem/laser/ExponentiallyModifiedGaussian.java b/src/main/java/pulse/problem/laser/ExponentiallyModifiedGaussian.java
index 379ab97..d4490d2 100644
--- a/src/main/java/pulse/problem/laser/ExponentiallyModifiedGaussian.java
+++ b/src/main/java/pulse/problem/laser/ExponentiallyModifiedGaussian.java
@@ -24,10 +24,11 @@
*/
public class ExponentiallyModifiedGaussian extends PulseTemporalShape {
+ private static final long serialVersionUID = -4437794069527301235L;
private double mu;
private double sigma;
private double lambda;
-
+
private final static int MIN_POINTS = 10;
/**
@@ -159,4 +160,4 @@ public int getRequiredDiscretisation() {
return MIN_POINTS;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/problem/laser/NumericPulse.java b/src/main/java/pulse/problem/laser/NumericPulse.java
index e834f02..a71d65f 100644
--- a/src/main/java/pulse/problem/laser/NumericPulse.java
+++ b/src/main/java/pulse/problem/laser/NumericPulse.java
@@ -1,10 +1,14 @@
package pulse.problem.laser;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import static pulse.properties.NumericProperties.derive;
import static pulse.properties.NumericPropertyKeyword.PULSE_WIDTH;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.interpolation.AkimaSplineInterpolator;
+import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
import pulse.input.ExperimentalData;
import pulse.problem.statements.Problem;
@@ -14,6 +18,7 @@
import pulse.baseline.FlatBaseline;
import pulse.tasks.Calculation;
+import pulse.util.FunctionSerializer;
/**
* A numeric pulse is given by a set of discrete {@code NumericPulseData}
@@ -24,9 +29,10 @@
*/
public class NumericPulse extends PulseTemporalShape {
+ private static final long serialVersionUID = 6088261629992349844L;
private NumericPulseData pulseData;
- private UnivariateFunction interpolation;
-
+ private transient UnivariateFunction interpolation;
+
private final static int MIN_POINTS = 20;
public NumericPulse() {
@@ -57,40 +63,42 @@ public NumericPulse(NumericPulse pulse) {
public void init(ExperimentalData data, DiscretePulse pulse) {
//generate baseline-subtracted numeric data from ExperimentalData
baselineSubtractedFrom(data);
-
+
//notify host pulse object of a new pulse width
- var problem = ( (Calculation) ((SearchTask) data.getParent())
- .getResponse() ).getProblem();
+ var problem = ((Calculation) ((SearchTask) data.getParent())
+ .getResponse()).getProblem();
setPulseWidthOf(problem);
//convert to dimensionless time and interpolate
- double timeFactor = problem.getProperties().timeFactor();
+ double timeFactor = problem.getProperties().characteristicTime();
doInterpolation(timeFactor);
}
-
+
/**
- * Copies the numeric pulse from metadata and subtracts a horizontal baseline
- * from the data points assigned to {@code pulseData}.
- * @param data the experimental data containing the metadata with numeric pulse data.
+ * Copies the numeric pulse from metadata and subtracts a horizontal
+ * baseline from the data points assigned to {@code pulseData}.
+ *
+ * @param data the experimental data containing the metadata with numeric
+ * pulse data.
*/
-
private void baselineSubtractedFrom(ExperimentalData data) {
pulseData = new NumericPulseData(data.getMetadata().getPulseData());
-
+
//subtracts a horizontal baseline from the pulse data
var baseline = new FlatBaseline();
baseline.fitTo(pulseData);
-
- for(int i = 0, size = pulseData.getTimeSequence().size(); i < size; i++)
- pulseData.setSignalAt(i,
+
+ for (int i = 0, size = pulseData.getTimeSequence().size(); i < size; i++) {
+ pulseData.setSignalAt(i,
pulseData.signalAt(i) - baseline.valueAt(pulseData.timeAt(i)));
+ }
}
private void setPulseWidthOf(Problem problem) {
- var timeSequence = pulseData.getTimeSequence();
- double pulseWidth = timeSequence.get(timeSequence.size() - 1);
+ var timeSequence = pulseData.getTimeSequence();
+ double pulseWidth = timeSequence.get(timeSequence.size() - 1);
- var pulseObject = problem.getPulse();
+ var pulseObject = problem.getPulse();
pulseObject.setPulseWidth(derive(PULSE_WIDTH, pulseWidth));
}
@@ -98,11 +106,11 @@ private void setPulseWidthOf(Problem problem) {
private void doInterpolation(double timeFactor) {
var interpolator = new AkimaSplineInterpolator();
- var timeList = pulseData.getTimeSequence().stream().mapToDouble(d -> d / timeFactor).toArray();
- var powerList = pulseData.getSignalData();
+ var timeList = pulseData.getTimeSequence().stream().mapToDouble(d -> d / timeFactor).toArray();
+ var powerList = pulseData.getSignalData();
this.setPulseWidth(timeList[timeList.length - 1]);
-
+
interpolation = interpolator.interpolate(timeList,
powerList.stream().mapToDouble(d -> d).toArray());
}
@@ -135,7 +143,7 @@ public NumericPulseData getData() {
public void setData(NumericPulseData pulseData) {
this.pulseData = pulseData;
-
+
}
public UnivariateFunction getInterpolation() {
@@ -147,4 +155,22 @@ public int getRequiredDiscretisation() {
return MIN_POINTS;
}
+ /*
+ Serialization
+ */
+ private void writeObject(ObjectOutputStream oos)
+ throws IOException {
+ // default serialization
+ oos.defaultWriteObject();
+ // write the object
+ FunctionSerializer.writeSplineFunction((PolynomialSplineFunction) interpolation, oos);
+ }
+
+ private void readObject(ObjectInputStream ois)
+ throws ClassNotFoundException, IOException {
+ // default deserialization
+ ois.defaultReadObject();
+ this.interpolation = FunctionSerializer.readSplineFunction(ois);
+ }
+
}
diff --git a/src/main/java/pulse/problem/laser/NumericPulseData.java b/src/main/java/pulse/problem/laser/NumericPulseData.java
index 5a53fd0..7bbfeee 100644
--- a/src/main/java/pulse/problem/laser/NumericPulseData.java
+++ b/src/main/java/pulse/problem/laser/NumericPulseData.java
@@ -14,6 +14,7 @@
*/
public class NumericPulseData extends AbstractData implements DiscreteInput {
+ private static final long serialVersionUID = 8142129124831241206L;
private final int externalID;
/**
@@ -54,7 +55,7 @@ public void addPoint(double time, double power) {
public int getExternalID() {
return externalID;
}
-
+
public double pulseWidth() {
return super.timeLimit();
}
@@ -73,5 +74,5 @@ public List getY() {
public IndexRange getIndexRange() {
return new IndexRange(this.getTimeSequence(), Range.UNLIMITED);
}
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/problem/laser/PulseTemporalShape.java b/src/main/java/pulse/problem/laser/PulseTemporalShape.java
index 6c3814e..9a74c09 100644
--- a/src/main/java/pulse/problem/laser/PulseTemporalShape.java
+++ b/src/main/java/pulse/problem/laser/PulseTemporalShape.java
@@ -1,6 +1,5 @@
package pulse.problem.laser;
-
import pulse.input.ExperimentalData;
import pulse.util.PropertyHolder;
import pulse.util.Reflexive;
@@ -23,7 +22,7 @@ public PulseTemporalShape() {
public PulseTemporalShape(PulseTemporalShape another) {
this.width = another.width;
}
-
+
/**
* This evaluates the dimensionless, discretised pulse function on a
* {@code grid} needed to evaluate the heat source in the difference scheme.
@@ -64,7 +63,7 @@ public double getPulseWidth() {
public void setPulseWidth(double width) {
this.width = width;
}
-
+
public abstract int getRequiredDiscretisation();
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/problem/laser/RectangularPulse.java b/src/main/java/pulse/problem/laser/RectangularPulse.java
index 2ba6b9d..7bc5dfb 100644
--- a/src/main/java/pulse/problem/laser/RectangularPulse.java
+++ b/src/main/java/pulse/problem/laser/RectangularPulse.java
@@ -14,11 +14,12 @@
*/
public class RectangularPulse extends PulseTemporalShape {
- private final static int MIN_POINTS = 4;
-
+ private static final long serialVersionUID = 8207478409316696745L;
+ private final static int MIN_POINTS = 2;
+
/**
* @param time the time measured from the start of the laser pulse.
- * @return
+ * @return
*/
@Override
public double evaluateAt(double time) {
@@ -35,7 +36,7 @@ public void set(NumericPropertyKeyword type, NumericProperty property) {
public PulseTemporalShape copy() {
return new RectangularPulse();
}
-
+
@Override
public int getRequiredDiscretisation() {
return MIN_POINTS;
diff --git a/src/main/java/pulse/problem/laser/TrapezoidalPulse.java b/src/main/java/pulse/problem/laser/TrapezoidalPulse.java
index c305b81..908e2cf 100644
--- a/src/main/java/pulse/problem/laser/TrapezoidalPulse.java
+++ b/src/main/java/pulse/problem/laser/TrapezoidalPulse.java
@@ -18,12 +18,13 @@
*/
public class TrapezoidalPulse extends PulseTemporalShape {
+ private static final long serialVersionUID = 2089809680713225034L;
private double rise;
private double fall;
private double h;
- private final static int MIN_POINTS = 6;
-
+ private final static int MIN_POINTS = 8;
+
/**
* Constructs a trapezoidal pulse using a default segmentation principle.
* The reader is referred to the {@code .xml} file containing the default
@@ -42,7 +43,7 @@ public TrapezoidalPulse(TrapezoidalPulse another) {
this.fall = another.fall;
this.h = another.h;
}
-
+
/**
* Calculates the height of the trapezium which under current segmentation
* will yield an area of unity.
@@ -125,10 +126,10 @@ public void set(NumericPropertyKeyword type, NumericProperty property) {
public PulseTemporalShape copy() {
return new TrapezoidalPulse(this);
}
-
+
@Override
public int getRequiredDiscretisation() {
return MIN_POINTS;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/problem/schemes/ADIScheme.java b/src/main/java/pulse/problem/schemes/ADIScheme.java
index db0c7e4..b20b34d 100644
--- a/src/main/java/pulse/problem/schemes/ADIScheme.java
+++ b/src/main/java/pulse/problem/schemes/ADIScheme.java
@@ -14,6 +14,11 @@
*/
public abstract class ADIScheme extends DifferenceScheme {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4772650159522354367L;
+
/**
* Creates a new {@code ADIScheme} with default values of grid density and
* time factor.
@@ -56,13 +61,14 @@ public ADIScheme(NumericProperty N, NumericProperty timeFactor, NumericProperty
public String toString() {
return getString("ADIScheme.4");
}
-
+
/**
- * Contains only an empty statement, as the pulse needs to be calculated not only
- * for the time step {@code m} but also accounting for the radial coordinate
+ * Contains only an empty statement, as the pulse needs to be calculated not
+ * only for the time step {@code m} but also accounting for the radial
+ * coordinate
+ *
* @param m thte time step
*/
-
@Override
public void prepareStep(int m) {
//do nothing
diff --git a/src/main/java/pulse/problem/schemes/BlockMatrixAlgorithm.java b/src/main/java/pulse/problem/schemes/BlockMatrixAlgorithm.java
index acaa5cd..450db9d 100644
--- a/src/main/java/pulse/problem/schemes/BlockMatrixAlgorithm.java
+++ b/src/main/java/pulse/problem/schemes/BlockMatrixAlgorithm.java
@@ -11,6 +11,7 @@
*/
public class BlockMatrixAlgorithm extends TridiagonalMatrixAlgorithm {
+ private static final long serialVersionUID = -6553638438386098008L;
private final double[] gamma;
private final double[] p;
private final double[] q;
@@ -36,7 +37,7 @@ public void evaluateBeta(final double[] U) {
super.evaluateBeta(U);
var alpha = getAlpha();
var beta = getBeta();
-
+
final int N = getGridPoints();
p[N - 1] = beta[N];
@@ -51,7 +52,7 @@ public void evaluateBeta(final double[] U) {
@Override
public void evaluateBeta(final double[] U, final int start, final int endExclusive) {
var alpha = getAlpha();
-
+
final double h = this.getGridStep();
final double HX2_TAU = h * h / this.getTimeStep();
diff --git a/src/main/java/pulse/problem/schemes/CoupledImplicitScheme.java b/src/main/java/pulse/problem/schemes/CoupledImplicitScheme.java
index f4577d9..17976a2 100644
--- a/src/main/java/pulse/problem/schemes/CoupledImplicitScheme.java
+++ b/src/main/java/pulse/problem/schemes/CoupledImplicitScheme.java
@@ -14,6 +14,7 @@
public abstract class CoupledImplicitScheme extends ImplicitScheme {
+ private static final long serialVersionUID = 1974655675470727643L;
private RadiativeTransferCoupling coupling;
private RTECalculationStatus calculationStatus;
private boolean autoUpdateFluxes = true; //should be false for nonlinear solvers
@@ -29,11 +30,11 @@ public CoupledImplicitScheme(NumericProperty N, NumericProperty timeFactor, Nume
this(N, timeFactor);
setTimeLimit(timeLimit);
}
-
+
@Override
public void finaliseStep() throws SolverException {
super.finaliseStep();
- if(autoUpdateFluxes) {
+ if (autoUpdateFluxes) {
var rte = this.getCoupling().getRadiativeTransferEquation();
setCalculationStatus(rte.compute(getCurrentSolution()));
}
@@ -59,11 +60,11 @@ public final RTECalculationStatus getCalculationStatus() {
public final void setCalculationStatus(RTECalculationStatus calculationStatus) throws SolverException {
this.calculationStatus = calculationStatus;
if (calculationStatus != RTECalculationStatus.NORMAL) {
- throw new SolverException(calculationStatus.toString(),
+ throw new SolverException(calculationStatus.toString(),
RTE_SOLVER_ERROR);
}
}
-
+
public final RadiativeTransferCoupling getCoupling() {
return coupling;
}
@@ -72,18 +73,18 @@ public final void setCoupling(RadiativeTransferCoupling coupling) {
this.coupling = coupling;
this.coupling.setParent(this);
}
-
+
public final boolean isAutoUpdateFluxes() {
return this.autoUpdateFluxes;
}
-
+
public final void setAutoUpdateFluxes(boolean auto) {
this.autoUpdateFluxes = auto;
}
-
+
@Override
public Class extends Problem>[] domain() {
return new Class[]{ParticipatingMedium.class};
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/problem/schemes/DifferenceScheme.java b/src/main/java/pulse/problem/schemes/DifferenceScheme.java
index 59c9220..64de3f8 100644
--- a/src/main/java/pulse/problem/schemes/DifferenceScheme.java
+++ b/src/main/java/pulse/problem/schemes/DifferenceScheme.java
@@ -1,5 +1,6 @@
package pulse.problem.schemes;
+import java.util.Objects;
import static pulse.properties.NumericProperties.def;
import static pulse.properties.NumericProperties.derive;
import static pulse.properties.NumericProperty.requireType;
@@ -28,7 +29,7 @@
*/
public abstract class DifferenceScheme extends PropertyHolder implements Reflexive {
- private DiscretePulse discretePulse;
+ private transient DiscretePulse discretePulse;
private Grid grid;
private double timeLimit;
@@ -91,8 +92,8 @@ public void copyFrom(DifferenceScheme df) {
protected void prepare(Problem problem) throws SolverException {
if (discretePulse == null) {
discretePulse = problem.discretePulseOn(grid);
- }
- discretePulse.recalculate();
+ }
+ discretePulse.init();
clearArrays();
}
@@ -113,14 +114,14 @@ public void runTimeSequence(Problem problem, final double offset, final double e
int numPoints = (int) curve.getNumPoints().getValue();
- final double startTime = (double) curve.getTimeShift().getValue();
- final double timeSegment = (endTime - startTime - offset) / problem.getProperties().timeFactor();
+ final double startTime = (double) curve.getTimeShift().getValue();
+ final double timeSegment = (endTime - startTime - offset) / problem.getProperties().characteristicTime();
double tau = grid.getTimeStep();
final double dt = timeSegment / (numPoints - 1);
- timeInterval = Math.max( (int) (dt / tau), 1);
+ timeInterval = Math.max((int) (dt / tau), 1);
- double wFactor = timeInterval * tau * problem.getProperties().timeFactor();
+ double wFactor = timeInterval * tau * problem.getProperties().characteristicTime();
// First point (index = 0) is always (0.0, 0.0)
curve.addPoint(0.0, 0.0);
@@ -296,16 +297,16 @@ public void set(NumericPropertyKeyword type, NumericProperty property) {
setTimeLimit(property);
}
}
-
+
public abstract double signal();
-
+
public abstract void clearArrays();
public abstract void timeStep(int m) throws SolverException;
public abstract void finaliseStep() throws SolverException;
- /**
+ /**
* Retrieves all problem statements that can be solved with this
* implementation of the difference scheme.
*
@@ -321,5 +322,5 @@ public void set(NumericPropertyKeyword type, NumericProperty property) {
* @return an exact copy of this {@code DifferenceScheme}.
*/
public abstract DifferenceScheme copy();
-
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/pulse/problem/schemes/DistributedDetection.java b/src/main/java/pulse/problem/schemes/DistributedDetection.java
index 88831e4..3d17946 100644
--- a/src/main/java/pulse/problem/schemes/DistributedDetection.java
+++ b/src/main/java/pulse/problem/schemes/DistributedDetection.java
@@ -1,5 +1,6 @@
package pulse.problem.schemes;
+import java.io.Serializable;
import java.util.stream.IntStream;
import pulse.problem.statements.model.AbsorptionModel;
@@ -11,7 +12,9 @@
* {@code AbsorptionModel}.
*
*/
-public class DistributedDetection {
+public class DistributedDetection implements Serializable {
+
+ private static final long serialVersionUID = 3587781877001360511L;
/**
* Calculates the effective signal registered by the detector, which takes
@@ -35,4 +38,4 @@ public static double evaluateSignal(final AbsorptionModel absorption, final Grid
return signal * 0.5 * hx;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pulse/problem/schemes/ExplicitScheme.java b/src/main/java/pulse/problem/schemes/ExplicitScheme.java
index 70a47ba..e4b858c 100644
--- a/src/main/java/pulse/problem/schemes/ExplicitScheme.java
+++ b/src/main/java/pulse/problem/schemes/ExplicitScheme.java
@@ -19,6 +19,11 @@
*/
public abstract class ExplicitScheme extends OneDimensionalScheme {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3025913683505686334L;
+
/**
* Constructs a default explicit scheme using the default values of
* {@code GRID_DENSITY} and {@code TAU_FACTOR}.
diff --git a/src/main/java/pulse/problem/schemes/FixedPointIterations.java b/src/main/java/pulse/problem/schemes/FixedPointIterations.java
index 1c359a4..dbf5992 100644
--- a/src/main/java/pulse/problem/schemes/FixedPointIterations.java
+++ b/src/main/java/pulse/problem/schemes/FixedPointIterations.java
@@ -1,6 +1,8 @@
package pulse.problem.schemes;
import static java.lang.Math.abs;
+
+import java.io.Serializable;
import java.util.Arrays;
import pulse.problem.schemes.solvers.SolverException;
import static pulse.problem.schemes.solvers.SolverException.SolverExceptionType.FINITE_DIFFERENCE_ERROR;
@@ -10,7 +12,7 @@
* page
*
*/
-public interface FixedPointIterations {
+public interface FixedPointIterations extends Serializable {
/**
* Performs iterations until the convergence criterion is satisfied.The
@@ -30,9 +32,9 @@ public default void doIterations(double[] V, final double error, final int m) th
final int N = V.length - 1;
- for (double V_0 = error + 1, V_N = error + 1;
- abs(V[0] - V_0)/abs(V[0] + V_0 + 1e-16) > error
- || abs(V[N] - V_N)/abs(V[N] + V_N + 1e-16) > error; finaliseIteration(V)) {
+ for (double V_0 = error + 1, V_N = error + 1;
+ abs(V[0] - V_0) / abs(V[0] + V_0 + 1e-16) > error
+ || abs(V[N] - V_N) / abs(V[N] + V_N + 1e-16) > error; finaliseIteration(V)) {
V_N = V[N];
V_0 = V[0];
diff --git a/src/main/java/pulse/problem/schemes/Grid.java b/src/main/java/pulse/problem/schemes/Grid.java
index f68467b..d8a0b33 100644
--- a/src/main/java/pulse/problem/schemes/Grid.java
+++ b/src/main/java/pulse/problem/schemes/Grid.java
@@ -2,7 +2,6 @@
import static java.lang.Math.pow;
import static java.lang.Math.rint;
-import static java.lang.String.format;
import static pulse.properties.NumericProperties.derive;
import static pulse.properties.NumericProperty.requireType;
import static pulse.properties.NumericPropertyKeyword.GRID_DENSITY;
@@ -10,7 +9,6 @@
import java.util.Set;
-import pulse.problem.laser.DiscretePulse;
import pulse.properties.NumericProperty;
import pulse.properties.NumericPropertyKeyword;
import pulse.util.PropertyHolder;
@@ -27,6 +25,7 @@
*/
public class Grid extends PropertyHolder {
+ private static final long serialVersionUID = -4293010190416468656L;
private double hx;
private double tau;
private double tauFactor;
@@ -46,7 +45,7 @@ public Grid(NumericProperty gridDensity, NumericProperty timeFactor) {
this.N = (int) gridDensity.getValue();
this.tauFactor = (double) timeFactor.getValue();
hx = 1. / N;
- setTimeStep(tauFactor * pow(hx, 2));
+ setTimeStep(tauFactor * pow(hx, 2));
}
protected Grid() {
@@ -63,37 +62,6 @@ public Grid copy() {
return new Grid(getGridDensity(), getTimeFactor());
}
- /**
- * Optimises the {@code Grid} parameters so that the timestep is
- * sufficiently small to enable accurate pulse correction.
- *
- * This can change the {@code tauFactor} and {@code tau} variables in the
- * {@code Grid} object if {@code discretePulseWidth/(M - 1) < grid.tau},
- * where M is the required number of pulse calculations.
- *
- *
- * @param pulse the discrete pulse representation
- * @see PulseTemporalShape.getRequiredDiscretisation()
- */
- public final void adjustTimeStep(DiscretePulse pulse) {
- double timeFactor = pulse.getConversionFactor();
-
- final int reqPoints = pulse.getPulse().getPulseShape().getRequiredDiscretisation();
-
- double pNominalWidth = (double) pulse.getPulse().getPulseWidth().getValue();
- double pResolvedWidth = pulse.resolvedPulseWidth();
- double pWidth = pNominalWidth < pResolvedWidth ? pResolvedWidth : pNominalWidth;
-
- double newTau = pWidth / timeFactor / (reqPoints > 1 ? reqPoints - 1 : 1);
- double newTauFactor = newTau / (hx * hx);
-
- final double EPS = 1E-10;
- if (newTauFactor < tauFactor - EPS) {
- setTimeFactor(derive(TAU_FACTOR, newTauFactor));
- }
-
- }
-
/**
* The listed properties include {@code GRID_DENSITY} and
* {@code TAU_FACTOR}.
@@ -151,7 +119,7 @@ public final double getTimeStep() {
protected final void setTimeStep(double tau) {
this.tau = tau;
-
+
}
/**
@@ -196,7 +164,7 @@ public void setGridDensity(NumericProperty gridDensity) {
requireType(gridDensity, GRID_DENSITY);
this.N = (int) gridDensity.getValue();
hx = 1. / N;
- setTimeStep(tauFactor * pow(hx, 2));
+ setTimeStep(tauFactor * pow(hx, 2));
firePropertyChanged(this, gridDensity);
}
@@ -209,7 +177,7 @@ public void setGridDensity(NumericProperty gridDensity) {
public void setTimeFactor(NumericProperty timeFactor) {
requireType(timeFactor, TAU_FACTOR);
this.tauFactor = (double) timeFactor.getValue();
- setTimeStep(tauFactor * pow(hx, 2));
+ setTimeStep(tauFactor * pow(hx, 2));
firePropertyChanged(this, timeFactor);
}
@@ -223,7 +191,7 @@ public void setTimeFactor(NumericProperty timeFactor) {
* @return a double representing the time on the finite grid
*/
public final double gridTime(double time, double dimensionFactor) {
- return rint((time / dimensionFactor) / tau) * tau;
+ return ((int) (time / dimensionFactor / tau)) * tau;
}
/**
@@ -241,15 +209,9 @@ public final double gridAxialDistance(double distance, double lengthFactor) {
@Override
public String toString() {
- var sb = new StringBuilder();
- sb.append("").
- append(getClass().getSimpleName())
- .append(":