diff --git a/pom.xml b/pom.xml
index a71c065..88351e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
kotik-coder
PULsE
- 1.93
+ 1.93F
PULsE
Processing Unit for Laser flash Experiments
diff --git a/src/main/java/pulse/AbstractData.java b/src/main/java/pulse/AbstractData.java
index f1f5ab8..2f58d47 100644
--- a/src/main/java/pulse/AbstractData.java
+++ b/src/main/java/pulse/AbstractData.java
@@ -32,8 +32,8 @@ public abstract class AbstractData extends PropertyHolder {
private int count;
- private List time;
- private List signal;
+ protected List time;
+ protected List signal;
private String name;
diff --git a/src/main/java/pulse/input/ExperimentalData.java b/src/main/java/pulse/input/ExperimentalData.java
index 3b2e5bd..bbbb2e6 100644
--- a/src/main/java/pulse/input/ExperimentalData.java
+++ b/src/main/java/pulse/input/ExperimentalData.java
@@ -419,7 +419,7 @@ private void doSetRange() {
}
/**
- * Retrieves the
+ * Retrieves the time limit.
*
* @see pulse.problem.schemes.DifferenceScheme
* @return a double, equal to the last element of the {@code time List}.
@@ -427,6 +427,6 @@ private void doSetRange() {
@Override
public double timeLimit() {
return timeAt(indexRange.getUpperBound());
- }
+ }
}
diff --git a/src/main/java/pulse/io/export/ExportManager.java b/src/main/java/pulse/io/export/ExportManager.java
index ec8c81a..2064c50 100644
--- a/src/main/java/pulse/io/export/ExportManager.java
+++ b/src/main/java/pulse/io/export/ExportManager.java
@@ -21,6 +21,9 @@
*
*/
public class ExportManager {
+
+ //current working dir
+ private static File cwd = null;
private ExportManager() {
// intentionally blank
@@ -85,7 +88,7 @@ public static Exporter findExporter(Class target)
public static void askToExport(T target, JFrame parentWindow, String fileTypeLabel) {
var exporter = findExporter(target);
if (exporter != null) {
- exporter.askToExport(target, parentWindow, fileTypeLabel);
+ cwd = exporter.askToExport(target, parentWindow, fileTypeLabel, cwd);
} else {
throw new IllegalArgumentException("No exporter for " + target.getClass().getSimpleName());
}
diff --git a/src/main/java/pulse/io/export/Exporter.java b/src/main/java/pulse/io/export/Exporter.java
index 71cb1ba..d2d35c0 100644
--- a/src/main/java/pulse/io/export/Exporter.java
+++ b/src/main/java/pulse/io/export/Exporter.java
@@ -89,12 +89,11 @@ public default void export(T target, File directory, Extension extension) {
* @param target the exported target
* @param parentWindow the parent frame.
* @param fileTypeLabel the label describing the specific type of files that
- * will be saved.
+ * @param directory the default directory of the file will be saved.
+ * @return the directory where files were exported
*/
- public default void askToExport(T target, JFrame parentWindow, String fileTypeLabel) {
- var fileChooser = new JFileChooser();
- var workingDirectory = new File(System.getProperty("user.home"));
- fileChooser.setCurrentDirectory(workingDirectory);
+ public default File askToExport(T target, JFrame parentWindow, String fileTypeLabel, File directory) {
+ var fileChooser = new JFileChooser(directory);
fileChooser.setMultiSelectionEnabled(true);
FileNameExtensionFilter choosable = null;
@@ -113,29 +112,35 @@ public default void askToExport(T target, JFrame parentWindow, String fileTypeLa
var file = fileChooser.getSelectedFile();
var path = file.getPath();
- if (!(fileChooser.getFileFilter() instanceof FileNameExtensionFilter)) {
- return;
- }
+ directory = file.isDirectory() ? file : file.getParentFile();
- var currentFilter = (FileNameExtensionFilter) fileChooser.getFileFilter();
- var ext = currentFilter.getExtensions()[0];
+ if ((fileChooser.getFileFilter() instanceof FileNameExtensionFilter)) {
+
+ var currentFilter = (FileNameExtensionFilter) fileChooser.getFileFilter();
+ var ext = currentFilter.getExtensions()[0];
+
+ if (!path.contains(".")) {
+ file = new File(path + "." + ext);
+ } else {
+ file = new File(path.substring(0, path.indexOf(".") + 1) + ext);
+ }
+
+ try {
+ var fos = new FileOutputStream(file);
+ printToStream(target, fos, Extension.valueOf(ext.toUpperCase()));
+ fos.close();
+ } catch (IOException e) {
+ System.err.println("An exception has been encountered while writing the contents of "
+ + target.getClass().getSimpleName() + " to " + file);
+ e.printStackTrace();
+ }
- if (!path.contains(".")) {
- file = new File(path + "." + ext);
- }
- else
- file = new File(path.substring(0, path.indexOf(".") + 1) + ext);
-
- try {
- var fos = new FileOutputStream(file);
- printToStream(target, fos, Extension.valueOf(ext.toUpperCase()));
- fos.close();
- } catch (IOException e) {
- System.err.println("An exception has been encountered while writing the contents of "
- + target.getClass().getSimpleName() + " to " + file);
- e.printStackTrace();
}
+
}
+
+ return directory;
+
}
/**
diff --git a/src/main/java/pulse/io/readers/AbstractReader.java b/src/main/java/pulse/io/readers/AbstractReader.java
index a557fcb..d98036e 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 d3320e3..a50d4e7 100644
--- a/src/main/java/pulse/io/readers/NetzschCSVReader.java
+++ b/src/main/java/pulse/io/readers/NetzschCSVReader.java
@@ -7,10 +7,16 @@
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import pulse.AbstractData;
import pulse.input.ExperimentalData;
@@ -44,10 +50,16 @@ public class NetzschCSVReader implements CurveReader {
/**
* Note comma is included as a delimiter character here.
*/
- public final static String delims = "[#();,/°Cx%^]+";
-
+ private final static String ENGLISH_DELIMS = "[#(),/°Cx%^]+";
+ private final static String GERMAN_DELIMS = "[#();/°Cx%^]+";
+
+ private static String delims = ENGLISH_DELIMS;
+
+ //default number format (British format)
+ private static Locale locale = Locale.ENGLISH;
+
private NetzschCSVReader() {
- // intentionally blank
+ //intentionally blank
}
/**
@@ -87,19 +99,25 @@ public List read(File file) throws IOException {
Objects.requireNonNull(file, Messages.getString("DATReader.1"));
ExperimentalData curve = new ExperimentalData();
+
+ //gets the number format for this locale
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
int shotId = determineShotID(reader, file);
+
+ var format = DecimalFormat.getInstance(locale);
+ format.setGroupingUsed(false);
var tempTokens = findLineByLabel(reader, THICKNESS, delims).split(delims);
- final double thickness = Double.parseDouble(tempTokens[tempTokens.length - 1]) * TO_METRES;
+
+ final double thickness = format.parse(tempTokens[tempTokens.length - 1]).doubleValue() * TO_METRES;
tempTokens = findLineByLabel(reader, DIAMETER, delims).split(delims);
- final double diameter = Double.parseDouble(tempTokens[tempTokens.length - 1]) * TO_METRES;
+ final double diameter = format.parse(tempTokens[tempTokens.length - 1]).doubleValue() * TO_METRES;
tempTokens = findLineByLabel(reader, SAMPLE_TEMPERATURE, delims).split(delims);
- final double sampleTemperature = Double.parseDouble(tempTokens[tempTokens.length - 1]) + TO_KELVIN;
+ final double sampleTemperature = format.parse(tempTokens[tempTokens.length - 1]).doubleValue() + TO_KELVIN;
/*
* Finds the detector keyword.
@@ -122,32 +140,52 @@ public List read(File file) throws IOException {
curve.setMetadata(met);
curve.setRange(new Range(curve.getTimeSequence()));
+ return new ArrayList<>(Arrays.asList(curve));
+ } catch (ParseException ex) {
+ Logger.getLogger(NetzschCSVReader.class.getName()).log(Level.SEVERE, null, ex);
}
- return new ArrayList<>(Arrays.asList(curve));
+ return null;
}
- protected static void populate(AbstractData data, BufferedReader reader) throws IOException {
+ protected static void populate(AbstractData data, BufferedReader reader) throws IOException, ParseException {
double time;
double power;
String[] tokens;
+ var format = DecimalFormat.getInstance(locale);
+ format.setGroupingUsed(false);
for (String line = reader.readLine(); line != null && !line.trim().isEmpty(); line = reader.readLine()) {
tokens = line.split(delims);
- time = Double.parseDouble(tokens[0]) * NetzschCSVReader.TO_SECONDS;
- power = Double.parseDouble(tokens[1]);
+ time = format.parse(tokens[0]).doubleValue() * NetzschCSVReader.TO_SECONDS;
+ power = format.parse(tokens[1]).doubleValue();
data.addPoint(time, power);
}
}
protected static int determineShotID(BufferedReader reader, File file) throws IOException {
- String[] shotID = reader.readLine().split(delims);
+ String shotIDLine = reader.readLine();
+ String[] shotID = shotIDLine.split(delims);
int shotId = -1;
+
+ if(shotID.length < 3) {
+
+ if(locale == Locale.ENGLISH) {
+ delims = GERMAN_DELIMS;
+ locale = Locale.GERMAN;
+ }
+ else {
+ delims = ENGLISH_DELIMS;
+ locale = Locale.ENGLISH;
+ }
+
+ shotID = shotIDLine.split(delims);
+ }
//check if first entry makes sense
if (!shotID[shotID.length - 2].equalsIgnoreCase(SHOT_DATA)) {
@@ -160,19 +198,7 @@ protected static int determineShotID(BufferedReader reader, File file) throws IO
return shotId;
}
-
- /*
- private double parseDoubleWithComma(String s) {
- var format = NumberFormat.getInstance(Locale.GERMANY);
- try {
- return format.parse(s).doubleValue();
- } catch (ParseException e) {
- System.out.println("Couldn't parse double from: " + s);
- e.printStackTrace();
- }
- return Double.NaN;
- }
- */
+
protected static String findLineByLabel(BufferedReader reader, String label, String delims) throws IOException {
String line = "";
@@ -195,7 +221,6 @@ protected static String findLineByLabel(BufferedReader reader, String label, Str
return line;
}
-
/**
* As this class uses the singleton pattern, only one instance is created
* using an empty no-argument constructor.
@@ -205,5 +230,14 @@ protected static String findLineByLabel(BufferedReader reader, String label, Str
public static CurveReader getInstance() {
return instance;
}
-
+
+ /**
+ * Get the standard delimiter chars.
+ * @return delims
+ */
+
+ public static String getDelims() {
+ return delims;
+ }
+
}
diff --git a/src/main/java/pulse/io/readers/NetzschPulseCSVReader.java b/src/main/java/pulse/io/readers/NetzschPulseCSVReader.java
index 2b67fe4..4ba3303 100644
--- a/src/main/java/pulse/io/readers/NetzschPulseCSVReader.java
+++ b/src/main/java/pulse/io/readers/NetzschPulseCSVReader.java
@@ -4,7 +4,10 @@
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.text.ParseException;
import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import pulse.problem.laser.NumericPulseData;
import pulse.ui.Messages;
@@ -37,10 +40,12 @@ public String getSupportedExtension() {
/**
* This performs a basic check, finding the shot ID, which is then passed to
- * a new {@code NumericPulseData} object. The latter is populated using the
- * time-power sequence stored in this file. If the {@value PULSE} keyword is
+ * a new {@code NumericPulseData} object.The latter is populated using the
+ * time-power sequence stored in this file.If the {@value PULSE} keyword is
* not found, the method will display an error.
*
+ * @param file
+ * @throws java.io.IOException
* @see pulse.io.readers.NetzschCSVReader.read()
* @return a new {@code NumericPulseData} object encapsulating the contents
* of {@code file}
@@ -49,14 +54,14 @@ public String getSupportedExtension() {
public NumericPulseData read(File file) throws IOException {
Objects.requireNonNull(file, Messages.getString("DATReader.1"));
- NumericPulseData data;
+ NumericPulseData data = null;
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
int shotId = NetzschCSVReader.determineShotID(reader, file);
data = new NumericPulseData(shotId);
- var pulseLabel = NetzschCSVReader.findLineByLabel(reader, PULSE, NetzschCSVReader.delims);
+ var pulseLabel = NetzschCSVReader.findLineByLabel(reader, PULSE, NetzschCSVReader.getDelims());
if (pulseLabel == null) {
System.err.println("Skipping " + file.getName());
@@ -66,24 +71,14 @@ public NumericPulseData read(File file) throws IOException {
reader.readLine();
NetzschCSVReader.populate(data, reader);
+ } catch (ParseException ex) {
+ Logger.getLogger(NetzschPulseCSVReader.class.getName()).log(Level.SEVERE, null, ex);
}
return data;
}
- /*
- private double parseDoubleWithComma(String s) {
- var format = NumberFormat.getInstance(Locale.GERMANY);
- try {
- return format.parse(s).doubleValue();
- } catch (ParseException e) {
- System.out.println("Couldn't parse double from: " + s);
- e.printStackTrace();
- }
- return Double.NaN;
- }
- */
/**
* As this class uses the singleton pattern, only one instance is created
* using an empty no-argument constructor.
diff --git a/src/main/java/pulse/io/readers/ReaderManager.java b/src/main/java/pulse/io/readers/ReaderManager.java
index 83c72ee..97bc4a2 100644
--- a/src/main/java/pulse/io/readers/ReaderManager.java
+++ b/src/main/java/pulse/io/readers/ReaderManager.java
@@ -8,6 +8,12 @@
import java.util.Objects;
import java.util.Scanner;
import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
@@ -207,13 +213,32 @@ public static Set readDirectory(List> readers, File dir
throw new IllegalArgumentException("Not a directory: " + directory);
}
- var list = new HashSet();
-
+ var es = Executors.newSingleThreadExecutor();
+
+ var callableList = new ArrayList>();
+
for (File f : directory.listFiles()) {
- list.add(read(readers, f));
+ Callable callable = () -> read(readers, f);
+ callableList.add(callable);
+ }
+
+ Set result = new HashSet<>();
+
+ try {
+ List> futures = es.invokeAll(callableList);
+
+ for(Future f : futures)
+ result.add(f.get());
+
+ } catch (InterruptedException ex) {
+ 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,
+ "Error executing read operation using concurrency", ex);
}
- return list;
+ return result;
}
/**
diff --git a/src/main/java/pulse/problem/statements/Problem.java b/src/main/java/pulse/problem/statements/Problem.java
index acde58f..4b47ebd 100644
--- a/src/main/java/pulse/problem/statements/Problem.java
+++ b/src/main/java/pulse/problem/statements/Problem.java
@@ -16,6 +16,7 @@
import pulse.math.Segment;
import pulse.math.transforms.InvLenSqTransform;
import pulse.math.transforms.StandardTransformations;
+import pulse.math.transforms.StickTransform;
import pulse.problem.laser.DiscretePulse;
import pulse.problem.schemes.DifferenceScheme;
import pulse.problem.schemes.Grid;
@@ -228,6 +229,13 @@ public void optimisationVector(ParameterVector output, List flags) {
var key = output.getIndex(i);
switch (key) {
+ case THICKNESS:
+ final double l = (double) properties.getSampleThickness().getValue();
+ var bounds = Segment.boundsFrom(THICKNESS);
+ output.setParameterBounds(i, bounds);
+ output.setTransform(i, new StickTransform(bounds));
+ output.set(i, l);
+ break;
case DIFFUSIVITY:
final double a = (double) properties.getDiffusivity().getValue();
output.setTransform(i, new InvLenSqTransform(properties));
@@ -284,6 +292,9 @@ public void assign(ParameterVector params) throws SolverException {
var key = params.getIndex(i);
switch (key) {
+ case THICKNESS:
+ properties.setSampleThickness(derive(THICKNESS, params.inverseTransform(i) ));
+ break;
case DIFFUSIVITY:
properties.setDiffusivity(derive(DIFFUSIVITY, params.inverseTransform(i)));
break;
diff --git a/src/main/java/pulse/properties/NumericPropertyFormatter.java b/src/main/java/pulse/properties/NumericPropertyFormatter.java
index 1f98dc4..f3c83cf 100644
--- a/src/main/java/pulse/properties/NumericPropertyFormatter.java
+++ b/src/main/java/pulse/properties/NumericPropertyFormatter.java
@@ -74,7 +74,9 @@ public NumberFormat numberFormat(NumericProperty p) {
: (double) value;
double absAdjustedValue = Math.abs(adjustedValue);
- if ((absAdjustedValue > UPPER_LIMIT) || (absAdjustedValue < LOWER_LIMIT && absAdjustedValue > ZERO)) {
+ if (addHtmlTags &&
+ ( (absAdjustedValue > UPPER_LIMIT)
+ || (absAdjustedValue < LOWER_LIMIT && absAdjustedValue > ZERO)) ) {
//format with scientific notations
f = new ScientificFormat(p.getDimensionFactor(), p.getDimensionDelta());
} else {
diff --git a/src/main/java/pulse/properties/NumericPropertyKeyword.java b/src/main/java/pulse/properties/NumericPropertyKeyword.java
index 3a45116..65cdf46 100644
--- a/src/main/java/pulse/properties/NumericPropertyKeyword.java
+++ b/src/main/java/pulse/properties/NumericPropertyKeyword.java
@@ -210,23 +210,20 @@ public enum NumericPropertyKeyword {
*/
OPTICAL_THICKNESS,
/**
- * Time shift (pulse sync)
+ * Time shift (pulse sync).
*/
TIME_SHIFT,
/**
- * Statistical significance.
+ * Statistical significance for calculating the critical value.
*/
SIGNIFICANCE,
- /**
- * Statistical probability.
- */
- PROBABILITY,
+
/**
* Optimiser statistic (usually, RSS).
*/
OPTIMISER_STATISTIC,
/**
- * Model selection criterion (AIC, BIC, etc.)
+ * Model selection criterion (AIC, BIC, etc.).
*/
MODEL_CRITERION,
/**
diff --git a/src/main/java/pulse/search/direction/ActiveFlags.java b/src/main/java/pulse/search/direction/ActiveFlags.java
index 5edc827..e13af6e 100644
--- a/src/main/java/pulse/search/direction/ActiveFlags.java
+++ b/src/main/java/pulse/search/direction/ActiveFlags.java
@@ -74,8 +74,8 @@ public static List activeParameters(SearchTask t) {
//problem dependent
var allActiveParams = selectActiveAndListed(flags, c.getProblem());
//problem independent (lower/upper bound)
- var listed = selectActiveAndListed(flags, t.getExperimentalCurve() );
- allActiveParams.addAll( selectActiveAndListed(flags, t.getExperimentalCurve() ) );
+ var listed = selectActiveAndListed(flags, t.getExperimentalCurve().getRange() );
+ allActiveParams.addAll(listed);
return allActiveParams;
}
diff --git a/src/main/java/pulse/search/statistics/AndersonDarlingTest.java b/src/main/java/pulse/search/statistics/AndersonDarlingTest.java
index 60b970a..99ac004 100644
--- a/src/main/java/pulse/search/statistics/AndersonDarlingTest.java
+++ b/src/main/java/pulse/search/statistics/AndersonDarlingTest.java
@@ -1,7 +1,6 @@
package pulse.search.statistics;
import static pulse.properties.NumericProperties.derive;
-import static pulse.properties.NumericPropertyKeyword.PROBABILITY;
import static pulse.properties.NumericPropertyKeyword.TEST_STATISTIC;
import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation;
@@ -32,9 +31,9 @@ public boolean test(SearchTask task) {
var testResult = GofStat.andersonDarling(residuals, nd);
this.setStatistic(derive(TEST_STATISTIC, testResult[0]));
- setProbability(derive(PROBABILITY, testResult[1]));
-
- return significanceTest();
+
+ //compare the p-value and the significance
+ return testResult[1] > significance;
}
@Override
diff --git a/src/main/java/pulse/search/statistics/KSTest.java b/src/main/java/pulse/search/statistics/KSTest.java
index d350d7e..ceb4ceb 100644
--- a/src/main/java/pulse/search/statistics/KSTest.java
+++ b/src/main/java/pulse/search/statistics/KSTest.java
@@ -1,7 +1,6 @@
package pulse.search.statistics;
import static pulse.properties.NumericProperties.derive;
-import static pulse.properties.NumericPropertyKeyword.PROBABILITY;
import static pulse.properties.NumericPropertyKeyword.TEST_STATISTIC;
import org.apache.commons.math3.distribution.NormalDistribution;
@@ -23,8 +22,10 @@ public class KSTest extends NormalityTest {
@Override
public boolean test(SearchTask task) {
evaluate(task);
- setProbability(derive(PROBABILITY, TestUtils.kolmogorovSmirnovTest(nd, residuals)));
- return significanceTest();
+
+ this.setStatistic(derive(TEST_STATISTIC,
+ TestUtils.kolmogorovSmirnovStatistic(nd, residuals)));
+ return !TestUtils.kolmogorovSmirnovTest(nd, residuals, this.significance);
}
@Override
diff --git a/src/main/java/pulse/search/statistics/NormalityTest.java b/src/main/java/pulse/search/statistics/NormalityTest.java
index f7bb3ed..a8de54c 100644
--- a/src/main/java/pulse/search/statistics/NormalityTest.java
+++ b/src/main/java/pulse/search/statistics/NormalityTest.java
@@ -3,7 +3,6 @@
import static pulse.properties.NumericProperties.def;
import static pulse.properties.NumericProperties.derive;
import static pulse.properties.NumericProperty.requireType;
-import static pulse.properties.NumericPropertyKeyword.PROBABILITY;
import static pulse.properties.NumericPropertyKeyword.SIGNIFICANCE;
import static pulse.properties.NumericPropertyKeyword.TEST_STATISTIC;
@@ -17,28 +16,25 @@
*
* For the test to pass, the model residuals need be distributed according to a
* (0, σ) normal distribution, where σ is the variance of the model
- * residuals. As this is the pre-requisite for optimizers based on the ordinary
+ * residuals. As this is the pre-requisite for optimisers based on the ordinary
* least-square statistic, the normality test can also be used to estimate if a
* fit 'failed' or 'succeeded' in describing the data.
+ *
+ * The test consists in testing the relation ,
+ * where the critical value is determined based on a given level of significance.
*
*/
public abstract class NormalityTest extends ResidualStatistic {
private double statistic;
- private double probability;
- private static double significance = (double) def(SIGNIFICANCE).getValue();
+ protected static double significance = (double) def(SIGNIFICANCE).getValue();
private static String selectedTestDescriptor;
protected NormalityTest() {
- probability = (double) def(PROBABILITY).getValue();
statistic = (double) def(TEST_STATISTIC).getValue();
}
- public boolean significanceTest() {
- return probability > significance;
- }
-
public static NumericProperty getStatisticalSignifiance() {
return derive(SIGNIFICANCE, significance);
}
@@ -48,10 +44,6 @@ public static void setStatisticalSignificance(NumericProperty alpha) {
NormalityTest.significance = (double) alpha.getValue();
}
- public NumericProperty getProbability() {
- return derive(PROBABILITY, probability);
- }
-
public abstract boolean test(SearchTask task);
@Override
@@ -65,11 +57,6 @@ public void setStatistic(NumericProperty statistic) {
this.statistic = (double) statistic.getValue();
}
- public void setProbability(NumericProperty probability) {
- requireType(probability, PROBABILITY);
- this.probability = (double) probability.getValue();
- }
-
@Override
public void set(NumericPropertyKeyword type, NumericProperty property) {
if (type == TEST_STATISTIC) {
diff --git a/src/main/java/pulse/tasks/Calculation.java b/src/main/java/pulse/tasks/Calculation.java
index 797b9f8..60cdd4c 100644
--- a/src/main/java/pulse/tasks/Calculation.java
+++ b/src/main/java/pulse/tasks/Calculation.java
@@ -186,9 +186,10 @@ public boolean setStatus(Status status) {
switch(this.status) {
case DONE:
+ case IN_PROGRESS:
+ case FAILED:
case EXECUTION_ERROR:
case INCOMPLETE:
- case IN_PROGRESS:
//if the TaskManager attempts to run this calculation
if(status == Status.QUEUED)
return false;
diff --git a/src/main/java/pulse/ui/Launcher.java b/src/main/java/pulse/ui/Launcher.java
index 65e31e4..1ee2635 100644
--- a/src/main/java/pulse/ui/Launcher.java
+++ b/src/main/java/pulse/ui/Launcher.java
@@ -95,17 +95,7 @@ private void arrangeErrorOutput() {
try {
var dir = new File(decodedPath).getParent();
errorLog = new File(dir + File.separator + "ErrorLog_" + now() + ".log");
- setErr(new PrintStream(errorLog) {
-
- @Override
- public void println(String str) {
- super.println(str);
- JOptionPane.showMessageDialog(null, "An exception has occurred. "
- + "Please check the stored log!", "Exception", JOptionPane.ERROR_MESSAGE);
- }
-
- }
- );
+ setErr(new PrintStream(errorLog));
} catch (FileNotFoundException e) {
System.err.println("Unable to set up error stream");
e.printStackTrace();
diff --git a/src/main/java/pulse/ui/components/Chart.java b/src/main/java/pulse/ui/components/Chart.java
index a485806..2158758 100644
--- a/src/main/java/pulse/ui/components/Chart.java
+++ b/src/main/java/pulse/ui/components/Chart.java
@@ -94,7 +94,7 @@ public void mouseDragged(MouseEvent e) {
//process dragged events
Range range = instance.getSelectedTask()
.getExperimentalCurve().getRange();
- double value = xCoord(e);
+ double value = xCoord(e) / factor; //convert to seconds back from ms -- if needed
if (lowerMarker.getState() != MovableValueMarker.State.IDLE) {
if (range.boundLimits(false).contains(value)) {
@@ -124,8 +124,8 @@ public void mouseDragged(MouseEvent e) {
if (instance.getSelectedTask() == eventTask) {
//update marker values
var segment = eventTask.getExperimentalCurve().getRange().getSegment();
- lowerMarker.setValue(segment.getMinimum());
- upperMarker.setValue(segment.getMaximum());
+ lowerMarker.setValue(segment.getMinimum() * factor); //convert to ms -- if needed
+ upperMarker.setValue(segment.getMaximum() * factor); //convert to ms -- if needed
}
});
} //tasks that have been finihed
@@ -241,11 +241,11 @@ public void plot(SearchTask task, boolean extendedCurve) {
lowerMarker = new MovableValueMarker(segment.getMinimum() * factor);
upperMarker = new MovableValueMarker(segment.getMaximum() * factor);
- final double margin = segment.getMaximum() / 20.0;
+ final double margin = (lowerMarker.getValue() + upperMarker.getValue())/20.0;
//add listener to handle range adjustment
- var lowerMarkerListener = new MouseOnMarkerListener(this, lowerMarker, margin);
- var upperMarkerListener = new MouseOnMarkerListener(this, upperMarker, margin);
+ var lowerMarkerListener = new MouseOnMarkerListener(this, lowerMarker, upperMarker, margin);
+ var upperMarkerListener = new MouseOnMarkerListener(this, upperMarker, upperMarker, margin);
chartPanel.addChartMouseListener(lowerMarkerListener);
chartPanel.addChartMouseListener(upperMarkerListener);
diff --git a/src/main/java/pulse/ui/components/listeners/MouseOnMarkerListener.java b/src/main/java/pulse/ui/components/listeners/MouseOnMarkerListener.java
index 4a4d1ef..834dc1c 100644
--- a/src/main/java/pulse/ui/components/listeners/MouseOnMarkerListener.java
+++ b/src/main/java/pulse/ui/components/listeners/MouseOnMarkerListener.java
@@ -27,16 +27,19 @@
*/
public class MouseOnMarkerListener implements ChartMouseListener {
- private final MovableValueMarker marker;
+ private final MovableValueMarker lower;
+ private final MovableValueMarker upper;
+
private final Chart chart;
private final double margin;
private final static Cursor CROSSHAIR = new Cursor(Cursor.CROSSHAIR_CURSOR);
private final static Cursor RESIZE = new Cursor(Cursor.E_RESIZE_CURSOR);
- public MouseOnMarkerListener(Chart chart, MovableValueMarker marker, double margin) {
+ public MouseOnMarkerListener(Chart chart, MovableValueMarker lower, MovableValueMarker upper, double margin) {
this.chart = chart;
- this.marker = marker;
+ this.lower = lower;
+ this.upper = upper;
this.margin = margin;
}
@@ -48,20 +51,29 @@ public void chartMouseClicked(ChartMouseEvent arg0) {
@Override
public void chartMouseMoved(ChartMouseEvent arg0) {
double xCoord = chart.xCoord(arg0.getTrigger());
- highlightMarker(xCoord, marker);
+ highlightMarker(xCoord);
}
- private void highlightMarker(double xCoord, MovableValueMarker marker) {
+ private void highlightMarker(double xCoord) {
- if (xCoord > (marker.getValue() - margin)
- & xCoord < (marker.getValue() + margin)) {
+ if (xCoord > (lower.getValue() - margin)
+ & xCoord < (lower.getValue() + margin)) {
- marker.setState(MovableValueMarker.State.SELECTED);
+ lower.setState(MovableValueMarker.State.SELECTED);
chart.getChartPanel().setCursor(RESIZE);
- } else {
+ }
+ else if (xCoord > (upper.getValue() - margin)
+ & xCoord < (upper.getValue() + margin)) {
+
+ upper.setState(MovableValueMarker.State.SELECTED);
+ chart.getChartPanel().setCursor(RESIZE);
+
+ }
+ else {
- marker.setState(MovableValueMarker.State.IDLE);
+ lower.setState(MovableValueMarker.State.IDLE);
+ upper.setState(MovableValueMarker.State.IDLE);
chart.getChartPanel().setCursor(CROSSHAIR);
}
diff --git a/src/main/java/pulse/ui/frames/MainGraphFrame.java b/src/main/java/pulse/ui/frames/MainGraphFrame.java
index 3d81254..fff33ec 100644
--- a/src/main/java/pulse/ui/frames/MainGraphFrame.java
+++ b/src/main/java/pulse/ui/frames/MainGraphFrame.java
@@ -8,6 +8,7 @@
import javax.swing.JInternalFrame;
import pulse.tasks.TaskManager;
+import pulse.tasks.logs.Status;
import pulse.ui.components.Chart;
import pulse.ui.components.panels.ChartToolbar;
import pulse.ui.components.panels.OpacitySlider;
@@ -44,7 +45,8 @@ private void initComponents() {
public void plot() {
var task = TaskManager.getManagerInstance().getSelectedTask();
- if (task != null) {
+ //do not plot tasks that are not finished
+ if (task != null && task.getCurrentCalculation().getStatus() != Status.IN_PROGRESS) {
Executors.newSingleThreadExecutor().submit(() -> chart.plot(task, false));
}
}
diff --git a/src/main/java/pulse/ui/frames/SearchOptionsFrame.java b/src/main/java/pulse/ui/frames/SearchOptionsFrame.java
index d8b0b6c..2d7edda 100644
--- a/src/main/java/pulse/ui/frames/SearchOptionsFrame.java
+++ b/src/main/java/pulse/ui/frames/SearchOptionsFrame.java
@@ -50,7 +50,7 @@ public class SearchOptionsFrame extends JInternalFrame {
private final static Font FONT = new Font(getString("PropertyHolderTable.FontName"), ITALIC, 16);
private final static List pathSolvers = instancesOf(PathOptimiser.class);
- private final NumericPropertyKeyword[] mandatorySelection = new NumericPropertyKeyword[]{DIFFUSIVITY, MAXTEMP};
+ private final NumericPropertyKeyword[] mandatorySelection = new NumericPropertyKeyword[]{MAXTEMP};
/**
* Create the frame.
diff --git a/src/main/java/pulse/ui/frames/dialogs/ExportDialog.java b/src/main/java/pulse/ui/frames/dialogs/ExportDialog.java
index f8a9300..ed0f7ee 100644
--- a/src/main/java/pulse/ui/frames/dialogs/ExportDialog.java
+++ b/src/main/java/pulse/ui/frames/dialogs/ExportDialog.java
@@ -14,6 +14,7 @@
import java.awt.Dimension;
import java.io.File;
+import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
@@ -81,12 +82,12 @@ public ExportDialog() {
}
private File directoryQuery() {
- var returnVal = fileChooser.showSaveDialog(this);
+ var returnVal = fileChooser.showOpenDialog(this);
File f = null;
if (returnVal == APPROVE_OPTION) {
- f = fileChooser.getCurrentDirectory();
+ dir = f = fileChooser.getSelectedFile();
}
return f;
@@ -171,8 +172,9 @@ private void initComponents() {
fileChooser = new JFileChooser();
fileChooser.setMultiSelectionEnabled(false);
fileChooser.setFileSelectionMode(DIRECTORIES_ONLY);
- // Checkboxex
- dir = fileChooser.getCurrentDirectory();
+
+ //get cwd
+ dir = new File("").getAbsoluteFile();
var directoryField = new JTextField(dir.getPath() + separator + projectName + separator);
directoryField.setEditable(false);
@@ -247,11 +249,8 @@ public void removeUpdate(DocumentEvent e) {
var browseBtn = new JButton("Browse...");
- browseBtn.addActionListener(e -> {
- if (directoryQuery() != null) {
- directoryField.setText(dir.getPath() + separator + projectName + separator);
- }
- });
+ browseBtn.addActionListener(e -> directoryField.setText(directoryQuery()
+ .getPath() + separator + projectName + separator) );
var exportBtn = new JButton("Export");
diff --git a/src/main/resources/NumericProperty.xml b/src/main/resources/NumericProperty.xml
index 89dca9d..9c78b74 100644
--- a/src/main/resources/NumericProperty.xml
+++ b/src/main/resources/NumericProperty.xml
@@ -1,5 +1,10 @@
+
+
-
-
-
+
-
-
+ minimum="1.0E-6" value="0.001" primitive-type="double" discreet="true"
+ default-search-variable="false">