Update Value and State annotations
This commit is contained in:
commit
900e249d5c
@ -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) {
|
||||
|
@ -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')
|
||||
|
@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -22,6 +22,6 @@ public class PKT8DeviceFactory implements DeviceViewFactory {
|
||||
|
||||
@Override
|
||||
public DeviceViewConnection buildView(Device device) {
|
||||
return PKT8View.build(device.getContext());
|
||||
return new PKT8ViewConnection();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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)
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
</ToolBar>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
|
@ -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>
|
||||
</ToolBar>
|
||||
</top>
|
||||
</BorderPane>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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);
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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"));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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<*>
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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> {
|
||||
|
@ -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", "");
|
||||
|
@ -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> {
|
||||
|
@ -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"};
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user