Default behavior for reference registry changed to strong references. PKT8 test for numass is working.

This commit is contained in:
Alexander Nozik 2017-11-15 14:21:32 +03:00
parent d77051b54f
commit f0fc22c9ec
6 changed files with 96 additions and 245 deletions

View File

@ -7,6 +7,7 @@ syntax: glob
build/*
target/*
private/*
out/*
.gradle/*
.nb-gradle/*
.idea/

View File

@ -3,16 +3,17 @@ package inr.numass.control
import hep.dataforge.context.Context
import hep.dataforge.context.Global
import hep.dataforge.control.DeviceManager
import hep.dataforge.control.connections.Roles
import hep.dataforge.control.devices.Device
import hep.dataforge.kodex.useMeta
import hep.dataforge.kodex.useMetaList
import hep.dataforge.meta.Meta
import hep.dataforge.server.ServerManager
import hep.dataforge.storage.api.Storage
import hep.dataforge.storage.commons.StorageConnection
import hep.dataforge.storage.commons.StorageManager
import inr.numass.client.ClientUtils
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty
import javafx.collections.FXCollections
import javafx.collections.ObservableList
import tornadofx.*
@ -25,32 +26,9 @@ class BoardController() : Controller(), AutoCloseable {
val contextProperty = SimpleObjectProperty<Context>(Global.instance())
var context: Context by contextProperty
// val metaProperty = SimpleObjectProperty<Meta>(Meta.empty())
// var meta: Meta by metaProperty
val numassRunProperty = SimpleStringProperty("")
var numassRun: String by numassRunProperty
private set
val storageProperty = nonNullObjectBinding(contextProperty, numassRunProperty) {
val rootStorage = context.pluginManager.getOrLoad(StorageManager::class.java).defaultStorage
if (!numassRun.isEmpty()) {
context.logger.info("Run information found. Selecting run {}", numassRun)
rootStorage.buildShelf(numassRun, Meta.empty());
} else {
rootStorage
}
}.apply {
onChange {
val connection = StorageConnection(value)
devices.forEach { device ->
device.forEachConnection(StorageConnection::class.java) { device.disconnect(it) }//removing all ald storage connections
device.connect(connection)
}
}
}
val storageProperty = SimpleObjectProperty<Storage>(null)
val serverManagerProperty = objectBinding(contextProperty) {
context.optFeature(ServerManager::class.java).orElse(null)
@ -58,52 +36,37 @@ class BoardController() : Controller(), AutoCloseable {
val devices: ObservableList<Device> = FXCollections.observableArrayList();
val deviceManagerProperty = objectBinding(contextProperty) {
context.optFeature(DeviceManager::class.java).orElse(null)
}.apply {
onChange {
value?.let {
devices.setAll(it.devices.toList());
}
}
}
// val deviceViews: ObservableList<DeviceDisplay<*>> = object : ListBinding<DeviceDisplay<*>>() {
// init {
// bind(devices)
// }
//
// override fun computeValue(): ObservableList<DeviceDisplay<*>> {
// val manager = deviceManagerProperty.value
// return if (manager == null) {
// FXCollections.emptyObservableList();
// } else {
// manager.deviceNames()
// .filter { it.length == 1 } // select top level devices
// .map { manager.optDevice(it) }
// .filter { it.isPresent }
// .map { it.get().getDisplay() }
// .toList().observable()
// }
// }
// }
fun configure(meta: Meta) {
Context.build("NUMASS", Global.instance(), meta.getMeta("context", meta)).apply {
val numassRun = meta.optMeta("numass").map { ClientUtils.getRunName(it) }.orElse("")
meta.useMeta("storage") {
pluginManager.getOrLoad(StorageManager::class.java).configure(it);
}
val rootStorage = pluginManager.getOrLoad(StorageManager::class.java).defaultStorage
val storage = if (!numassRun.isEmpty()) {
logger.info("Run information found. Selecting run {}", numassRun)
rootStorage.buildShelf(numassRun, Meta.empty());
} else {
rootStorage
}
val connection = StorageConnection(storage)
val deviceManager = pluginManager.getOrLoad(DeviceManager::class.java)
meta.useMetaList("device") {
it.forEach {
pluginManager.getOrLoad(DeviceManager::class.java).buildDevice(it)
deviceManager.buildDevice(it)
}
}
meta.useMeta("numass") {
numassRun = ClientUtils.getRunName(it)
}
deviceManager.devices.forEach { it.connect(connection, Roles.STORAGE_ROLE, Roles.MEASUREMENT_LISTENER_ROLE) }
}.also {
runLater {
context = it
devices.setAll(context.getFeature(DeviceManager::class.java).devices.toList());
}
}
}
@ -112,89 +75,4 @@ class BoardController() : Controller(), AutoCloseable {
context.close()
//Global.terminate()
}
// val devices: ObservableList<DeviceDisplay<*>> = FXCollections.observableArrayList<DeviceDisplay<*>>();
//
// val contextProperty = SimpleObjectProperty<Context>(Global.instance())
// var context: Context by contextProperty
// private set
//
// val storageProperty = SimpleObjectProperty<Storage>()
// var storage: Storage? by storageProperty
// private set
//
// val serverManagerProperty = SimpleObjectProperty<ServerManager>()
// var serverManager: ServerManager? by serverManagerProperty
// private set
//
// fun load(app: Application) {
// runAsync {
// getConfig(app).ifPresent {
// val context = Context.build("NUMASS", Global.instance(), it)
// load(context, it)
// }
// }
//
// }
//
// private fun load(context: Context, meta: Meta) {
// this.context = context;
// devices.clear();
// meta.getMetaList("device").forEach {
// try {
// Platform.runLater { devices.add(buildDeviceView(context, it)) };
// } catch (ex: Exception) {
// context.logger.error("Can't build device view", ex);
// }
// }
//
// if (meta.hasMeta("storage")) {
// val st = buildStorage(context, meta);
// val storageConnection = StorageConnection(storage);
// devices.forEach {
// if (it.device.acceptsRole(Roles.STORAGE_ROLE)) {
// it.device.connect(storageConnection, Roles.STORAGE_ROLE);
// }
// }
// Platform.runLater {
// storage = st
// meta.optMeta("server").ifPresent { serverMeta ->
// val sm = context.getPluginManager().getOrLoad(ServerManager::class.java);
// sm.configure(serverMeta)
//
// sm.bind(NumassStorageServerObject(serverManager, storage, "numass-storage"));
// serverManager = sm
// }
// }
// }
// }
//
// private fun buildDeviceView(context: Context, deviceMeta: Meta): DeviceDisplay<*> {
// context.logger.info("Building device with meta: {}", deviceMeta)
// val device = context.loadFeature("devices", DeviceManager::class.java).buildDevice(deviceMeta)
// device.init();
// return device.getDisplay();
// }
//
// private fun buildStorage(context: Context, meta: Meta): Storage {
// val storageMeta = meta.getMeta("storage").builder
// .putValue("readOnly", false)
// .putValue("monitor", true)
//
// context.logger.info("Creating storage for server with meta {}", storageMeta)
// var storage = StorageFactory.buildStorage(context, storageMeta);
//
// val numassRun = ClientUtils.getRunName(meta)
// if (!numassRun.isEmpty()) {
// context.logger.info("Run information found. Selecting run {}", numassRun)
// storage = storage.buildShelf(numassRun, Meta.empty());
// }
// return storage;
// }
//
// override fun close() {
// devices.forEach {
// it.close()
// }
// context.close();
// }
}

View File

@ -22,9 +22,8 @@ import hep.dataforge.meta.Metoid
import hep.dataforge.names.Named
internal fun createChannel(name: String): PKT8Channel {
return PKT8Channel(MetaBuilder("channel").putValue("name", name)) { d -> d }
}
internal fun createChannel(name: String): PKT8Channel =
PKT8Channel(MetaBuilder("channel").putValue("name", name)) { d -> d }
internal fun createChannel(meta: Meta): PKT8Channel {
val transformationType = meta.getString("transformationType", "default")

View File

@ -42,7 +42,6 @@ import inr.numass.control.DeviceView
import inr.numass.control.StorageHelper
import java.time.Duration
import java.util.*
import kotlin.streams.toList
/**
@ -61,14 +60,14 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
/**
* The key is the letter (a,b,c,d...) as in measurements
*/
private val channels = LinkedHashMap<String, PKT8Channel>()
val channels = LinkedHashMap<String, PKT8Channel>()
private var collector: RegularPointCollector? = null
private var storageHelper: StorageHelper? = null
/**
* Cached values
*/
private var format: TableFormat? = null
//private var format: TableFormat? = null
private// Building data format
@ -76,15 +75,12 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
val tableFormatBuilder = TableFormatBuilder()
.addTime("timestamp")
for (channel in channels.values) {
for (channel in this.channels.values) {
tableFormatBuilder.addNumber(channel.name)
}
tableFormatBuilder.build()
}
val chanels: Collection<PKT8Channel>
get() = this.channels.values
val sps: String
get() = getState(SPS).stringValue()
@ -119,7 +115,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
} else {
//set default channel configuration
for (designation in CHANNEL_DESIGNATIONS) {
channels.put(designation, createChannel(designation))
this.channels.put(designation, createChannel(designation))
}
logger.warn("No channels defined in configuration")
}
@ -143,12 +139,9 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
// setting up the collector
storageHelper = StorageHelper(this) { connection: StorageConnection -> this.buildLoader(connection) }
val duration = Duration.parse(meta().getString("averagingDuration", "PT30S"))
collector = RegularPointCollector(
duration,
channels.values.stream().map { it.name }.toList()
) { dp: Values ->
collector = RegularPointCollector(duration, this.channels.values.map { it.name }) { dp: Values ->
logger.debug("Point measurement complete. Pushing...")
storageHelper!!.push(dp)
storageHelper?.push(dp)
}
}
@ -162,13 +155,12 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
@Throws(ControlException::class)
override fun buildHandler(portName: String): PortHandler {
val handler: PortHandler
//setup connection
if ("virtual" == portName) {
val handler: PortHandler = if ("virtual" == portName) {
logger.info("Starting {} using virtual debug port", name)
handler = PKT8VirtualPort("PKT8", meta().getMetaOrEmpty("debug"))
PKT8VirtualPort("PKT8", meta().getMetaOrEmpty("debug"))
} else {
handler = super.buildHandler(portName)
super.buildHandler(portName)
}
handler.setDelimiter("\n")
@ -209,17 +201,17 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
* @return
*/
private fun spsToStr(sps: Int): String {
when (sps) {
0 -> return "2.5 SPS"
1 -> return "5 SPS"
2 -> return "10 SPS"
3 -> return "25 SPS"
4 -> return "50 SPS"
5 -> return "100 SPS"
6 -> return "500 SPS"
7 -> return "1 kSPS"
8 -> return "3.75 kSPS"
else -> return "unknown value"
return when (sps) {
0 -> "2.5 SPS"
1 -> "5 SPS"
2 -> "10 SPS"
3 -> "25 SPS"
4 -> "50 SPS"
5 -> "100 SPS"
6 -> "500 SPS"
7 -> "1 kSPS"
8 -> "3.75 kSPS"
else -> "unknown value"
}
}
@ -231,15 +223,15 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
* @return
*/
private fun pgaToStr(pga: Int): String {
when (pga) {
0 -> return "± 5 V"
1 -> return "± 2,5 V"
2 -> return "± 1,25 V"
3 -> return "± 0,625 V"
4 -> return "± 312.5 mV"
5 -> return "± 156.25 mV"
6 -> return "± 78.125 mV"
else -> return "unknown value"
return when (pga) {
0 -> "± 5 V"
1 -> "± 2,5 V"
2 -> "± 1,25 V"
3 -> "± 0,625 V"
4 -> "± 312.5 mV"
5 -> "± 156.25 mV"
6 -> "± 78.125 mV"
else -> "unknown value"
}
}
@ -256,7 +248,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
updateState(SPS, Integer.parseInt(response.substring(4)))
// getLogger().info("successfully sampling rate to {}", spsToStr(this.sps));
} else {
logger.error("Setting sps failsed with message: " + response)
logger.error("Setting sps failed with message: " + response)
}
}
@ -309,7 +301,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
try {
logger.info("Starting measurement")
handler.holdBy(this)
handler.send(this,"s")
handler.send(this, "s")
afterStart()
} catch (ex: ControlException) {
portError("Failed to start measurement", ex)
@ -332,9 +324,8 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
error(ex)
false
} finally {
if (collector != null) {
collector!!.clear()
}
collector?.clear()
logger.debug("Removing port lock")
handler.unholdBy(this)
}
}
@ -351,13 +342,11 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
val designation = trimmed.substring(0, 1)
val rawValue = java.lang.Double.parseDouble(trimmed.substring(1)) / 100
val channel = channels[designation]
val channel = this@PKT8Device.channels[designation]
if (channel != null) {
result(channel.evaluate(rawValue))
if (collector != null) {
collector!!.put(channel.getName(), channel.getTemperature(rawValue))
}
collector?.put(channel.name, channel.getTemperature(rawValue))
} else {
result(PKT8Result(designation, rawValue, -1.0))
}
@ -380,4 +369,12 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
private val CHANNEL_DESIGNATIONS = arrayOf("a", "b", "c", "d", "e", "f", "g", "h")
}
}
data class PKT8Result(val channel: String, val rawValue: Double, val temperature: Double) {
val rawString: String = String.format("%.2f", rawValue)
val temperatureString: String = String.format("%.2f", temperature)
}

