Update Value and State annotations

This commit is contained in:
Alexander Nozik 2017-05-31 22:11:14 +03:00
commit 900e249d5c
38 changed files with 729 additions and 873 deletions

View File

@ -1,11 +1,35 @@
buildscript {
ext.kotlin_version = '1.1.2-2'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects{
apply plugin: "kotlin"
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
javaParameters = true
}
}
}
dependencies {
compile project(':numass-client')
compile "hep.dataforge:plots-jfc" // project(':dataforge-plots:plots-jfc')
compile "hep.dataforge:dataforge-control" //project(':dataforge-control')
compile "hep.dataforge:kodex"
// https://mvnrepository.com/artifact/org.controlsfx/controlsfx
compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.12'
//graphics
compile 'org.controlsfx:controlsfx:8.40.12'
compile "no.tornado:tornadofx:1.7.4"
}
task installAll(type: Copy) {

View File

@ -1,9 +1,9 @@
plugins{
id "org.jetbrains.kotlin.jvm" version '1.1.2-2'
id "application"
id 'com.github.johnrengelman.shadow' version '2.0.0'
}
if (!hasProperty('mainClass')) {
ext.mainClass = 'inr.numass.control.ServerApp'//"inr.numass.viewer.test.TestApp"
}
@ -21,11 +21,6 @@ configurations{
}
dependencies {
//graphics
compile 'org.controlsfx:controlsfx:8.40.12'
compile "no.tornado:tornadofx:1.7.4"
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
//DataForge dependencies
compile project(':numass-control')
compile project(':numass-server')

View File

@ -1,12 +1,6 @@
package inr.numass.control
import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.Sensor
import hep.dataforge.fx.fragments.FXFragment
import hep.dataforge.fx.fragments.FragmentWindow
import hep.dataforge.storage.filestorage.FileStorage
import inr.numass.control.NumassControlUtils.getDFIcon
import javafx.geometry.Orientation
import javafx.geometry.Pos
import javafx.scene.control.Hyperlink
@ -17,7 +11,7 @@ import tornadofx.*
/**
* Created by darksnake on 11-May-17.
*/
class BoardView : View("Numass control board", ImageView(getDFIcon())) {
class BoardView : View("Numass control board", ImageView(dfIcon)) {
private val controller: BoardController by inject();
override val root = borderpane {
@ -87,23 +81,11 @@ class BoardView : View("Numass control board", ImageView(getDFIcon())) {
vbox {
prefHeight = 40.0
bindChildren(controller.devices) { connection ->
titledpane(title = "Device: " + connection.device.name, collapsible = true) {
hbox {
alignment = Pos.CENTER_LEFT
vgrow = Priority.ALWAYS;
deviceStateIndicator(connection, Device.INITIALIZED_STATE)
deviceStateIndicator(connection, PortSensor.CONNECTED_STATE)
deviceStateIndicator(connection, Sensor.MEASURING_STATE)
deviceStateIndicator(connection, "storing")
pane {
hgrow = Priority.ALWAYS
}
togglebutton("View") {
isSelected = false
FragmentWindow(FXFragment.buildFromNode(connection.device.name) { connection.fxNode }).bindTo(this)
}
}
}
titledpane(
title = "Device: " + connection.device.name,
collapsible = true,
node = connection.getBoardView()
)
}
}
}

View File

@ -16,7 +16,7 @@ dependencies {
task debug(dependsOn: classes, type: JavaExec) {
main mainClass
args "--config.resource=/config-debug/devices.xml"
args = ["--config.resource=/config-debug/devices.xml"]
classpath = sourceSets.main.runtimeClasspath
description "Start application in debug mode with default virtual port"
group "debug"
@ -24,7 +24,7 @@ task debug(dependsOn: classes, type: JavaExec) {
task testRun(dependsOn: classes, type: JavaExec) {
main mainClass
args(["--config=D:/temp/test/numass-devices.xml", "--device=thermo-1"])
args = ["--config=D:/temp/test/numass-devices.xml", "--device=thermo-1"]
classpath = sourceSets.main.runtimeClasspath
description "Start application using real device"
group "debug"

View File

@ -1,53 +0,0 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package inr.numass.control.cryotemp;
import hep.dataforge.control.devices.DeviceFactory;
import hep.dataforge.meta.Meta;
import inr.numass.control.DeviceViewConnection;
import inr.numass.control.NumassControlApplication;
import javafx.stage.Stage;
import java.util.Objects;
/**
* @author darksnake
*/
public class PKT8App extends NumassControlApplication<PKT8Device> {
@Override
protected DeviceViewConnection<PKT8Device> buildView(PKT8Device device) {
return PKT8View.build(device.getContext());
}
@Override
protected DeviceFactory getDeviceFactory() {
return new PKT8DeviceFactory();
}
@Override
protected void setupStage(Stage stage, PKT8Device device) {
stage.setTitle("Numass temperature view " + device.getName());
stage.setMinHeight(400);
stage.setMinWidth(400);
}
@Override
protected boolean acceptDevice(Meta meta) {
return Objects.equals(meta.getString("type"), "PKT8");
}
}

View File

@ -22,6 +22,6 @@ public class PKT8DeviceFactory implements DeviceViewFactory {
@Override
public DeviceViewConnection buildView(Device device) {
return PKT8View.build(device.getContext());
return new PKT8ViewConnection();
}
}

View File

@ -1,35 +0,0 @@
package inr.numass.control.cryotemp;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.fx.fragments.FXFragment;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import java.io.IOException;
/**
* Created by darksnake on 07-Oct-16.
*/
public class PKT8PlotFragment extends FXFragment {
private PKT8PlotView plotController;
public PKT8PlotFragment(PKT8Device device) {
super("PKT8 cryogenic temperature viewer", 600, 400);
try {
FXMLLoader loader = new FXMLLoader(device.getContext().getClassLoader().getResource("fxml/PKT8Plot.fxml"));
loader.setClassLoader(device.getContext().getClassLoader());
loader.load();
plotController = loader.getController();
device.connect(plotController, Roles.VIEW_ROLE);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected Parent buildRoot() {
return plotController.getPane();
}
}

View File

@ -1,144 +0,0 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package inr.numass.control.cryotemp;
import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.MeasurementListener;
import hep.dataforge.meta.Meta;
import hep.dataforge.plots.PlotUtils;
import hep.dataforge.plots.data.TimePlottable;
import hep.dataforge.plots.data.TimePlottableGroup;
import hep.dataforge.plots.fx.FXPlotFrame;
import hep.dataforge.plots.fx.PlotContainer;
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
import inr.numass.control.DeviceViewConnection;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import java.net.URL;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.ResourceBundle;
/**
* FXML Controller class
*
* @author darksnake
*/
public class PKT8PlotView extends DeviceViewConnection<PKT8Device> implements Initializable, MeasurementListener {
private FXPlotFrame plotFrame;
private TimePlottableGroup plottables;
@FXML
private BorderPane root;
@FXML
private ToggleButton rawDataButton;
@FXML
private AnchorPane plotArea;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
}
@Override
public void open(PKT8Device device) throws Exception {
super.open(device);
rawDataButton.selectedProperty().addListener(observable -> {
if (plotFrame != null) {
setupPlotFrame(plotFrame.getConfig());
if (device != null) {
setupChannels(device);
}
}
});
setupPlotFrame(device.meta().getMetaOrEmpty("plot.frame"));
setupChannels(device);
}
@Override
public void close() throws Exception {
super.close();
}
/**
* Set o reset plot area
*/
private synchronized void setupPlotFrame(Meta plotFrameMeta) {
plottables = new TimePlottableGroup();
plottables.setMaxAge(Duration.parse(plotFrameMeta.getString("maxAge", "PT2H")));
plotArea.getChildren().clear();
plotFrame = new JFreeChartFrame(plotFrameMeta);
PlotUtils.setXAxis(plotFrame, "timestamp", null, "time");
PlotContainer container = PlotContainer.anchorTo(plotArea);
container.setPlot(plotFrame);
}
private void setupChannels(PKT8Device device) {
Collection<PKT8Channel> channels = device.getChanels();
//plot config from device configuration
//Do not use view config here, it is applyed separately
channels.stream()
.filter(channel -> !plottables.has(channel.getName()))
.forEachOrdered(channel -> {
//plot config from device configuration
TimePlottable plottable = new TimePlottable(channel.getName());
plottable.configure(channel.meta());
plottables.add(plottable);
plotFrame.add(plottable);
});
if (device.meta().hasMeta("plotConfig")) {
plottables.applyConfig(device.meta().getMeta("plotConfig"));
plottables.setMaxItems(1000);
plottables.setPrefItems(400);
}
// getPlottables.applyConfig(plotFrame.getConfig());
}
@Override
public synchronized void onMeasurementResult(Measurement measurement, Object result, Instant time) {
PKT8Result res = PKT8Result.class.cast(result);
//PENDING replace by connection?
if (rawDataButton.isSelected()) {
plottables.put(res.channel, res.rawValue);
} else {
plottables.put(res.channel, res.temperature);
}
}
@Override
public void onMeasurementFailed(Measurement measurement, Throwable exception) {
}
@Override
public Node getFXNode() {
return root;
}
}

View File

@ -1,150 +0,0 @@
package inr.numass.control.cryotemp;
import hep.dataforge.context.Context;
import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.MeasurementListener;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.exceptions.MeasurementException;
import hep.dataforge.fx.fragments.FragmentWindow;
import hep.dataforge.fx.fragments.LogFragment;
import inr.numass.control.DeviceViewConnection;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.net.URL;
import java.time.Instant;
import java.util.Comparator;
import java.util.ResourceBundle;
/**
* Created by darksnake on 07-Oct-16.
*/
public class PKT8View extends DeviceViewConnection<PKT8Device> implements Initializable, MeasurementListener {
public static PKT8View build(Context context) {
try {
FXMLLoader loader = new FXMLLoader(context.getClassLoader().getResource("fxml/PKT8Indicator.fxml"));
loader.setClassLoader(context.getClassLoader());
loader.load();
return loader.getController();
} catch (IOException e) {
throw new Error(e);
}
}
private LogFragment logFragment;
private PKT8PlotFragment plotFragment;
@FXML
private BorderPane root;
@FXML
private ToggleButton startStopButton;
@FXML
private ToggleButton storeButton;
@FXML
private ToggleButton consoleButton;
@FXML
private ToggleButton plotButton;
@FXML
private Label lastUpdateLabel;
@FXML
private TableView<PKT8Result> table;
@FXML
private TableColumn<TableView<PKT8Result>, String> sensorColumn;
@FXML
private TableColumn<TableView<PKT8Result>, Double> resColumn;
@FXML
private TableColumn<TableView<PKT8Result>, String> tempColumn;
@Override
public void initialize(URL location, ResourceBundle resources) {
sensorColumn.setCellValueFactory(new PropertyValueFactory<>("channel"));
resColumn.setCellValueFactory(new PropertyValueFactory<>("rawString"));
tempColumn.setCellValueFactory(new PropertyValueFactory<>("temperatureString"));
}
@Override
public void open(@NotNull PKT8Device device) throws Exception {
super.open(device);
this.logFragment = new LogFragment();
logFragment.addRootLogHandler();
new FragmentWindow(logFragment).bindTo(consoleButton);
plotFragment = new PKT8PlotFragment(device);
startStopButton.selectedProperty().setValue(getDevice().isMeasuring());
new FragmentWindow(plotFragment).bindTo(plotButton);
bindBooleanToState("storing", storeButton.selectedProperty());
}
@Override
public void close() throws Exception {
super.close();
logFragment = null;
plotFragment = null;
}
@Override
public void onMeasurementResult(Measurement<?> measurement, Object result, Instant time) {
PKT8Result res = PKT8Result.class.cast(result);
Platform.runLater(() -> {
lastUpdateLabel.setText(time.toString());
table.getItems().removeIf(it -> it.channel.equals(res.channel));
table.getItems().add(res);
table.getItems().sort(Comparator.comparing(o -> o.channel));
});
}
@Override
public void onMeasurementFailed(Measurement measurement, Throwable exception) {
}
private void startMeasurement() throws MeasurementException {
getDevice().startMeasurement();
}
private void stopMeasurement() throws MeasurementException {
if (getDevice().isMeasuring()) {
getDevice().stopMeasurement(false);
}
}
@FXML
private void onStartStopClick(ActionEvent event) {
if (getDevice() != null) {
try {
if (startStopButton.isSelected()) {
startMeasurement();
} else {
//in case device started
stopMeasurement();
}
} catch (ControlException ex) {
getDevice().getLogger().error("Failed to start or stop device", ex);
}
}
}
@Override
public Node getFXNode() {
return root;
}
}

View File

@ -27,7 +27,7 @@ public class PKT8VirtualPort extends VirtualPort implements Metoid {
}
@Override
protected void evaluateRequest(String request) {
protected synchronized void evaluateRequest(String request) {
switch (request) {
case "s":
String[] letters = {"a", "b", "c", "d", "e", "f", "g", "h"};
@ -48,16 +48,15 @@ public class PKT8VirtualPort extends VirtualPort implements Metoid {
() -> {
double res = average + generator.nextGaussian() * sigma;
//TODO convert double value to formatted string
return letter + "000120000\n";
return String.format("%s000%d", letter, (int) (res * 100));
},
Duration.ZERO, Duration.ofMillis(200), letter, "measurement"
Duration.ZERO, Duration.ofMillis(500), letter, "measurement"
);
}
return;
case "p":
cancelByTag("measurement");
this.recievePhrase("stopped\n\r");
return;
this.receivePhrase("Stopped");
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package inr.numass.control.cryotemp
import hep.dataforge.control.connections.Roles
import hep.dataforge.control.devices.DeviceFactory
import hep.dataforge.meta.Meta
import inr.numass.control.DeviceViewConnection
import inr.numass.control.NumassControlApplication
import javafx.stage.Stage
/**
* @author darksnake
*/
class PKT8App : NumassControlApplication<PKT8Device>() {
override fun buildView(device: PKT8Device): DeviceViewConnection<PKT8Device> {
return PKT8ViewConnection().apply {
device.connect(this, Roles.VIEW_ROLE)
}
}
override val deviceFactory: DeviceFactory = PKT8DeviceFactory()
override fun setupStage(stage: Stage, device: PKT8Device) {
stage.title = "Numass temperature view " + device.name
stage.minHeight = 400.0
stage.minWidth = 400.0
}
override fun acceptDevice(meta: Meta): Boolean {
return meta.getString("type") == "PKT8"
}
}

View File

@ -14,32 +14,14 @@
* limitations under the License.
*/
package inr.numass.control.cryotemp;
package inr.numass.control.cryotemp
/**
* Created by darksnake on 28-Sep-16.
*/
public class PKT8Result {
data class PKT8Result(var channel: String, var rawValue: Double, var temperature: Double) {
public String channel;
public double rawValue;
public double temperature;
val rawString: String = String.format("%.2f", rawValue)
public PKT8Result(String channel, double rawValue, double temperature) {
this.channel = channel;
this.rawValue = rawValue;
this.temperature = temperature;
}
public String getChannel() {
return channel;
}
public String getRawString() {
return String.format("%.2f", rawValue);
}
public String getTemperatureString() {
return String.format("%.2f", temperature);
}
val temperatureString: String = String.format("%.2f", temperature)
}

View File

@ -0,0 +1,224 @@
package inr.numass.control.cryotemp
import hep.dataforge.control.devices.Sensor
import hep.dataforge.control.measurements.Measurement
import hep.dataforge.control.measurements.MeasurementListener
import hep.dataforge.fx.fragments.FXFragment
import hep.dataforge.fx.fragments.FragmentWindow
import hep.dataforge.fx.fragments.LogFragment
import hep.dataforge.meta.Meta
import hep.dataforge.plots.PlotUtils
import hep.dataforge.plots.data.TimePlottable
import hep.dataforge.plots.data.TimePlottableGroup
import hep.dataforge.plots.fx.FXPlotFrame
import hep.dataforge.plots.fx.PlotContainer
import hep.dataforge.plots.jfreechart.JFreeChartFrame
import inr.numass.control.DeviceViewConnection
import javafx.application.Platform
import javafx.beans.binding.ListBinding
import javafx.beans.property.SimpleObjectProperty
import javafx.collections.FXCollections
import javafx.collections.MapChangeListener
import javafx.collections.ObservableList
import javafx.geometry.Orientation
import javafx.scene.Node
import javafx.scene.Parent
import javafx.scene.control.ToggleButton
import javafx.scene.layout.Priority
import javafx.scene.layout.VBox
import javafx.scene.text.Font
import tornadofx.*
import java.time.Duration
import java.time.Instant
/**
* Created by darksnake on 30-May-17.
*/
class PKT8ViewConnection : DeviceViewConnection<PKT8Device>(), MeasurementListener {
private val cryoView by lazy { CryoView() }
private val plotView by lazy { CryoPlotView() }
internal val table = FXCollections.observableHashMap<String, PKT8Result>()
val lastUpdateProperty = SimpleObjectProperty<String>("NEVER")
override fun getBoardView(): Parent {
return VBox().apply {
this += super.getBoardView()
}
}
override fun getFXNode(): Node {
if (!isOpen) {
throw RuntimeException("Not connected!")
}
return cryoView.root;
}
override fun onMeasurementFailed(measurement: Measurement<*>, exception: Throwable) {
}
override fun onMeasurementResult(measurement: Measurement<*>, result: Any, time: Instant) {
if (result is PKT8Result) {
Platform.runLater {
lastUpdateProperty.set(time.toString())
table.put(result.channel, result);
}
}
}
inner class CryoView() : View() {
private var plotButton: ToggleButton by singleAssign()
private var logButton: ToggleButton by singleAssign()
private val logWindow = FragmentWindow(LogFragment().apply {
addLogHandler(device.logger)
})
// need those to have strong references to listeners
private val plotView = CryoPlotView();
private val plotWindow = FragmentWindow(FXFragment.buildFromNode(plotView.title) { plotView.root })
override val root = borderpane {
top {
toolbar {
togglebutton("Measure") {
isSelected = false
bindBooleanToState(Sensor.MEASURING_STATE, selectedProperty())
}
togglebutton("Store") {
isSelected = false
bindBooleanToState("storing", selectedProperty())
}
separator(Orientation.VERTICAL)
pane {
hgrow = Priority.ALWAYS
}
separator(Orientation.VERTICAL)
plotButton = togglebutton("Plot") {
isSelected = false
plotWindow.bindTo(this)
}
logButton = togglebutton("Log") {
isSelected = false
logWindow.bindTo(this)
}
}
}
center {
tableview<PKT8Result> {
items = object : ListBinding<PKT8Result>() {
init {
bind(table)
}
override fun computeValue(): ObservableList<PKT8Result> {
return FXCollections.observableArrayList(table.values).apply {
sortBy { it.channel }
}
}
}
column("Sensor", PKT8Result::channel);
column("Resistance", PKT8Result::rawValue).cellFormat {
text = String.format("%.2f", it)
}
column("Temperature", PKT8Result::temperature).cellFormat {
text = String.format("%.2f", it)
}
}
}
bottom {
toolbar {
label("Last update: ")
label(lastUpdateProperty) {
font = Font.font("System Bold")
}
}
}
}
}
inner class CryoPlotView : View("PKT8 temperature plot") {
val plotFrameMeta: Meta = device.meta.getMetaOrEmpty("plotConfig")
val plotFrame: FXPlotFrame by lazy {
JFreeChartFrame(plotFrameMeta).apply {
PlotUtils.setXAxis(this, "timestamp", null, "time")
}
}
var rawDataButton: ToggleButton by singleAssign()
val plottables: TimePlottableGroup by lazy {
TimePlottableGroup().apply {
setMaxAge(Duration.parse(plotFrameMeta.getString("maxAge", "PT2H")))
}
}
override val root: Parent = borderpane {
prefWidth = 800.0
prefHeight = 600.0
PlotContainer.centerIn(this).plot = plotFrame
top {
toolbar {
rawDataButton = togglebutton("Raw data") {
isSelected = false
action {
clearPlot()
}
}
button("Reset") {
action {
clearPlot()
}
}
}
}
}
init {
val channels = device.chanels
//plot config from device configuration
//Do not use view config here, it is applyed separately
channels.stream()
.filter { channel -> !plottables.has(channel.name) }
.forEachOrdered { channel ->
//plot config from device configuration
val plottable = TimePlottable(channel.name)
plottable.configure(channel.meta())
plottables.add(plottable)
plotFrame.add(plottable)
}
if (device.meta().hasMeta("plotConfig")) {
plottables.applyConfig(device.meta().getMeta("plotConfig"))
plottables.setMaxItems(1000)
plottables.setPrefItems(400)
}
table.addListener(MapChangeListener { change ->
if (change.wasAdded()) {
change.valueAdded.apply {
if (rawDataButton.isSelected()) {
plottables.put(this.channel, this.rawValue)
} else {
plottables.put(this.channel, this.temperature)
}
}
}
})
}
fun clearPlot() {
plottables.forEach {
it.clear()
}
}
}
}

View File

@ -4,7 +4,7 @@
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<BorderPane fx:id="root" xmlns:fx="http://javafx.com/fxml/1" prefHeight="400.0" prefWidth="400.0"
xmlns="http://javafx.com/javafx/8.0.111" fx:controller="inr.numass.control.cryotemp.PKT8View">
xmlns="http://javafx.com/javafx/8.0.111" fx:controller="inr.numass.control.cryotemp.PKT8ViewConnection">
<center>
<TableView fx:id="table" BorderPane.alignment="CENTER">
<columns>
@ -31,14 +31,12 @@
</top>
<bottom>
<ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<items>
<Label text="Last update: "/>
<Label fx:id="lastUpdateLabel" text="NONE">
<font>
<Font name="System Bold" size="12.0"/>
</font>
</Label>
</items>
<Label text="Last update: "/>
<Label fx:id="lastUpdateLabel" text="NONE">
<font>
<Font name="System Bold" size="12.0"/>
</font>
</Label>
</ToolBar>
</bottom>
</BorderPane>

View File

@ -27,12 +27,10 @@ limitations under the License.
</center>
<top>
<ToolBar BorderPane.alignment="CENTER">
<items>
<ToggleButton fx:id="rawDataButton" mnemonicParsing="false" text="Raw data"/>
<Separator orientation="VERTICAL"/>
<Pane HBox.hgrow="ALWAYS"/>
<Separator orientation="VERTICAL"/>
</items>
<ToggleButton fx:id="rawDataButton" mnemonicParsing="false" text="Raw data"/>
<Separator orientation="VERTICAL"/>
<Pane HBox.hgrow="ALWAYS"/>
<Separator orientation="VERTICAL"/>
</ToolBar>
</top>
</BorderPane>

View File

@ -18,10 +18,11 @@ package inr.numass.control.magnet;
import hep.dataforge.control.ports.VirtualPort;
import hep.dataforge.exceptions.PortException;
import hep.dataforge.meta.Meta;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.LoggerFactory;
/**
*
@ -69,7 +70,7 @@ public class VirtualLambdaPort extends VirtualPort {
evaluateRequest(comand.trim(), value.trim());
} catch (RuntimeException ex) {
recievePhrase("FAIL");//TODO какая команда правильная?
receivePhrase("FAIL");//TODO какая команда правильная?
LoggerFactory.getLogger(getClass()).error("Request evaluation failure", ex);
}

View File

@ -49,7 +49,7 @@ public class MagnetControllerApp extends Application {
List<SafeMagnetController> controllers = new ArrayList<>();
@Override
public void start(Stage primaryStage) throws IOException, ControlException {
public void start(Stage stage) throws IOException, ControlException {
Locale.setDefault(Locale.US);// чтобы отделение десятичных знаков было точкой
ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
@ -108,10 +108,10 @@ public class MagnetControllerApp extends Application {
Scene scene = new Scene(vbox, width, height);
primaryStage.setTitle("Numass magnet view");
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
stage.setTitle("Numass magnet view");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
}
@Override

View File

@ -1,31 +0,0 @@
package inr.numass.control;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceListener;
import hep.dataforge.fx.fragments.FXFragment;
import javafx.scene.Parent;
/**
* Created by darksnake on 20-Oct-16.
*/
public abstract class DeviceFragment<T extends Device> extends FXFragment implements DeviceListener {
private final T device;
protected DeviceFragment(T device) {
this.device = device;
}
@Override
protected Parent buildRoot() {
return buildRoot(device);
}
protected abstract Parent buildRoot(T device);
@Override
public void evaluateDeviceException(Device device, String message, Throwable exception) {
//do something pretty
}
}

View File

@ -1,72 +0,0 @@
package inr.numass.control;
import hep.dataforge.control.connections.DeviceConnection;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceListener;
import hep.dataforge.fx.FXObject;
import hep.dataforge.values.Value;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.BooleanProperty;
import java.util.HashMap;
import java.util.Map;
/**
* Created by darksnake on 14-May-17.
*/
public abstract class DeviceViewConnection<D extends Device> extends DeviceConnection<D> implements DeviceListener, FXObject {
private Map<String, ObjectBinding<Value>> bindings = new HashMap<>();
/**
* Get binding for a given device state
*
* @param state
* @return
*/
public ObjectBinding<Value> getStateBinding(String state) {
return bindings.computeIfAbsent(state, stateName ->
new ObjectBinding<Value>() {
@Override
protected Value computeValue() {
if(isOpen()) {
return getDevice().getState(stateName);
} else {
return Value.NULL;
}
}
}
);
}
/**
* Bind existing boolean property to writable device state
*
* @param state
* @param property
*/
protected void bindBooleanToState(String state, BooleanProperty property) {
getStateBinding(state).addListener((observable, oldValue, newValue) -> {
if (isOpen() && oldValue != newValue) {
property.setValue(newValue.booleanValue());
}
});
property.addListener((observable, oldValue, newValue) -> {
if (isOpen() && oldValue != newValue) {
getDevice().setState(state, newValue);
}
});
}
@Override
public void notifyDeviceStateChanged(Device device, String name, Value state) {
if (bindings.containsKey(name)) {
bindings.get(name).invalidate();
}
}
// /**
// * The small view for
// * @return
// */
// public abstract Optional<Parent> getBoardView();
}

View File

@ -1,12 +0,0 @@
package inr.numass.control;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceFactory;
public interface DeviceViewFactory extends DeviceFactory {
/**
* Create but do not connect view connection for the device
* @return
*/
DeviceViewConnection buildView(Device device);
}

View File

@ -1,94 +0,0 @@
package inr.numass.control;
import ch.qos.logback.classic.Level;
import hep.dataforge.context.Context;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceFactory;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.meta.Meta;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.slf4j.LoggerFactory;
import java.util.Locale;
/**
* Created by darksnake on 14-May-17.
*/
public abstract class NumassControlApplication<D extends Device> extends Application {
private D device;
@Override
public void start(Stage primaryStage) throws Exception {
Locale.setDefault(Locale.US);// чтобы отделение десятичных знаков было точкой
ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(Level.INFO);
device = setupDevice();
DeviceViewConnection<D> controller = buildView(device);
Scene scene = new Scene(controller.getPane());
primaryStage.setScene(scene);
Platform.runLater(() -> {
device.connect(controller, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE);
});
primaryStage.show();
setupStage(primaryStage, device);
NumassControlUtils.setDFStageIcon(primaryStage);
}
/**
* Build a view connection
*
* @return
*/
protected abstract DeviceViewConnection<D> buildView(D device);
/**
* Get a device factory for given device
*
* @return
*/
protected abstract DeviceFactory getDeviceFactory();
protected abstract void setupStage(Stage stage, D device);
protected abstract boolean acceptDevice(Meta meta);
private D setupDevice() {
Meta config = NumassControlUtils.getConfig(this)
.orElseGet(() -> NumassControlUtils.readResourceMeta("/config/devices.xml"));
Context ctx = NumassControlUtils.setupContext(config);
Meta deviceConfig = NumassControlUtils.findDeviceMeta(config, this::acceptDevice)
.orElseThrow(() -> new RuntimeException("Device configuration not found"));
try {
@SuppressWarnings("unchecked") D d = (D) getDeviceFactory().build(ctx, deviceConfig);
d.init();
NumassControlUtils.connectStorage(d, config);
return d;
} catch (ControlException e) {
throw new RuntimeException("Failed to build device", e);
}
}
@Override
public void stop() throws Exception {
super.stop();
if (device != null) {
device.shutdown();
device.getContext().close();
}
}
}

View File

@ -1,115 +0,0 @@
package inr.numass.control;
import hep.dataforge.context.Context;
import hep.dataforge.context.Global;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.connections.StorageConnection;
import hep.dataforge.control.devices.Device;
import hep.dataforge.exceptions.StorageException;
import hep.dataforge.io.MetaFileReader;
import hep.dataforge.io.XMLMetaReader;
import hep.dataforge.meta.Meta;
import hep.dataforge.storage.api.Storage;
import hep.dataforge.storage.commons.StorageFactory;
import hep.dataforge.storage.commons.StorageManager;
import inr.numass.client.ClientUtils;
import javafx.application.Application;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.Optional;
import java.util.function.Predicate;
/**
* Created by darksnake on 08-May-17.
*/
public class NumassControlUtils {
public static final String DEFAULT_CONFIG_LOCATION = "./numass-control.xml";
/**
* Create a single or multiple storage connections for a device
*
* @param device
* @param config
*/
public static void connectStorage(Device device, Meta config) {
//TODO add on reset listener
if (config.hasMeta("storage") && device.acceptsRole(Roles.STORAGE_ROLE)) {
String numassRun = ClientUtils.getRunName(config);
config.getMetaList("storage").forEach(node -> {
device.getContext().getLogger().info("Creating storage for device with meta: {}", node);
//building storage in a separate thread
new Thread(() -> {
Storage storage = StorageFactory.buildStorage(device.getContext(), node);
if (!numassRun.isEmpty()) {
try {
storage = storage.buildShelf(numassRun, Meta.empty());
} catch (StorageException e) {
device.getContext().getLogger().error("Failed to build shelf", e);
}
}
device.connect(new StorageConnection(storage), Roles.STORAGE_ROLE);
}).start();
});
}
}
public static Meta readResourceMeta(String path) {
try {
return new XMLMetaReader().read(NumassControlUtils.class.getResourceAsStream(path));
} catch (IOException | ParseException e) {
throw new RuntimeException(e);
}
}
public static Optional<Meta> getConfig(Application app) {
String debugConfig = app.getParameters().getNamed().get("config.resource");
if (debugConfig != null) {
return Optional.ofNullable(readResourceMeta(debugConfig));
}
String configFileName = app.getParameters().getNamed().get("config");
Logger logger = LoggerFactory.getLogger(app.getClass());
if (configFileName == null) {
logger.info("Configuration path not defined. Loading configuration from {}", DEFAULT_CONFIG_LOCATION);
configFileName = DEFAULT_CONFIG_LOCATION;
}
File configFile = new File(configFileName);
if (configFile.exists()) {
try {
Meta config = MetaFileReader.read(configFile).build();
return Optional.of(config);
} catch (IOException | ParseException e) {
throw new RuntimeException(e);
}
} else {
logger.warn("Configuration file not found");
return Optional.empty();
}
}
public static Optional<Meta> findDeviceMeta(Meta config, Predicate<Meta> criterion) {
return config.getMetaList("device").stream().filter(criterion).findFirst().map(it -> it);
}
public static Context setupContext(Meta meta) {
Context ctx = Global.getContext("NUMASS-CONTROL");
ctx.pluginManager().getOrLoad(StorageManager.class);
return ctx;
}
public static void setDFStageIcon(Stage stage) {
stage.getIcons().add(getDFIcon());
}
public static Image getDFIcon(){
return new Image(NumassControlUtils.class.getResourceAsStream("/img/df.png"));
}
}

View File

@ -1,51 +0,0 @@
package inr.numass.control;
import hep.dataforge.control.connections.StorageConnection;
import hep.dataforge.control.devices.AbstractDevice;
import hep.dataforge.exceptions.StorageException;
import hep.dataforge.storage.api.PointLoader;
import hep.dataforge.tables.DataPoint;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* A helper to store points in multiple loaders
* Created by darksnake on 16-May-17.
*/
public class StorageHelper implements AutoCloseable {
private final AbstractDevice device;
private final Map<StorageConnection, PointLoader> loaderMap = new HashMap<>();
private final Function<StorageConnection, PointLoader> loaderFactory;
public StorageHelper(AbstractDevice device, Function<StorageConnection, PointLoader> loaderFactory) {
this.device = device;
this.loaderFactory = loaderFactory;
}
public void push(DataPoint point) {
if (!device.hasState("storing") || device.getState("storing").booleanValue()) {
device.forEachConnection("storage", StorageConnection.class, connection -> {
PointLoader pl = loaderMap.computeIfAbsent(connection, loaderFactory);
try {
pl.push(point);
} catch (StorageException ex) {
device.getLogger().error("Push to loader failed", ex);
}
});
}
}
@Override
public void close() {
loaderMap.values().forEach(it -> {
try {
it.close();
} catch (Exception ex) {
device.getLogger().error("Failed to close Loader", ex);
}
});
}
}

View File

@ -0,0 +1,89 @@
package inr.numass.control
import hep.dataforge.control.connections.DeviceConnection
import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.DeviceListener
import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.Sensor
import hep.dataforge.fx.FXObject
import hep.dataforge.fx.fragments.FXFragment
import hep.dataforge.fx.fragments.FragmentWindow
import hep.dataforge.values.Value
import javafx.beans.binding.ObjectBinding
import javafx.beans.property.BooleanProperty
import javafx.geometry.Pos
import javafx.scene.Parent
import javafx.scene.layout.HBox
import javafx.scene.layout.Priority
import tornadofx.*
import java.util.*
/**
* Created by darksnake on 14-May-17.
*/
abstract class DeviceViewConnection<D : Device> : DeviceConnection<D>(), DeviceListener, FXObject {
private val bindings = HashMap<String, ObjectBinding<Value>>()
/**
* Get binding for a given device state
* @param state
* *
* @return
*/
fun getStateBinding(state: String): ObjectBinding<Value> {
return bindings.computeIfAbsent(state) { stateName ->
object : ObjectBinding<Value>() {
override fun computeValue(): Value {
if (isOpen) {
return device.getState(stateName)
} else {
return Value.NULL
}
}
}
}
}
/**
* Bind existing boolean property to writable device state
* @param state
* *
* @param property
*/
protected fun bindBooleanToState(state: String, property: BooleanProperty) {
getStateBinding(state).addListener { observable, oldValue, newValue ->
if (isOpen && oldValue !== newValue) {
property.value = newValue.booleanValue()
}
}
property.addListener { observable, oldValue, newValue ->
if (isOpen && oldValue != newValue) {
device.setState(state, newValue)
}
}
}
override fun notifyDeviceStateChanged(device: Device, name: String, state: Value) {
bindings[name]?.invalidate()
}
open fun getBoardView(): Parent {
return HBox().apply {
alignment = Pos.CENTER_LEFT
vgrow = Priority.ALWAYS;
deviceStateIndicator(this@DeviceViewConnection, Device.INITIALIZED_STATE)
deviceStateIndicator(this@DeviceViewConnection, PortSensor.CONNECTED_STATE)
deviceStateIndicator(this@DeviceViewConnection, Sensor.MEASURING_STATE)
deviceStateIndicator(this@DeviceViewConnection, "storing")
pane {
hgrow = Priority.ALWAYS
}
togglebutton("View") {
isSelected = false
FragmentWindow(FXFragment.buildFromNode(device.name) { fxNode }).bindTo(this)
}
}
}
}

View File

@ -0,0 +1,12 @@
package inr.numass.control
import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.DeviceFactory
interface DeviceViewFactory : DeviceFactory {
/**
* Create but do not connect view connection for the device
* @return
*/
fun buildView(device: Device): DeviceViewConnection<*>
}

View File

@ -95,4 +95,4 @@ fun EventTarget.deviceStateIndicator(connection: DeviceViewConnection<*>, state:
}
separator(Orientation.VERTICAL)
}
}
}

View File

@ -0,0 +1,94 @@
package inr.numass.control
import ch.qos.logback.classic.Level
import hep.dataforge.control.connections.Roles
import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.DeviceFactory
import hep.dataforge.exceptions.ControlException
import hep.dataforge.meta.Meta
import javafx.application.Platform
import javafx.scene.Scene
import javafx.stage.Stage
import org.slf4j.LoggerFactory
import tornadofx.*
import java.util.*
import java.util.function.Predicate
/**
* Created by darksnake on 14-May-17.
*/
abstract class NumassControlApplication<D : Device> : App() {
private var device: D by singleAssign()
override fun start(stage: Stage) {
Locale.setDefault(Locale.US)// чтобы отделение десятичных знаков было точкой
val rootLogger = LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME) as ch.qos.logback.classic.Logger
rootLogger.level = Level.INFO
device = setupDevice()
val controller = buildView(device)
val scene = Scene(controller.pane)
stage.scene = scene
Platform.runLater { device.connect(controller, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE) }
stage.show()
setupStage(stage, device)
setDFStageIcon(stage)
}
/**
* Build a view connection
* @return
*/
protected abstract fun buildView(device: D): DeviceViewConnection<D>
/**
* Get a device factory for given device
* @return
*/
protected abstract val deviceFactory: DeviceFactory
protected abstract fun setupStage(stage: Stage, device: D)
protected abstract fun acceptDevice(meta: Meta): Boolean
private fun setupDevice(): D {
val config = getConfig(this)
.orElseGet { readResourceMeta("/config/devices.xml") }
val ctx = setupContext(config)
val deviceConfig = findDeviceMeta(config, Predicate<Meta> { this.acceptDevice(it) })
.orElseThrow { RuntimeException("Device configuration not found") }
try {
@Suppress("UNCHECKED_CAST")
val d = deviceFactory.build(ctx, deviceConfig) as D
d.init()
connectStorage(d, config)
return d
} catch (e: ControlException) {
throw RuntimeException("Failed to build device", e)
}
}
override fun stop() {
try {
device.shutdown()
} catch (ex: Exception) {
LoggerFactory.getLogger(javaClass).error("Failed to shutdown application", ex);
} finally {
device.context.close()
super.stop()
}
}
}

View File

@ -0,0 +1,117 @@
package inr.numass.control
import hep.dataforge.context.Context
import hep.dataforge.context.Global
import hep.dataforge.control.connections.Roles
import hep.dataforge.control.connections.StorageConnection
import hep.dataforge.control.devices.Device
import hep.dataforge.exceptions.StorageException
import hep.dataforge.io.MetaFileReader
import hep.dataforge.io.XMLMetaReader
import hep.dataforge.meta.Meta
import hep.dataforge.storage.commons.StorageFactory
import hep.dataforge.storage.commons.StorageManager
import inr.numass.client.ClientUtils
import javafx.application.Application
import javafx.scene.image.Image
import javafx.stage.Stage
import org.slf4j.LoggerFactory
import java.io.File
import java.io.IOException
import java.text.ParseException
import java.util.*
import java.util.function.Predicate
/**
* Created by darksnake on 08-May-17.
*/
val DEFAULT_CONFIG_LOCATION = "./numass-control.xml"
val dfIcon: Image = Image(Global::class.java.getResourceAsStream("/img/df.png"))
/**
* Create a single or multiple storage connections for a device
* @param device
* *
* @param config
*/
fun connectStorage(device: Device, config: Meta) {
//TODO add on reset listener
if (config.hasMeta("storage") && device.acceptsRole(Roles.STORAGE_ROLE)) {
val numassRun = ClientUtils.getRunName(config)
config.getMetaList("storage").forEach { node ->
device.context.logger.info("Creating storage for device with meta: {}", node)
//building storage in a separate thread
Thread {
var storage = StorageFactory.buildStorage(device.context, node)
if (!numassRun.isEmpty()) {
try {
storage = storage.buildShelf(numassRun, Meta.empty())
} catch (e: StorageException) {
device.context.logger.error("Failed to build shelf", e)
}
}
device.connect(StorageConnection(storage), Roles.STORAGE_ROLE)
}.start()
}
}
}
fun readResourceMeta(path: String): Meta {
try {
return XMLMetaReader().read(Global::class.java.getResourceAsStream(path))
} catch (e: IOException) {
throw RuntimeException(e)
} catch (e: ParseException) {
throw RuntimeException(e)
}
}
fun getConfig(app: Application): Optional<Meta> {
val debugConfig = app.parameters.named["config.resource"]
if (debugConfig != null) {
return Optional.ofNullable(readResourceMeta(debugConfig))
}
var configFileName: String? = app.parameters.named["config"]
val logger = LoggerFactory.getLogger(app.javaClass)
if (configFileName == null) {
logger.info("Configuration path not defined. Loading configuration from {}", DEFAULT_CONFIG_LOCATION)
configFileName = DEFAULT_CONFIG_LOCATION
}
val configFile = File(configFileName)
if (configFile.exists()) {
try {
val config = MetaFileReader.read(configFile).build()
return Optional.of(config)
} catch (e: IOException) {
throw RuntimeException(e)
} catch (e: ParseException) {
throw RuntimeException(e)
}
} else {
logger.warn("Configuration file not found")
return Optional.empty<Meta>()
}
}
fun findDeviceMeta(config: Meta, criterion: Predicate<Meta>): Optional<Meta> {
return config.getMetaList("device").stream().filter(criterion).findFirst().map { it -> it }
}
fun setupContext(meta: Meta): Context {
val ctx = Global.getContext("NUMASS-CONTROL")
ctx.pluginManager().getOrLoad(StorageManager::class.java)
return ctx
}
fun setDFStageIcon(stage: Stage) {
stage.icons.add(dfIcon)
}

View File

@ -0,0 +1,41 @@
package inr.numass.control
import hep.dataforge.control.connections.StorageConnection
import hep.dataforge.control.devices.AbstractDevice
import hep.dataforge.exceptions.StorageException
import hep.dataforge.storage.api.PointLoader
import hep.dataforge.tables.DataPoint
import java.util.*
import java.util.function.Function
/**
* A helper to store points in multiple loaders
* Created by darksnake on 16-May-17.
*/
class StorageHelper(private val device: AbstractDevice, private val loaderFactory: Function<StorageConnection, PointLoader>) : AutoCloseable {
private val loaderMap = HashMap<StorageConnection, PointLoader>()
fun push(point: DataPoint) {
if (!device.hasState("storing") || device.getState("storing").booleanValue()) {
device.forEachConnection("storage", StorageConnection::class.java) { connection ->
val pl = loaderMap.computeIfAbsent(connection, loaderFactory)
try {
pl.push(point)
} catch (ex: StorageException) {
device.logger.error("Push to loader failed", ex)
}
}
}
}
override fun close() {
loaderMap.values.forEach { it ->
try {
it.close()
} catch (ex: Exception) {
device.logger.error("Failed to close Loader", ex)
}
}
}
}

View File

@ -25,7 +25,7 @@ public class TestVac extends Application {
VacCollectorView controller;
@Override
public void start(Stage primaryStage) {
public void start(Stage stage) {
try {
Sensor<Double> sensor1 = Virtual.randomDoubleSensor("vac1", Duration.ofMillis(200), 1e-5, 2e-6);
Sensor<Double> sensor2 = Virtual.randomDoubleSensor("vac2", Duration.ofMillis(200), 2e-5, 2e-6);
@ -65,9 +65,9 @@ public class TestVac extends Application {
Scene scene = new Scene(loader.getRoot(), 800, 600);
primaryStage.setTitle("Vacuum measurement test");
primaryStage.setScene(scene);
primaryStage.show();
stage.setTitle("Vacuum measurement test");
stage.setScene(scene);
stage.show();
} catch (Exception ex) {
throw new Error(ex);
}

View File

@ -28,15 +28,17 @@ import inr.numass.debunch.FrameAnalizer;
import java.io.PrintWriter;
import static hep.dataforge.values.ValueType.NUMBER;
/**
* @author Darksnake
*/
@TypedActionDef(name = "debunch", inputType = RawNMFile.class, outputType = RawNMFile.class)
@ValueDef(name = "upperchanel", type = "NUMBER", def = "4095", info = "An upper chanel for debuncing")
@ValueDef(name = "lowerchanel", type = "NUMBER", def = "0", info = "A lower chanel for debuncing")
@ValueDef(name = "rejectprob", type = "NUMBER", def = "1e-5", info = "Rejection probability")
@ValueDef(name = "framelength", type = "NUMBER", def = "5", info = "Frame length in seconds")
@ValueDef(name = "maxcr", type = "NUMBER", def = "100", info = "Maximum count rate for debunching")
@ValueDef(name = "upperchanel", type = {NUMBER}, def = "4095", info = "An upper chanel for debuncing")
@ValueDef(name = "lowerchanel", type = {NUMBER}, def = "0", info = "A lower chanel for debuncing")
@ValueDef(name = "rejectprob", type = {NUMBER}, def = "1e-5", info = "Rejection probability")
@ValueDef(name = "framelength", type = {NUMBER}, def = "5", info = "Frame length in seconds")
@ValueDef(name = "maxcr", type = {NUMBER}, def = "100", info = "Maximum count rate for debunching")
public class DebunchAction extends OneToOneAction<RawNMFile, RawNMFile> {
@Override

View File

@ -37,11 +37,13 @@ import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.CopyOnWriteArrayList;
import static hep.dataforge.values.ValueType.NUMBER;
/**
* @author Darksnake
*/
@TypedActionDef(name = "monitor", inputType = Table.class, outputType = Table.class)
@ValueDef(name = "monitorPoint", type = "NUMBER", required = true, info = "The Uset for monitor point")
@ValueDef(name = "monitorPoint", type = {NUMBER}, required = true, info = "The Uset for monitor point")
@ValueDef(name = "monitorFile", info = "The outputfile for monitor points", def = "monitor.onComplete")
@ValueDef(name = "calculateRelative", info = "Calculate count rate relative to average monitor point", def = "false")
public class MonitorCorrectAction extends OneToOneAction<Table, Table> {

View File

@ -44,16 +44,18 @@ import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import static hep.dataforge.values.ValueType.NUMBER;
import static hep.dataforge.values.ValueType.STRING;
import static inr.numass.utils.TritiumUtils.pointExpression;
/**
* @author Darksnake
*/
@TypedActionDef(name = "prepareData", inputType = NumassData.class, outputType = Table.class)
@ValueDef(name = "lowerWindow", type = "NUMBER", def = "0", info = "Base for the window lowerWindow bound")
@ValueDef(name = "lowerWindowSlope", type = "NUMBER", def = "0", info = "Slope for the window lowerWindow bound")
@ValueDef(name = "upperWindow", type = "NUMBER", info = "Upper bound for window")
@ValueDef(name = "deadTime", type = "[NUMBER, STRING]", info = "Dead time in s. Could be an expression.")
@ValueDef(name = "lowerWindow", type = {NUMBER}, def = "0", info = "Base for the window lowerWindow bound")
@ValueDef(name = "lowerWindowSlope", type = {NUMBER}, def = "0", info = "Slope for the window lowerWindow bound")
@ValueDef(name = "upperWindow", type = {NUMBER}, info = "Upper bound for window")
@ValueDef(name = "deadTime", type = {NUMBER, STRING}, info = "Dead time in s. Could be an expression.")
@ValueDef(name = "correction",
info = "An expression to correct count number depending on potential `U`, point length `T` and point itself as `point`")
@ValueDef(name = "utransform", info = "Expression for voltage transformation. Uses U as input")
@ -103,9 +105,9 @@ public class PrepareDataAction extends OneToOneAction<NumassData, Table> {
utransform = Function.identity();
}
if(meta.hasMeta("debunch")){
if(dataFile instanceof NumassDataLoader){
dataFile = ((NumassDataLoader) dataFile).applyRawTransformation(raw->debunch(context,raw,meta.getMeta("debunch")));
if (meta.hasMeta("debunch")) {
if (dataFile instanceof NumassDataLoader) {
dataFile = ((NumassDataLoader) dataFile).applyRawTransformation(raw -> debunch(context, raw, meta.getMeta("debunch")));
} else {
throw new RuntimeException("Debunch not available");
}
@ -173,8 +175,8 @@ public class PrepareDataAction extends OneToOneAction<NumassData, Table> {
}
@ValueDef(name = "value", type = "[NUMBER, STRING]", info = "Value or function to multiply count rate")
@ValueDef(name = "err", type = "[NUMBER, STRING]", info = "error of the value")
@ValueDef(name = "value", type = {NUMBER, STRING}, info = "Value or function to multiply count rate")
@ValueDef(name = "err", type = {NUMBER, STRING}, info = "error of the value")
private Correction makeCorrection(Meta corrMeta) {
final String expr = corrMeta.getString("value");
final String errExpr = corrMeta.getString("err", "");

View File

@ -26,6 +26,7 @@ import hep.dataforge.meta.Laminate;
import inr.numass.data.NMFile;
import inr.numass.data.RawNMFile;
import static hep.dataforge.values.ValueType.NUMBER;
import static inr.numass.NumassIO.getNumassData;
/**
@ -36,7 +37,7 @@ import static inr.numass.NumassIO.getNumassData;
inputType = Binary.class, outputType = NMFile.class, info = "Read binary numass data file")
@ValueDef(name = "fileName", info = "The name of the file. By default equals file name.")
@ValueDef(name = "HVdev", info = "Divider for HV measurements. Should be set to 1.0 for numass data 2014",
def = "2.468555393226049", type = "NUMBER")
def = "2.468555393226049", type = {NUMBER})
@ValueDef(name = "noUset", info = "If 'true', then Uset = Uread")
@NodeDef(name = "debunch", target = "class::inr.numass.actions.DebunchAction", info = "If given, governs debunching")
public class ReadLegacyDataAction extends OneToOneAction<Binary, NMFile> {

View File

@ -24,6 +24,8 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import static hep.dataforge.values.ValueType.BOOLEAN;
/**
* Compact all-in-one model for sterile neutrino spectrum
*
@ -32,7 +34,7 @@ import java.io.InputStream;
@NodeDef(name = "resolution")
@NodeDef(name = "transmission")
@ValueDef(name = "fssFile", info = "The name for external FSS file. By default internal FSS file is used")
@ValueDef(name = "useFSS", type = "BOOLEAN")
@ValueDef(name = "useFSS", type = {BOOLEAN})
public class SterileNeutrinoSpectrum extends AbstractParametricFunction {
private static final String[] list = {"X", "trap", "E0", "mnu2", "msterile2", "U2"};

View File

@ -67,7 +67,7 @@ public class TestModels {
double A = meta.getDouble("resolution", meta.getDouble("resolution.width", 8.3e-5));//8.3e-5
double from = meta.getDouble("from", 13900d);
double to = meta.getDouble("to", 18700d);
context.getLog().report("Setting up tritium model with real transmission function");
context.getChronicle().report("Setting up tritium model with real transmission function");
BivariateFunction resolutionTail;
if (meta.hasValue("resolution.tailAlpha")) {
resolutionTail = ResolutionFunction.getAngledTail(meta.getDouble("resolution.tailAlpha"), meta.getDouble("resolution.tailBeta", 0));
@ -78,7 +78,7 @@ public class TestModels {
RangedNamedSetSpectrum beta = new BetaSpectrum();
ModularSpectrum sp = new ModularSpectrum(beta, new ResolutionFunction(A, resolutionTail), from, to);
if (meta.getBoolean("caching", false)) {
context.getLog().report("Caching turned on");
context.getChronicle().report("Caching turned on");
sp.setCaching(true);
}
//Adding trapping energy dependence

View File

@ -31,7 +31,7 @@ import java.io.IOException;
public class TestDirectoryViewer extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
public void start(Stage stage) throws IOException {
new StorageManager().startGlobal();
NumassDataLoader reader = NumassDataLoader.fromLocalDir(null, new File("C:\\Users\\darksnake\\Dropbox\\PlayGround\\data-test\\20150703143643_1\\"));
@ -49,13 +49,13 @@ public class TestDirectoryViewer extends Application {
Scene scene = new Scene(comp.getRoot(), 800, 600);
primaryStage.setTitle("Detector Visualisation test");
primaryStage.setScene(scene);
primaryStage.setMinHeight(600);
primaryStage.setMinWidth(800);
stage.setTitle("Detector Visualisation test");
stage.setScene(scene);
stage.setMinHeight(600);
stage.setMinWidth(800);
// primaryStage.setResizable(false);
primaryStage.show();
stage.show();
}
/**

View File

@ -31,7 +31,7 @@ class JFCTest : View("My View") {
override val root = borderpane {
center {
container.plot = plot
add(container.root)
add(container.pane)
}
bottom {
add(button)