Moved WorkManager to fx
This commit is contained in:
parent
ab006cb10f
commit
583ed5d63c
@ -7,12 +7,15 @@
|
|||||||
package inr.numass.scripts
|
package inr.numass.scripts
|
||||||
|
|
||||||
import hep.dataforge.grind.Grind
|
import hep.dataforge.grind.Grind
|
||||||
|
import hep.dataforge.tables.DataPoint
|
||||||
import inr.numass.storage.NMPoint
|
import inr.numass.storage.NMPoint
|
||||||
import inr.numass.storage.NumassData
|
import inr.numass.storage.NumassData
|
||||||
import inr.numass.storage.NumassDataLoader
|
import inr.numass.storage.NumassDataLoader
|
||||||
|
import inr.numass.storage.RawNMPoint
|
||||||
import inr.numass.utils.NMEventGeneratorWithPulser
|
import inr.numass.utils.NMEventGeneratorWithPulser
|
||||||
import inr.numass.utils.PileUpSimulator
|
import inr.numass.utils.PileUpSimulator
|
||||||
import inr.numass.utils.TritiumUtils
|
import inr.numass.utils.TritiumUtils
|
||||||
|
import inr.numass.utils.UnderflowCorrection
|
||||||
import org.apache.commons.math3.random.JDKRandomGenerator
|
import org.apache.commons.math3.random.JDKRandomGenerator
|
||||||
|
|
||||||
rnd = new JDKRandomGenerator();
|
rnd = new JDKRandomGenerator();
|
||||||
@ -37,12 +40,37 @@ List<NMPoint> pileup = new ArrayList<>();
|
|||||||
lowerChannel = 400;
|
lowerChannel = 400;
|
||||||
upperChannel = 1800;
|
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) {
|
def cfg = Grind.buildMeta(cr: cr) {
|
||||||
pulser(mean: 3450, sigma: 86.45, freq: 66.43)
|
pulser(mean: 3450, sigma: 86.45, freq: 66.43)
|
||||||
}
|
}
|
||||||
NMEventGeneratorWithPulser generator = new NMEventGeneratorWithPulser(rnd, cfg)
|
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);
|
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();
|
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 ->
|
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);
|
PileUpSimulator simulator = buildSimulator(point, cr);
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ public class Numass {
|
|||||||
|
|
||||||
public static void printDescription(Context context, boolean allowANSI) throws DescriptorException {
|
public static void printDescription(Context context, boolean allowANSI) throws DescriptorException {
|
||||||
PrintWriter writer = new PrintWriter(context.io().out());
|
PrintWriter writer = new PrintWriter(context.io().out());
|
||||||
|
|
||||||
DescriptorFormatter formatter = new TextDescriptorFormatter(writer, allowANSI);
|
DescriptorFormatter formatter = new TextDescriptorFormatter(writer, allowANSI);
|
||||||
writer.println("***Data description***");
|
writer.println("***Data description***");
|
||||||
writer.print(" ");
|
writer.print(" ");
|
||||||
|
@ -60,6 +60,7 @@ import java.util.Arrays;
|
|||||||
*/
|
*/
|
||||||
@TypedActionDef(name = "showLoss", inputType = FitState.class, outputType = FitState.class,
|
@TypedActionDef(name = "showLoss", inputType = FitState.class, outputType = FitState.class,
|
||||||
info = "Show loss spectrum for fit with loss model. Calculate excitation to ionisation ratio.")
|
info = "Show loss spectrum for fit with loss model. Calculate excitation to ionisation ratio.")
|
||||||
|
@Deprecated
|
||||||
public class ShowLossSpectrumAction extends OneToOneAction<FitState, FitState> {
|
public class ShowLossSpectrumAction extends OneToOneAction<FitState, FitState> {
|
||||||
|
|
||||||
private static final String[] names = {"X", "exPos", "ionPos", "exW", "ionW", "exIonRatio"};
|
private static final String[] names = {"X", "exPos", "ionPos", "exW", "ionW", "exIonRatio"};
|
||||||
|
@ -68,10 +68,7 @@ public class NMEventGenerator implements Supplier<NMEvent> {
|
|||||||
distribution = d;
|
distribution = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadSpectrum(Map<Double, Double> spectrum, int minChanel, int maxChanel) {
|
public void loadSpectrum(Map<Double, Double> spectrum) {
|
||||||
assert minChanel >= 0;
|
|
||||||
assert maxChanel <= RawNMPoint.MAX_CHANEL;
|
|
||||||
|
|
||||||
double[] chanels = new double[spectrum.size()];
|
double[] chanels = new double[spectrum.size()];
|
||||||
double[] values = new double[spectrum.size()];
|
double[] values = new double[spectrum.size()];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -82,6 +79,10 @@ public class NMEventGenerator implements Supplier<NMEvent> {
|
|||||||
distribution = new EnumeratedRealDistribution(chanels, values);
|
distribution = new EnumeratedRealDistribution(chanels, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadSpectrum(double[] channels, double[] values) {
|
||||||
|
distribution = new EnumeratedRealDistribution(channels, values);
|
||||||
|
}
|
||||||
|
|
||||||
public void loadSpectrum(NMPoint point) {
|
public void loadSpectrum(NMPoint point) {
|
||||||
double[] chanels = new double[RawNMPoint.MAX_CHANEL];
|
double[] chanels = new double[RawNMPoint.MAX_CHANEL];
|
||||||
double[] values = 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);
|
distribution = new EnumeratedRealDistribution(chanels, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected NMEvent nextEvent(NMEvent prev) {
|
protected NMEvent nextEvent(NMEvent prev) {
|
||||||
short chanel;
|
short chanel;
|
||||||
|
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
package inr.numass.utils;
|
package inr.numass.utils;
|
||||||
|
|
||||||
|
import hep.dataforge.tables.DataPoint;
|
||||||
import hep.dataforge.tables.ListTable;
|
import hep.dataforge.tables.ListTable;
|
||||||
|
import hep.dataforge.tables.MapPoint;
|
||||||
import hep.dataforge.tables.Table;
|
import hep.dataforge.tables.Table;
|
||||||
import inr.numass.storage.NMPoint;
|
import inr.numass.storage.NMPoint;
|
||||||
import org.apache.commons.math3.analysis.ParametricUnivariateFunction;
|
import org.apache.commons.math3.analysis.ParametricUnivariateFunction;
|
||||||
@ -23,6 +25,8 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public class UnderflowCorrection {
|
public class UnderflowCorrection {
|
||||||
|
|
||||||
|
private static String[] pointNames = {"U", "amp", "expConst", "correction"};
|
||||||
|
|
||||||
// private final static int CUTOFF = -200;
|
// private final static int CUTOFF = -200;
|
||||||
|
|
||||||
// public double get(Logable log, Meta meta, NMPoint point) {
|
// 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) {
|
// public Table fitAllPoints(Iterable<NMPoint> data, int xLow, int xHigh, int binning) {
|
||||||
ListTable.Builder builder = new ListTable.Builder("U", "amp", "expConst");
|
// ListTable.Builder builder = new ListTable.Builder("U", "amp", "expConst");
|
||||||
for (NMPoint point : data) {
|
// for (NMPoint point : data) {
|
||||||
double[] fitRes = getUnderflowExpParameters(point, xLow, xHigh, binning);
|
// double[] fitRes = getUnderflowExpParameters(point, xLow, xHigh, binning);
|
||||||
builder.row(point.getUset(), fitRes[0], fitRes[1]);
|
// builder.row(point.getUset(), fitRes[0], fitRes[1]);
|
||||||
}
|
// }
|
||||||
return builder.build();
|
// return builder.build();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Table fitAllPoints(Iterable<NMPoint> data, int xLow, int xHigh, int upper, int binning) {
|
public DataPoint fitPoint(NMPoint point, int xLow, int xHigh, int upper, int binning) {
|
||||||
ListTable.Builder builder = new ListTable.Builder("U", "amp", "expConst", "correction");
|
|
||||||
for (NMPoint point : data) {
|
|
||||||
double norm = ((double) point.getCountInWindow(xLow, upper)) / point.getLength();
|
double norm = ((double) point.getCountInWindow(xLow, upper)) / point.getLength();
|
||||||
double[] fitRes = getUnderflowExpParameters(point, xLow, xHigh, binning);
|
double[] fitRes = getUnderflowExpParameters(point, xLow, xHigh, binning);
|
||||||
double a = fitRes[0];
|
double a = fitRes[0];
|
||||||
double sigma = fitRes[1];
|
double sigma = fitRes[1];
|
||||||
|
|
||||||
//builder.row(point.getUset(), a, sigma, (a * sigma * (Math.exp(xLow / sigma) - 1) - a*xLow) / norm + 1d);
|
return new MapPoint(pointNames,point.getUset(), a, sigma, a * sigma * Math.exp(xLow / sigma) / norm + 1d);
|
||||||
builder.row(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();
|
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.exceptions.StorageException;
|
||||||
import hep.dataforge.fx.fragments.FragmentWindow;
|
import hep.dataforge.fx.fragments.FragmentWindow;
|
||||||
import hep.dataforge.fx.fragments.LogFragment;
|
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.fx.work.WorkManagerFragment;
|
||||||
import hep.dataforge.goals.Work;
|
|
||||||
import inr.numass.NumassProperties;
|
import inr.numass.NumassProperties;
|
||||||
import inr.numass.storage.NumassData;
|
import inr.numass.storage.NumassData;
|
||||||
import inr.numass.storage.NumassStorage;
|
import inr.numass.storage.NumassStorage;
|
||||||
@ -85,6 +86,8 @@ public class MainViewerController implements Initializable {
|
|||||||
@FXML
|
@FXML
|
||||||
private ToggleButton processManagerButton;
|
private ToggleButton processManagerButton;
|
||||||
|
|
||||||
|
private WorkManager workManager;
|
||||||
|
|
||||||
public static MainViewerController build(NumassStorage root) {
|
public static MainViewerController build(NumassStorage root) {
|
||||||
MainViewerController res = new MainViewerController();
|
MainViewerController res = new MainViewerController();
|
||||||
res.setRootStorage(root);
|
res.setRootStorage(root);
|
||||||
@ -102,9 +105,10 @@ public class MainViewerController implements Initializable {
|
|||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
public void initialize(URL url, ResourceBundle rb) {
|
||||||
LogFragment logFragment = new LogFragment();
|
LogFragment logFragment = new LogFragment();
|
||||||
logFragment.hookStd();
|
logFragment.addRootLogHandler();
|
||||||
|
//logFragment.hookStd();
|
||||||
new FragmentWindow(logFragment).bindTo(consoleButton);
|
new FragmentWindow(logFragment).bindTo(consoleButton);
|
||||||
new FragmentWindow(WorkManagerFragment.attachToContext(Global.instance())).bindTo(processManagerButton);
|
new FragmentWindow(new WorkManagerFragment(getWorkManager())).bindTo(processManagerButton);
|
||||||
|
|
||||||
mspController = new MspViewController(getContext());
|
mspController = new MspViewController(getContext());
|
||||||
this.mspTab.setContent(mspController.getRoot());
|
this.mspTab.setContent(mspController.getRoot());
|
||||||
@ -131,7 +135,7 @@ public class MainViewerController implements Initializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadDirectory(String path) {
|
private void loadDirectory(String path) {
|
||||||
getContext().getWorkManager().startWork("viewer.loadDirectory", (Work work) -> {
|
getWorkManager().startWork("viewer.loadDirectory", (Work work) -> {
|
||||||
work.setTitle("Load storage (" + path + ")");
|
work.setTitle("Load storage (" + path + ")");
|
||||||
work.setProgress(-1);
|
work.setProgress(-1);
|
||||||
work.setStatus("Building numass storage tree...");
|
work.setStatus("Building numass storage tree...");
|
||||||
@ -151,10 +155,18 @@ public class MainViewerController implements Initializable {
|
|||||||
return Global.instance();
|
return Global.instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized WorkManager getWorkManager() {
|
||||||
|
if(workManager == null) {
|
||||||
|
workManager = new WorkManager();
|
||||||
|
workManager.startGlobal();
|
||||||
|
}
|
||||||
|
return workManager;
|
||||||
|
}
|
||||||
|
|
||||||
public void setRootStorage(NumassStorage root) {
|
public void setRootStorage(NumassStorage root) {
|
||||||
|
|
||||||
getContext().getWorkManager().cleanup();
|
getWorkManager().cleanup();
|
||||||
getContext().getWorkManager().startWork("viewer.storage.load", (Work callback) -> {
|
getWorkManager().startWork("viewer.storage.load", (Work callback) -> {
|
||||||
callback.setTitle("Fill data to UI (" + root.getName() + ")");
|
callback.setTitle("Fill data to UI (" + root.getName() + ")");
|
||||||
callback.setProgress(-1);
|
callback.setProgress(-1);
|
||||||
Platform.runLater(() -> statusBar.setProgress(-1));
|
Platform.runLater(() -> statusBar.setProgress(-1));
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
package inr.numass.viewer;
|
package inr.numass.viewer;
|
||||||
|
|
||||||
import hep.dataforge.exceptions.StorageException;
|
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.NumassData;
|
||||||
import inr.numass.storage.NumassStorage;
|
import inr.numass.storage.NumassStorage;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
@ -22,7 +22,8 @@ package inr.numass.viewer;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import hep.dataforge.context.Context;
|
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.io.ColumnedDataWriter;
|
||||||
import hep.dataforge.meta.Meta;
|
import hep.dataforge.meta.Meta;
|
||||||
import hep.dataforge.meta.MetaBuilder;
|
import hep.dataforge.meta.MetaBuilder;
|
||||||
@ -211,10 +212,14 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WorkManager getWorkManager(){
|
||||||
|
return context.getPlugin(WorkManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
public void loadData(NumassData data) {
|
public void loadData(NumassData data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
if (data != null) {
|
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() + ")");
|
callback.setTitle("Load numass data (" + data.getName() + ")");
|
||||||
points = data.getNMPoints();
|
points = data.getNMPoints();
|
||||||
|
|
||||||
@ -239,7 +244,7 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupHVPane(Supplier<Table> hvData) {
|
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();
|
Table t = hvData.get();
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
@ -343,7 +348,7 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
|
|||||||
detectorPlot.removePlot();
|
detectorPlot.removePlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
context.getWorkManager().startWork("viewer.numass.load.detector", (Work callback) -> {
|
getWorkManager().startWork("viewer.numass.load.detector", (Work callback) -> {
|
||||||
Meta plottableConfig = new MetaBuilder("plot")
|
Meta plottableConfig = new MetaBuilder("plot")
|
||||||
.setValue("connectionType", "step")
|
.setValue("connectionType", "step")
|
||||||
.setValue("thickness", 2)
|
.setValue("thickness", 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user