View File

@ -7,6 +7,7 @@ import hep.dataforge.fx.bindWindow
import hep.dataforge.fx.fragments.LogFragment
import hep.dataforge.fx.plots.PlotContainer
import hep.dataforge.meta.Meta
import hep.dataforge.plots.Plot
import hep.dataforge.plots.PlotFrame
import hep.dataforge.plots.PlotUtils
import hep.dataforge.plots.data.TimePlot
@ -135,16 +136,14 @@ class PKT8Display : DeviceDisplay<PKT8Device>(), MeasurementListener {
}
inner class CryoPlotView : View("PKT8 temperature plot") {
val plotFrameMeta: Meta = device.meta.getMetaOrEmpty("plotConfig")
private val plotFrameMeta: Meta = device.meta.getMetaOrEmpty("plotConfig")
val plotFrame: PlotFrame by lazy {
private val plotFrame: PlotFrame by lazy {
JFreeChartFrame(plotFrameMeta).apply {
PlotUtils.setXAxis(this, "timestamp", null, "time")
}
}
private val plottables = plotFrame.plots
var rawDataButton: ToggleButton by singleAssign()
override val root: Parent = borderpane {
@ -169,39 +168,43 @@ class PKT8Display : DeviceDisplay<PKT8Device>(), MeasurementListener {
}
init {
val channels = device.chanels
//frame config from device configuration
//Do not use view config here, it is applyed separately
channels.stream()
.filter { channel -> !plottables.has(channel.name) }
.forEachOrdered { channel ->
//frame config from device configuration
val plot = TimePlot(channel.name)
plot.configure(channel.meta())
plottables.add(plot)
plotFrame.add(plot)
}
if (device.meta().hasMeta("plotConfig")) {
plottables.configure(device.meta().getMeta("plotConfig"))
TimePlot.setMaxItems(plottables, 1000)
TimePlot.setPrefItems(plottables, 400)
with(plotFrame.plots) {
configure(device.meta().getMeta("plotConfig"))
TimePlot.setMaxItems(this, 1000)
TimePlot.setPrefItems(this, 400)
}
}
table.addListener(MapChangeListener { change ->
if (change.wasAdded()) {
change.valueAdded.apply {
if (rawDataButton.isSelected) {
plottables.opt(channel).ifPresent { TimePlot.put(it, rawValue) }
} else {
plottables.opt(channel).ifPresent { TimePlot.put(it, temperature) }
getPlot(channel)?.apply {
if (rawDataButton.isSelected) {
TimePlot.put(this, rawValue)
} else {
TimePlot.put(this, temperature)
}
}
}
}
})
}
fun clearPlot() {
plottables.clear()
private fun getPlot(channelName: String): Plot? {
return if (plotFrame.plots.has(channelName)) {
plotFrame.get(channelName)
} else {
device.channels.values.find { it.name == channelName }?.let {
TimePlot(it.name).apply {
configure(it.meta())
plotFrame.add(this)
}
}
}
}
private fun clearPlot() {
plotFrame.clear()
}
}
}

View File

@ -1,27 +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
/**
* Created by darksnake on 28-Sep-16.
*/
data class PKT8Result(var channel: String, var rawValue: Double, var temperature: Double) {
val rawString: String = String.format("%.2f", rawValue)
val temperatureString: String = String.format("%.2f", temperature)
}