diff --git a/numass-main/src/main/groovy/inr/numass/scripts/SimulatePileup.groovy b/numass-main/src/main/groovy/inr/numass/scripts/SimulatePileup.groovy index 4241b909..a4b20fed 100644 --- a/numass-main/src/main/groovy/inr/numass/scripts/SimulatePileup.groovy +++ b/numass-main/src/main/groovy/inr/numass/scripts/SimulatePileup.groovy @@ -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 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) - generator.loadSpectrum(point, reference, lowerChannel, upperChannel); + + 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); diff --git a/numass-main/src/main/java/inr/numass/Numass.java b/numass-main/src/main/java/inr/numass/Numass.java index 6c48bab1..87451a34 100644 --- a/numass-main/src/main/java/inr/numass/Numass.java +++ b/numass-main/src/main/java/inr/numass/Numass.java @@ -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(" "); diff --git a/numass-main/src/main/java/inr/numass/actions/ShowLossSpectrumAction.java b/numass-main/src/main/java/inr/numass/actions/ShowLossSpectrumAction.java index 9d9c3e57..d01ea222 100644 --- a/numass-main/src/main/java/inr/numass/actions/ShowLossSpectrumAction.java +++ b/numass-main/src/main/java/inr/numass/actions/ShowLossSpectrumAction.java @@ -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 { private static final String[] names = {"X", "exPos", "ionPos", "exW", "ionW", "exIonRatio"}; diff --git a/numass-main/src/main/java/inr/numass/utils/NMEventGenerator.java b/numass-main/src/main/java/inr/numass/utils/NMEventGenerator.java index d9401e7b..5b7aa3a3 100644 --- a/numass-main/src/main/java/inr/numass/utils/NMEventGenerator.java +++ b/numass-main/src/main/java/inr/numass/utils/NMEventGenerator.java @@ -68,10 +68,7 @@ public class NMEventGenerator implements Supplier { distribution = d; } - public void loadSpectrum(Map spectrum, int minChanel, int maxChanel) { - assert minChanel >= 0; - assert maxChanel <= RawNMPoint.MAX_CHANEL; - + public void loadSpectrum(Map 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 { 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 { distribution = new EnumeratedRealDistribution(chanels, values); } + protected NMEvent nextEvent(NMEvent prev) { short chanel; diff --git a/numass-main/src/main/java/inr/numass/utils/UnderflowCorrection.java b/numass-main/src/main/java/inr/numass/utils/UnderflowCorrection.java index fecfef25..358c4004 100644 --- a/numass-main/src/main/java/inr/numass/utils/UnderflowCorrection.java +++ b/numass-main/src/main/java/inr/numass/utils/UnderflowCorrection.java @@ -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 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 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 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]; + + return new MapPoint(pointNames,point.getUset(), a, sigma, a * sigma * Math.exp(xLow / sigma) / norm + 1d); } public Table fitAllPoints(Iterable data, int xLow, int xHigh, int upper, int binning) { - ListTable.Builder builder = new ListTable.Builder("U", "amp", "expConst", "correction"); + ListTable.Builder builder = new ListTable.Builder(pointNames); for (NMPoint point : data) { - 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); + builder.row(fitPoint(point,xLow,xHigh,upper,binning)); } return builder.build(); } diff --git a/numass-main/src/main/java/inr/numass/workbench/NumassWorkbenchController.java b/numass-main/src/main/java/inr/numass/workbench/NumassWorkbenchController.java deleted file mode 100644 index e04e64d5..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/NumassWorkbenchController.java +++ /dev/null @@ -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 contextFactory; - - List actionEditors = new ArrayList<>(); - MetaEditor dataEditor; - Context context; - - Configuration dataConfig; - Configuration actionsConfig; - - Map 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 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 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 oldItem, List 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 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 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); - } - -} diff --git a/numass-main/src/main/java/inr/numass/workbench/OutputTab.java b/numass-main/src/main/java/inr/numass/workbench/OutputTab.java deleted file mode 100644 index 50dd1d57..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/OutputTab.java +++ /dev/null @@ -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 Alexander Nozik - */ -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(); -} diff --git a/numass-main/src/main/java/inr/numass/workbench/PlotOutputTab.java b/numass-main/src/main/java/inr/numass/workbench/PlotOutputTab.java deleted file mode 100644 index f76cea94..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/PlotOutputTab.java +++ /dev/null @@ -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; - } - - - -} diff --git a/numass-main/src/main/java/inr/numass/workbench/StagePane.java b/numass-main/src/main/java/inr/numass/workbench/StagePane.java deleted file mode 100644 index 143ea20a..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/StagePane.java +++ /dev/null @@ -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 Alexander Nozik - */ -public class StagePane extends TabPane implements Named { - - private String name; - private final Map 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(); - } - -} diff --git a/numass-main/src/main/java/inr/numass/workbench/StagePaneHolder.java b/numass-main/src/main/java/inr/numass/workbench/StagePaneHolder.java deleted file mode 100644 index 166613a9..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/StagePaneHolder.java +++ /dev/null @@ -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 Alexander Nozik - */ -public interface StagePaneHolder { - StagePane getStagePane(String stageName); - void clearStage(String stageName); -} diff --git a/numass-main/src/main/java/inr/numass/workbench/TextOutputTab.java b/numass-main/src/main/java/inr/numass/workbench/TextOutputTab.java deleted file mode 100644 index f25d3560..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/TextOutputTab.java +++ /dev/null @@ -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 Alexander Nozik - */ -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(); - } - -} diff --git a/numass-main/src/main/java/inr/numass/workbench/Workbench.java b/numass-main/src/main/java/inr/numass/workbench/Workbench.java deleted file mode 100644 index 19795db0..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/Workbench.java +++ /dev/null @@ -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(); - } - -} diff --git a/numass-main/src/main/java/inr/numass/workbench/WorkbenchIOManager.java b/numass-main/src/main/java/inr/numass/workbench/WorkbenchIOManager.java deleted file mode 100644 index b5556b40..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/WorkbenchIOManager.java +++ /dev/null @@ -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 Alexander Nozik - */ -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())); - } - -} diff --git a/numass-main/src/main/java/inr/numass/workbench/WorkbenchUtils.java b/numass-main/src/main/java/inr/numass/workbench/WorkbenchUtils.java deleted file mode 100644 index b845281e..00000000 --- a/numass-main/src/main/java/inr/numass/workbench/WorkbenchUtils.java +++ /dev/null @@ -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 Alexander Nozik - */ -public class WorkbenchUtils { - -} diff --git a/numass-viewer/src/main/java/inr/numass/viewer/MainViewerController.java b/numass-viewer/src/main/java/inr/numass/viewer/MainViewerController.java index 860c8b60..d18300cc 100644 --- a/numass-viewer/src/main/java/inr/numass/viewer/MainViewerController.java +++ b/numass-viewer/src/main/java/inr/numass/viewer/MainViewerController.java @@ -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)); diff --git a/numass-viewer/src/main/java/inr/numass/viewer/NumassLoaderTreeBuilder.java b/numass-viewer/src/main/java/inr/numass/viewer/NumassLoaderTreeBuilder.java index 1c0afcf2..590d85e5 100644 --- a/numass-viewer/src/main/java/inr/numass/viewer/NumassLoaderTreeBuilder.java +++ b/numass-viewer/src/main/java/inr/numass/viewer/NumassLoaderTreeBuilder.java @@ -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; diff --git a/numass-viewer/src/main/java/inr/numass/viewer/NumassLoaderViewComponent.java b/numass-viewer/src/main/java/inr/numass/viewer/NumassLoaderViewComponent.java index 734561d1..aa73198b 100644 --- a/numass-viewer/src/main/java/inr/numass/viewer/NumassLoaderViewComponent.java +++ b/numass-viewer/src/main/java/inr/numass/viewer/NumassLoaderViewComponent.java @@ -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().>startWork("viewer.numass.load", (Work callback) -> { + getWorkManager().>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 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)