Moved WorkManager to fx
This commit is contained in:
parent
ab006cb10f
commit
583ed5d63c
@ -7,12 +7,15 @@
|
||||
package inr.numass.scripts
|
||||
|
||||
import hep.dataforge.grind.Grind
|
||||
import hep.dataforge.tables.DataPoint
|
||||
import inr.numass.storage.NMPoint
|
||||
import inr.numass.storage.NumassData
|
||||
import inr.numass.storage.NumassDataLoader
|
||||
import inr.numass.storage.RawNMPoint
|
||||
import inr.numass.utils.NMEventGeneratorWithPulser
|
||||
import inr.numass.utils.PileUpSimulator
|
||||
import inr.numass.utils.TritiumUtils
|
||||
import inr.numass.utils.UnderflowCorrection
|
||||
import org.apache.commons.math3.random.JDKRandomGenerator
|
||||
|
||||
rnd = new JDKRandomGenerator();
|
||||
@ -37,12 +40,37 @@ List<NMPoint> pileup = new ArrayList<>();
|
||||
lowerChannel = 400;
|
||||
upperChannel = 1800;
|
||||
|
||||
PileUpSimulator buildSimulator(NMPoint point, double cr, NMPoint reference = null, double scale = 1d) {
|
||||
PileUpSimulator buildSimulator(NMPoint point, double cr, NMPoint reference = null, boolean extrapolate = true, double scale = 1d) {
|
||||
def cfg = Grind.buildMeta(cr: cr) {
|
||||
pulser(mean: 3450, sigma: 86.45, freq: 66.43)
|
||||
}
|
||||
NMEventGeneratorWithPulser generator = new NMEventGeneratorWithPulser(rnd, cfg)
|
||||
|
||||
if (extrapolate) {
|
||||
double[] chanels = new double[RawNMPoint.MAX_CHANEL];
|
||||
double[] values = new double[RawNMPoint.MAX_CHANEL];
|
||||
DataPoint fitResult = new UnderflowCorrection().fitPoint(point, 400, 600, 1800, 20);
|
||||
|
||||
def amp = fitResult.getDouble("amp")
|
||||
def sigma = fitResult.getDouble("expConst")
|
||||
if (sigma > 0) {
|
||||
|
||||
for (int i = 0; i < upperChannel; i++) {
|
||||
chanels[i] = i;
|
||||
if (i < lowerChannel) {
|
||||
values[i] = point.getLength()*amp * Math.exp((i as double) / sigma)
|
||||
} else {
|
||||
values[i] = Math.max(0, point.getCountInChanel(i) - (reference == null ? 0 : reference.getCountInChanel(i)));
|
||||
}
|
||||
}
|
||||
generator.loadSpectrum(chanels, values)
|
||||
} else {
|
||||
generator.loadSpectrum(point, reference, lowerChannel, upperChannel);
|
||||
}
|
||||
} else {
|
||||
generator.loadSpectrum(point, reference, lowerChannel, upperChannel);
|
||||
}
|
||||
|
||||
return new PileUpSimulator(point.length * scale, rnd, generator).withUset(point.uset).generate();
|
||||
}
|
||||
|
||||
@ -53,7 +81,7 @@ double adjustCountRate(PileUpSimulator simulator, NMPoint point) {
|
||||
}
|
||||
|
||||
data.NMPoints.forEach { point ->
|
||||
double cr = TritiumUtils.countRateWithDeadTime(point, lowerChannel, upperChannel, 6.2e-6);
|
||||
double cr = TritiumUtils.countRateWithDeadTime(point, lowerChannel, upperChannel, 6.55e-6);
|
||||
|
||||
PileUpSimulator simulator = buildSimulator(point, cr);
|
||||
|
||||
|
@ -45,6 +45,7 @@ public class Numass {
|
||||
|
||||
public static void printDescription(Context context, boolean allowANSI) throws DescriptorException {
|
||||
PrintWriter writer = new PrintWriter(context.io().out());
|
||||
|
||||
DescriptorFormatter formatter = new TextDescriptorFormatter(writer, allowANSI);
|
||||
writer.println("***Data description***");
|
||||
writer.print(" ");
|
||||
|
@ -60,6 +60,7 @@ import java.util.Arrays;
|
||||
*/
|
||||
@TypedActionDef(name = "showLoss", inputType = FitState.class, outputType = FitState.class,
|
||||
info = "Show loss spectrum for fit with loss model. Calculate excitation to ionisation ratio.")
|
||||
@Deprecated
|
||||
public class ShowLossSpectrumAction extends OneToOneAction<FitState, FitState> {
|
||||
|
||||
private static final String[] names = {"X", "exPos", "ionPos", "exW", "ionW", "exIonRatio"};
|
||||
|
@ -68,10 +68,7 @@ public class NMEventGenerator implements Supplier<NMEvent> {
|
||||
distribution = d;
|
||||
}
|
||||
|
||||
public void loadSpectrum(Map<Double, Double> spectrum, int minChanel, int maxChanel) {
|
||||
assert minChanel >= 0;
|
||||
assert maxChanel <= RawNMPoint.MAX_CHANEL;
|
||||
|
||||
public void loadSpectrum(Map<Double, Double> spectrum) {
|
||||
double[] chanels = new double[spectrum.size()];
|
||||
double[] values = new double[spectrum.size()];
|
||||
int i = 0;
|
||||
@ -82,6 +79,10 @@ public class NMEventGenerator implements Supplier<NMEvent> {
|
||||
distribution = new EnumeratedRealDistribution(chanels, values);
|
||||
}
|
||||
|
||||
public void loadSpectrum(double[] channels, double[] values) {
|
||||
distribution = new EnumeratedRealDistribution(channels, values);
|
||||
}
|
||||
|
||||
public void loadSpectrum(NMPoint point) {
|
||||
double[] chanels = new double[RawNMPoint.MAX_CHANEL];
|
||||
double[] values = new double[RawNMPoint.MAX_CHANEL];
|
||||
@ -118,6 +119,7 @@ public class NMEventGenerator implements Supplier<NMEvent> {
|
||||
distribution = new EnumeratedRealDistribution(chanels, values);
|
||||
}
|
||||
|
||||
|
||||
protected NMEvent nextEvent(NMEvent prev) {
|
||||
short chanel;
|
||||
|
||||
|
@ -5,7 +5,9 @@
|
||||
*/
|
||||
package inr.numass.utils;
|
||||
|
||||
import hep.dataforge.tables.DataPoint;
|
||||
import hep.dataforge.tables.ListTable;
|
||||
import hep.dataforge.tables.MapPoint;
|
||||
import hep.dataforge.tables.Table;
|
||||
import inr.numass.storage.NMPoint;
|
||||
import org.apache.commons.math3.analysis.ParametricUnivariateFunction;
|
||||
@ -23,6 +25,8 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class UnderflowCorrection {
|
||||
|
||||
private static String[] pointNames = {"U", "amp", "expConst", "correction"};
|
||||
|
||||
// private final static int CUTOFF = -200;
|
||||
|
||||
// public double get(Logable log, Meta meta, NMPoint point) {
|
||||
@ -49,25 +53,28 @@ public class UnderflowCorrection {
|
||||
// }
|
||||
// }
|
||||
|
||||
public Table fitAllPoints(Iterable<NMPoint> data, int xLow, int xHigh, int binning) {
|
||||
ListTable.Builder builder = new ListTable.Builder("U", "amp", "expConst");
|
||||
for (NMPoint point : data) {
|
||||
double[] fitRes = getUnderflowExpParameters(point, xLow, xHigh, binning);
|
||||
builder.row(point.getUset(), fitRes[0], fitRes[1]);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
// public Table fitAllPoints(Iterable<NMPoint> data, int xLow, int xHigh, int binning) {
|
||||
// ListTable.Builder builder = new ListTable.Builder("U", "amp", "expConst");
|
||||
// for (NMPoint point : data) {
|
||||
// double[] fitRes = getUnderflowExpParameters(point, xLow, xHigh, binning);
|
||||
// builder.row(point.getUset(), fitRes[0], fitRes[1]);
|
||||
// }
|
||||
// return builder.build();
|
||||
// }
|
||||
|
||||
public Table fitAllPoints(Iterable<NMPoint> data, int xLow, int xHigh, int upper, int binning) {
|
||||
ListTable.Builder builder = new ListTable.Builder("U", "amp", "expConst", "correction");
|
||||
for (NMPoint point : data) {
|
||||
public DataPoint fitPoint(NMPoint point, int xLow, int xHigh, int upper, int binning) {
|
||||
double norm = ((double) point.getCountInWindow(xLow, upper)) / point.getLength();
|
||||
double[] fitRes = getUnderflowExpParameters(point, xLow, xHigh, binning);
|
||||
double a = fitRes[0];
|
||||
double sigma = fitRes[1];
|
||||
|
||||
//builder.row(point.getUset(), a, sigma, (a * sigma * (Math.exp(xLow / sigma) - 1) - a*xLow) / norm + 1d);
|
||||
builder.row(point.getUset(), a, sigma, a * sigma * Math.exp(xLow / sigma) / norm + 1d);
|
||||
return new MapPoint(pointNames,point.getUset(), a, sigma, a * sigma * Math.exp(xLow / sigma) / norm + 1d);
|
||||
}
|
||||
|
||||
public Table fitAllPoints(Iterable<NMPoint> data, int xLow, int xHigh, int upper, int binning) {
|
||||
ListTable.Builder builder = new ListTable.Builder(pointNames);
|
||||
for (NMPoint point : data) {
|
||||
builder.row(fitPoint(point,xLow,xHigh,upper,binning));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -1,449 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
import hep.dataforge.actions.Action;
|
||||
import hep.dataforge.actions.ActionManager;
|
||||
import hep.dataforge.actions.ActionStateListener;
|
||||
import hep.dataforge.actions.ActionUtils;
|
||||
import hep.dataforge.context.Context;
|
||||
import hep.dataforge.context.Global;
|
||||
import hep.dataforge.data.DataNode;
|
||||
import hep.dataforge.data.FileDataFactory;
|
||||
import hep.dataforge.description.ActionDescriptor;
|
||||
import hep.dataforge.description.DescriptorUtils;
|
||||
import hep.dataforge.exceptions.NameNotFoundException;
|
||||
import hep.dataforge.fx.FXDataOutputPane;
|
||||
import hep.dataforge.fx.FXReportListener;
|
||||
import hep.dataforge.fx.configuration.MetaEditor;
|
||||
import hep.dataforge.fx.fragments.FragmentWindow;
|
||||
import hep.dataforge.fx.fragments.LogFragment;
|
||||
import hep.dataforge.fx.work.WorkManagerFragment;
|
||||
import hep.dataforge.io.IOManager;
|
||||
import hep.dataforge.io.MetaFileReader;
|
||||
import hep.dataforge.meta.ConfigChangeListener;
|
||||
import hep.dataforge.meta.Configuration;
|
||||
import hep.dataforge.meta.Meta;
|
||||
import hep.dataforge.meta.MetaBuilder;
|
||||
import hep.dataforge.plots.PlotFrame;
|
||||
import hep.dataforge.plots.PlotHolder;
|
||||
import hep.dataforge.plots.PlotsPlugin;
|
||||
import hep.dataforge.utils.ContextMetaFactory;
|
||||
import hep.dataforge.values.Value;
|
||||
import inr.numass.NumassIO;
|
||||
import inr.numass.NumassProperties;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.stage.FileChooser;
|
||||
import org.controlsfx.control.StatusBar;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* FXML Controller class
|
||||
*
|
||||
* @author Alexander Nozik
|
||||
*/
|
||||
public class NumassWorkbenchController implements Initializable, StagePaneHolder, ActionStateListener, PlotHolder {
|
||||
|
||||
Context parentContext;
|
||||
ContextMetaFactory<Context> contextFactory;
|
||||
|
||||
List<MetaEditor> actionEditors = new ArrayList<>();
|
||||
MetaEditor dataEditor;
|
||||
Context context;
|
||||
|
||||
Configuration dataConfig;
|
||||
Configuration actionsConfig;
|
||||
|
||||
Map<String, StagePane> stages = new ConcurrentHashMap<>();
|
||||
|
||||
WorkManagerFragment processWindow;
|
||||
|
||||
FXDataOutputPane logPane;
|
||||
|
||||
BooleanProperty isRunning = new SimpleBooleanProperty(false);
|
||||
|
||||
@FXML
|
||||
private StatusBar statusBar;
|
||||
@FXML
|
||||
private TabPane stagesPane;
|
||||
@FXML
|
||||
private Accordion metaContainer;
|
||||
@FXML
|
||||
private Tab logTab;
|
||||
@FXML
|
||||
private ToggleButton runButton;
|
||||
@FXML
|
||||
private ToggleButton consoleButton;
|
||||
@FXML
|
||||
private ToggleButton processButton;
|
||||
|
||||
@Override
|
||||
public void clearStage(String stageName) {
|
||||
StagePane sp = stages.get(stageName);
|
||||
if (sp != null) {
|
||||
sp.closeAll();
|
||||
Tab t = findTabWithName(stagesPane, stageName);
|
||||
stagesPane.getTabs().remove(t);
|
||||
stages.remove(stageName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the controller class.
|
||||
*/
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
logPane = new FXDataOutputPane();
|
||||
logTab.setContent(logPane.getRoot());
|
||||
|
||||
LogFragment consoleWindow = new LogFragment();
|
||||
new FragmentWindow(consoleWindow).bindTo(consoleButton);
|
||||
consoleWindow.addRootLogHandler();
|
||||
consoleWindow.hookStd();
|
||||
|
||||
processWindow = new WorkManagerFragment();
|
||||
new FragmentWindow(processWindow).bindTo(processButton);
|
||||
|
||||
isRunning.addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
|
||||
runButton.setSelected(newValue);
|
||||
if (newValue) {
|
||||
runButton.setText("Stop");
|
||||
} else {
|
||||
runButton.setText("Run");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
if (context == null) {
|
||||
throw new RuntimeException("Context not defined");
|
||||
} else {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup context for current run
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
private void buildContext(Meta config) {
|
||||
// close existing context
|
||||
if (this.context != null) {
|
||||
try {
|
||||
this.context.close();
|
||||
} catch (Exception ex) {
|
||||
context.getLogger().error("Failed to close context", ex);
|
||||
}
|
||||
}
|
||||
// building context using provided factory
|
||||
this.context = this.contextFactory.build(parentContext, config);
|
||||
|
||||
// attachig visual process manager
|
||||
processWindow.setManager(context.getWorkManager());
|
||||
|
||||
// setting io manager
|
||||
context.setIO(new WorkbenchIOManager(new NumassIO(), this));
|
||||
buildContextPane();
|
||||
context.getLog().addListener(new FXReportListener(logPane));
|
||||
|
||||
// display plots iside workbench
|
||||
PlotsPlugin.buildFrom(context).setPlotHolder(this);
|
||||
}
|
||||
|
||||
private Tab findTabWithName(TabPane pane, String name) {
|
||||
return pane.getTabs().stream().filter((t) -> t.getText().equals(name)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* build or get tabPane for a given stage
|
||||
*
|
||||
* @param stage
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public synchronized StagePane getStagePane(String stage) {
|
||||
if (!stages.containsKey(stage)) {
|
||||
Tab stageTab = new Tab(stage);
|
||||
StagePane stageTabPane = new StagePane();
|
||||
stageTab.setContent(stageTabPane);
|
||||
stages.put(stage, stageTabPane);
|
||||
Platform.runLater(() -> stagesPane.getTabs().add(stageTab));
|
||||
return stageTabPane;
|
||||
} else {
|
||||
return stages.get(stage);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ActionDescriptor> listActions() {
|
||||
return ActionManager.buildFrom(getContext()).list();
|
||||
}
|
||||
|
||||
private ActionDescriptor getDescriptorForAction(String actionType) {
|
||||
return listActions().stream().filter((a) -> a.getName().equals(actionType)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private void buildContextPane() {
|
||||
Configuration contextValues = new Configuration("context");
|
||||
//TODO add asMeta method to Context and replace map here
|
||||
context.getProperties().entrySet().stream().forEach((item) -> {
|
||||
contextValues.setValue(item.getKey(), item.getValue());
|
||||
});
|
||||
|
||||
contextValues.addObserver(new ConfigChangeListener() {
|
||||
@Override
|
||||
public void notifyValueChanged(String name, Value oldItem, Value newItem) {
|
||||
context.putValue(name, newItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyElementChanged(String name, List<? extends Meta> oldItem, List<? extends Meta> newItem) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
MetaEditor contextEditor = MetaEditor.build(contextValues, null);
|
||||
|
||||
contextEditor.geTable().setShowRoot(false);
|
||||
TitledPane contextPane = new TitledPane("Context", contextEditor);
|
||||
metaContainer.getPanes().add(contextPane);
|
||||
}
|
||||
|
||||
public void loadConfig(Meta config) {
|
||||
cleanUp();
|
||||
buildContext(config);
|
||||
|
||||
//loading data configuration
|
||||
if (config.hasMeta("data")) {
|
||||
dataConfig = new Configuration(config.getMeta("data"));
|
||||
//replacing file name value with appropriate nodes
|
||||
if (dataConfig.hasValue("file")) {
|
||||
Value fileValue = dataConfig.getValue("file");
|
||||
dataConfig.removeValue("file");
|
||||
fileValue.listValue().stream().forEach((fileName) -> {
|
||||
dataConfig.putNode(new MetaBuilder("file")
|
||||
.putValue("path", fileName));
|
||||
});
|
||||
}
|
||||
dataEditor = MetaEditor.build(dataConfig,
|
||||
DescriptorUtils.buildDescriptor(
|
||||
DescriptorUtils.findAnnotatedElement("class::hep.dataforge.data.FileDataFactory")
|
||||
));
|
||||
dataEditor.geTable().setShowRoot(false);
|
||||
metaContainer.getPanes().add(new TitledPane("Data", dataEditor));
|
||||
}
|
||||
|
||||
//loading actions configuration
|
||||
actionsConfig = new Configuration("actionlist");
|
||||
|
||||
List<Configuration> actions = config.getMetaList("action").stream()
|
||||
.map(m -> new Configuration(m)).collect(Collectors.toList());
|
||||
|
||||
actionsConfig.attachNodeItem("action", actions);
|
||||
|
||||
int counter = 0;
|
||||
for (Configuration action : actions) {
|
||||
counter++;
|
||||
MetaEditor actionEditor = new MetaEditor();
|
||||
//Freezing actions names
|
||||
// rootItem.setFrozenValuePredicate((c, n) -> c.getName().equals("action") && n.equals("type"));
|
||||
actionEditor.setRoot(action, getDescriptorForAction(action.getString("type")));
|
||||
|
||||
actionEditors.add(actionEditor);
|
||||
String actionTitle = String.format("action [%d]: %s", counter, action.getString("type"));
|
||||
TitledPane actionPane = new TitledPane(actionTitle, actionEditor);
|
||||
metaContainer.getPanes().add(actionPane);
|
||||
}
|
||||
runButton.setDisable(false);
|
||||
}
|
||||
|
||||
private void clearAllStages() {
|
||||
logPane.clear();
|
||||
stages.keySet().stream().forEach((stageName) -> {
|
||||
clearStage(stageName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up results and configuration panes
|
||||
*/
|
||||
private synchronized void cleanUp() {
|
||||
//clear previus action panes
|
||||
if (processWindow.getManager() != null) {
|
||||
processWindow.getManager().cleanup();
|
||||
}
|
||||
metaContainer.getPanes().clear();
|
||||
clearAllStages();
|
||||
actionsConfig = null;
|
||||
dataConfig = null;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onLoadConfigClick(ActionEvent event) {
|
||||
statusBar.setText("Loading configuration file...");
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Open Configuration File");
|
||||
String storageRoot = NumassProperties.getNumassProperty("numass.workbench.root");
|
||||
if (storageRoot == null || !new File(storageRoot).exists()) {
|
||||
fileChooser.setInitialDirectory(new File(".").getAbsoluteFile());
|
||||
} else {
|
||||
fileChooser.setInitialDirectory(new File(storageRoot));
|
||||
}
|
||||
File cfgFile = fileChooser.showOpenDialog(((Node) event.getTarget()).getScene().getWindow());
|
||||
if (cfgFile != null) {
|
||||
NumassProperties.setNumassProperty("numass.workbench.root", cfgFile.getParentFile().getAbsolutePath());
|
||||
try {
|
||||
Meta cfg = MetaFileReader.read(cfgFile).build();
|
||||
this.loadConfig(cfg);
|
||||
getContext().putValue(IOManager.ROOT_DIRECTORY_CONTEXT_KEY, cfgFile.getParentFile().toString());
|
||||
|
||||
} catch (IOException | ParseException ex) {
|
||||
context.getLogger().error("Error reading configuration file", ex);
|
||||
}
|
||||
statusBar.setText("Configuration file loaded");
|
||||
} else {
|
||||
statusBar.setText("Loading configuration file canceled");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onRunButtonClick(ActionEvent event) {
|
||||
if (!isRunning.get()) {
|
||||
if (context != null && !actionsConfig.isEmpty()) {
|
||||
statusBar.setText("Starting action execution");
|
||||
runActions();
|
||||
}
|
||||
} else {
|
||||
this.context.getWorkManager().shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public Meta getDataConfiguration() {
|
||||
return dataConfig == null ? Meta.empty() : new MetaBuilder(dataConfig).substituteValues(getContext()).build();
|
||||
}
|
||||
|
||||
public Meta getActionConfiguration() {
|
||||
return actionsConfig == null ? Meta.empty() : new MetaBuilder(actionsConfig).substituteValues(getContext()).build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void runActions() {
|
||||
clearAllStages();
|
||||
// processWindow.show();
|
||||
new Thread(() -> {
|
||||
|
||||
Platform.runLater(() -> {
|
||||
isRunning.set(true);
|
||||
statusBar.setProgress(-1);
|
||||
});
|
||||
|
||||
DataNode data = new FileDataFactory().build(getContext(), getDataConfiguration());
|
||||
try {
|
||||
ActionUtils.runAction(getContext(), data, getActionConfiguration()).computeAll();
|
||||
Platform.runLater(() -> statusBar.setText("Execution complete"));
|
||||
} catch (Exception ex) {
|
||||
if (ex instanceof java.util.concurrent.CancellationException) {
|
||||
//cach cancelation exception
|
||||
Global.instance().getLogger().info("Interrupted by user");
|
||||
Platform.runLater(() -> {
|
||||
statusBar.setText("Execution interrupted by user");
|
||||
});
|
||||
} else {
|
||||
//cach all other exceptions
|
||||
Global.instance().getLogger().error("Exception while executing action chain", ex);
|
||||
ex.printStackTrace(System.err);
|
||||
Platform.runLater(() -> {
|
||||
//printing stack trace to the default output
|
||||
statusBar.setText("Execution failed");
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("Exception!");
|
||||
alert.setHeaderText("Action execution failure");
|
||||
alert.setContentText(ex.getMessage());
|
||||
alert.show();
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
Platform.runLater(() -> {
|
||||
isRunning.set(false);
|
||||
statusBar.setProgress(0);
|
||||
});
|
||||
}
|
||||
|
||||
}, "actions").start();
|
||||
}
|
||||
|
||||
public void setParentContext(Context parentContext) {
|
||||
this.parentContext = parentContext;
|
||||
}
|
||||
|
||||
public void setContextFactory(ContextMetaFactory<Context> contextFactory) {
|
||||
this.contextFactory = contextFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyActionStarted(Action action, Object argument) {
|
||||
Platform.runLater(() -> statusBar.setText(String.format("Action '%s' started", action.getName())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyActionFinished(Action action, Object result) {
|
||||
Platform.runLater(() -> statusBar.setText(String.format("Action '%s' fineshed", action.getName())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAcionProgress(Action action, double progress, String message) {
|
||||
Platform.runLater(() -> {
|
||||
statusBar.setText(String.format("%s: %s started", action.getName(), message));
|
||||
if (progress > 0) {
|
||||
statusBar.setProgress(progress);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotFrame buildPlotFrame(String stage, String name, Meta annotation) {
|
||||
return getStagePane(stage).buildPlotOutput(name, annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotFrame getPlotFrame(String stage, String name) throws NameNotFoundException {
|
||||
StagePane pane = getStagePane(stage);
|
||||
Tab tab = findTabWithName(pane, "image::" + name);
|
||||
if (tab != null && tab instanceof PlotOutputTab) {
|
||||
return ((PlotOutputTab) tab).getFrame();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPlotFrame(String stage, String name) {
|
||||
StagePane pane = getStagePane(stage);
|
||||
Tab tab = findTabWithName(pane, "image::" + name);
|
||||
return (tab != null && tab instanceof PlotOutputTab);
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
import hep.dataforge.names.Named;
|
||||
import javafx.scene.control.Tab;
|
||||
|
||||
/**
|
||||
* A tab which contains output of task or action.
|
||||
*
|
||||
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
|
||||
*/
|
||||
public abstract class OutputTab extends Tab implements Named {
|
||||
|
||||
private String name;
|
||||
|
||||
public OutputTab(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public OutputTab(String name, String title) {
|
||||
super(title);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public abstract void close();
|
||||
|
||||
public abstract void clear();
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
import hep.dataforge.meta.Meta;
|
||||
import hep.dataforge.plots.fx.PlotContainer;
|
||||
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
||||
|
||||
public class PlotOutputTab extends OutputTab {
|
||||
|
||||
private final JFreeChartFrame frame;
|
||||
|
||||
public PlotOutputTab(String name, Meta meta) {
|
||||
super(name);
|
||||
PlotContainer container = new PlotContainer();
|
||||
frame = new JFreeChartFrame(meta);
|
||||
container.setPlot(frame);
|
||||
// AnchorPane pane = new AnchorPane();
|
||||
// frame = new JFreeChartFrame(name, meta).display(pane);
|
||||
setContent(container.getRoot());
|
||||
}
|
||||
|
||||
public PlotOutputTab(String name, String title, Meta meta) {
|
||||
super(name, title);
|
||||
PlotContainer container = new PlotContainer();
|
||||
frame = new JFreeChartFrame(meta);
|
||||
container.setPlot(frame);
|
||||
setContent(container.getRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
|
||||
public JFreeChartFrame getFrame() {
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
import hep.dataforge.fx.FXUtils;
|
||||
import hep.dataforge.meta.Meta;
|
||||
import hep.dataforge.names.Named;
|
||||
import hep.dataforge.plots.PlotFrame;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.TabPane;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
|
||||
*/
|
||||
public class StagePane extends TabPane implements Named {
|
||||
|
||||
private String name;
|
||||
private final Map<String, OutputTab> tabs = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void closeAll() {
|
||||
tabs.values().stream().map((tab) -> {
|
||||
tab.close();
|
||||
return tab;
|
||||
}).forEach((tab) -> {
|
||||
Platform.runLater(() -> getTabs().remove(tab));
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void closeTab(String name) {
|
||||
FXUtils.runNow(() -> {
|
||||
tabs.get(name).close();
|
||||
getTabs().remove(tabs.get(name));
|
||||
tabs.remove(name);
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized TextOutputTab buildTextOutput(String name) {
|
||||
TextOutputTab out = new TextOutputTab(name);
|
||||
FXUtils.runNow(() -> {
|
||||
if (tabs.containsKey(name)) {
|
||||
tabs.get(name).close();
|
||||
getTabs().remove(tabs.get(name));
|
||||
tabs.replace(name, out);
|
||||
}
|
||||
getTabs().add(out);
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
public synchronized PlotFrame buildPlotOutput(String name, Meta meta) {
|
||||
PlotOutputTab out = new PlotOutputTab("plot::" + name, meta);
|
||||
FXUtils.runNow(() -> {
|
||||
if (tabs.containsKey(name)) {
|
||||
tabs.get(name).close();
|
||||
getTabs().remove(tabs.get(name));
|
||||
tabs.replace(name, out);
|
||||
}
|
||||
getTabs().add(out);
|
||||
});
|
||||
return out.getFrame();
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
|
||||
*/
|
||||
public interface StagePaneHolder {
|
||||
StagePane getStagePane(String stageName);
|
||||
void clearStage(String stageName);
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
import hep.dataforge.fx.FXDataOutputPane;
|
||||
import javafx.event.Event;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* A text output tab. Basically it is attached to IOManager::onComplete
|
||||
*
|
||||
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
|
||||
*/
|
||||
public class TextOutputTab extends OutputTab {
|
||||
|
||||
private final FXDataOutputPane out;
|
||||
|
||||
/**
|
||||
* Create new stream output tab
|
||||
*
|
||||
* @param name
|
||||
* @param stream outputStream to which output should be redirected after
|
||||
* displaying in window
|
||||
*/
|
||||
public TextOutputTab(String name) {
|
||||
super(name);
|
||||
// onComplete = new DataOutputPane();
|
||||
out = new FXDataOutputPane();
|
||||
setContent(out.getRoot());
|
||||
setOnClosed((Event event) -> close());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
out.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void close() {
|
||||
clear();
|
||||
}
|
||||
|
||||
public OutputStream getStream() {
|
||||
return out.getStream();
|
||||
}
|
||||
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
import hep.dataforge.context.Global;
|
||||
import inr.numass.Numass;
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.WindowEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexander Nozik
|
||||
*/
|
||||
public class Workbench extends Application {
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException, ParseException {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/NumassWorkbench.fxml"));
|
||||
Parent parent = loader.load();
|
||||
|
||||
Scene scene = new Scene(parent, 800, 600);
|
||||
|
||||
NumassWorkbenchController controller = loader.getController();
|
||||
controller.setContextFactory(Numass::buildContext);
|
||||
|
||||
primaryStage.setTitle("Numass workbench");
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
|
||||
scene.getWindow().setOnCloseRequest((WindowEvent event) -> {
|
||||
try {
|
||||
controller.getContext().getWorkManager().getRoot().cancel(true);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
Global.instance().close();
|
||||
super.stop();
|
||||
}
|
||||
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
import hep.dataforge.io.BasicIOManager;
|
||||
import hep.dataforge.io.IOManager;
|
||||
import hep.dataforge.names.Name;
|
||||
import org.apache.commons.io.output.TeeOutputStream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An IOManager wrapper that redirects output to appropriate FX components
|
||||
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
|
||||
*/
|
||||
public class WorkbenchIOManager extends BasicIOManager {
|
||||
|
||||
private final IOManager manager;
|
||||
private final StagePaneHolder holder;
|
||||
|
||||
public WorkbenchIOManager(IOManager manager, StagePaneHolder holder) {
|
||||
this.manager = manager;
|
||||
this.holder = holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFile(String path) {
|
||||
return manager.getFile(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getRootDirectory() {
|
||||
return manager.getRootDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream in() {
|
||||
return manager.in();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream in(String path) {
|
||||
return manager.in(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream out(Name stage, Name name) {
|
||||
//split output between parent output and holder output
|
||||
OutputStream primary = holder.getStagePane(stage.toString()).buildTextOutput(name.toString()).getStream();
|
||||
OutputStream secondary = manager.out(stage, name);
|
||||
return new TeeOutputStream(primary, secondary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream out() {
|
||||
return manager.out();
|
||||
// return new ConsoleStream(holder.getLogArea(), new PrintStream(manager.onComplete()));
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package inr.numass.workbench;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
|
||||
*/
|
||||
public class WorkbenchUtils {
|
||||
|
||||
}
|
@ -20,8 +20,9 @@ import hep.dataforge.context.Global;
|
||||
import hep.dataforge.exceptions.StorageException;
|
||||
import hep.dataforge.fx.fragments.FragmentWindow;
|
||||
import hep.dataforge.fx.fragments.LogFragment;
|
||||
import hep.dataforge.fx.work.Work;
|
||||
import hep.dataforge.fx.work.WorkManager;
|
||||
import hep.dataforge.fx.work.WorkManagerFragment;
|
||||
import hep.dataforge.goals.Work;
|
||||
import inr.numass.NumassProperties;
|
||||
import inr.numass.storage.NumassData;
|
||||
import inr.numass.storage.NumassStorage;
|
||||
@ -85,6 +86,8 @@ public class MainViewerController implements Initializable {
|
||||
@FXML
|
||||
private ToggleButton processManagerButton;
|
||||
|
||||
private WorkManager workManager;
|
||||
|
||||
public static MainViewerController build(NumassStorage root) {
|
||||
MainViewerController res = new MainViewerController();
|
||||
res.setRootStorage(root);
|
||||
@ -102,9 +105,10 @@ public class MainViewerController implements Initializable {
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
LogFragment logFragment = new LogFragment();
|
||||
logFragment.hookStd();
|
||||
logFragment.addRootLogHandler();
|
||||
//logFragment.hookStd();
|
||||
new FragmentWindow(logFragment).bindTo(consoleButton);
|
||||
new FragmentWindow(WorkManagerFragment.attachToContext(Global.instance())).bindTo(processManagerButton);
|
||||
new FragmentWindow(new WorkManagerFragment(getWorkManager())).bindTo(processManagerButton);
|
||||
|
||||
mspController = new MspViewController(getContext());
|
||||
this.mspTab.setContent(mspController.getRoot());
|
||||
@ -131,7 +135,7 @@ public class MainViewerController implements Initializable {
|
||||
}
|
||||
|
||||
private void loadDirectory(String path) {
|
||||
getContext().getWorkManager().startWork("viewer.loadDirectory", (Work work) -> {
|
||||
getWorkManager().startWork("viewer.loadDirectory", (Work work) -> {
|
||||
work.setTitle("Load storage (" + path + ")");
|
||||
work.setProgress(-1);
|
||||
work.setStatus("Building numass storage tree...");
|
||||
@ -151,10 +155,18 @@ public class MainViewerController implements Initializable {
|
||||
return Global.instance();
|
||||
}
|
||||
|
||||
private synchronized WorkManager getWorkManager() {
|
||||
if(workManager == null) {
|
||||
workManager = new WorkManager();
|
||||
workManager.startGlobal();
|
||||
}
|
||||
return workManager;
|
||||
}
|
||||
|
||||
public void setRootStorage(NumassStorage root) {
|
||||
|
||||
getContext().getWorkManager().cleanup();
|
||||
getContext().getWorkManager().startWork("viewer.storage.load", (Work callback) -> {
|
||||
getWorkManager().cleanup();
|
||||
getWorkManager().startWork("viewer.storage.load", (Work callback) -> {
|
||||
callback.setTitle("Fill data to UI (" + root.getName() + ")");
|
||||
callback.setProgress(-1);
|
||||
Platform.runLater(() -> statusBar.setProgress(-1));
|
||||
|
@ -16,7 +16,7 @@
|
||||
package inr.numass.viewer;
|
||||
|
||||
import hep.dataforge.exceptions.StorageException;
|
||||
import hep.dataforge.goals.Work;
|
||||
import hep.dataforge.fx.work.Work;
|
||||
import inr.numass.storage.NumassData;
|
||||
import inr.numass.storage.NumassStorage;
|
||||
import javafx.application.Platform;
|
||||
|
@ -22,7 +22,8 @@ package inr.numass.viewer;
|
||||
*/
|
||||
|
||||
import hep.dataforge.context.Context;
|
||||
import hep.dataforge.goals.Work;
|
||||
import hep.dataforge.fx.work.Work;
|
||||
import hep.dataforge.fx.work.WorkManager;
|
||||
import hep.dataforge.io.ColumnedDataWriter;
|
||||
import hep.dataforge.meta.Meta;
|
||||
import hep.dataforge.meta.MetaBuilder;
|
||||
@ -211,10 +212,14 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
|
||||
return data;
|
||||
}
|
||||
|
||||
private WorkManager getWorkManager(){
|
||||
return context.getPlugin(WorkManager.class);
|
||||
}
|
||||
|
||||
public void loadData(NumassData data) {
|
||||
this.data = data;
|
||||
if (data != null) {
|
||||
context.getWorkManager().<List<NMPoint>>startWork("viewer.numass.load", (Work callback) -> {
|
||||
getWorkManager().<List<NMPoint>>startWork("viewer.numass.load", (Work callback) -> {
|
||||
callback.setTitle("Load numass data (" + data.getName() + ")");
|
||||
points = data.getNMPoints();
|
||||
|
||||
@ -239,7 +244,7 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
|
||||
}
|
||||
|
||||
private void setupHVPane(Supplier<Table> hvData) {
|
||||
context.getWorkManager().startWork("viewer.numass.hv", (Work callback) -> {
|
||||
getWorkManager().startWork("viewer.numass.hv", (Work callback) -> {
|
||||
Table t = hvData.get();
|
||||
Platform.runLater(() -> {
|
||||
if (t != null) {
|
||||
@ -343,7 +348,7 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
|
||||
detectorPlot.removePlot();
|
||||
}
|
||||
|
||||
context.getWorkManager().startWork("viewer.numass.load.detector", (Work callback) -> {
|
||||
getWorkManager().startWork("viewer.numass.load.detector", (Work callback) -> {
|
||||
Meta plottableConfig = new MetaBuilder("plot")
|
||||
.setValue("connectionType", "step")
|
||||
.setValue("thickness", 2)
|
||||
|
Loading…
Reference in New Issue
Block a user