Using viewer version 0.5 by default

This commit is contained in:
Alexander Nozik 2017-10-30 14:53:39 +03:00
parent ab5c97252e
commit 252002db5a
7 changed files with 162 additions and 123 deletions

View File

@ -15,7 +15,7 @@ if (!hasProperty('mainClass')) {
mainClassName = mainClass mainClassName = mainClass
version = "0.4.0" version = "0.5.0"
description = "The viewer for numass data" description = "The viewer for numass data"

View File

@ -70,7 +70,7 @@ class AmplitudeView(
private val data: ObservableMap<String, NumassPoint> = FXCollections.observableHashMap() private val data: ObservableMap<String, NumassPoint> = FXCollections.observableHashMap()
private val plots: ObservableMap<String, Goal<DataPlot>> = FXCollections.observableHashMap() private val plots: ObservableMap<String, Goal<DataPlot>> = FXCollections.observableHashMap()
val isEmpty = booleanBinding(data){data.isEmpty()} val isEmpty = booleanBinding(data) { data.isEmpty() }
private val progress = object : DoubleBinding() { private val progress = object : DoubleBinding() {
init { init {
@ -130,9 +130,8 @@ class AmplitudeView(
} else { } else {
NumassAnalyzer.COUNT_KEY NumassAnalyzer.COUNT_KEY
} }
val seriesName = String.format("%s: %.2f", key, point.voltage)
DataPlot.plot( DataPlot.plot(
seriesName, key,
XYAdapter(NumassAnalyzer.CHANNEL_KEY, valueAxis), XYAdapter(NumassAnalyzer.CHANNEL_KEY, valueAxis),
NumassDataUtils.spectrumWithBinning(getSpectrum(point), binning) NumassDataUtils.spectrumWithBinning(getSpectrum(point), binning)
).configure { ).configure {

View File

@ -3,15 +3,17 @@ package inr.numass.viewer
import hep.dataforge.kodex.configure import hep.dataforge.kodex.configure
import hep.dataforge.kodex.fx.dfIcon import hep.dataforge.kodex.fx.dfIcon
import hep.dataforge.kodex.fx.plots.PlotContainer import hep.dataforge.kodex.fx.plots.PlotContainer
import hep.dataforge.kodex.fx.runGoal
import hep.dataforge.kodex.fx.ui
import hep.dataforge.plots.PlotFrame import hep.dataforge.plots.PlotFrame
import hep.dataforge.plots.data.TimePlot import hep.dataforge.plots.data.TimePlot
import hep.dataforge.plots.jfreechart.JFreeChartFrame import hep.dataforge.plots.jfreechart.JFreeChartFrame
import inr.numass.data.api.NumassSet import inr.numass.data.api.NumassSet
import javafx.collections.FXCollections import javafx.collections.FXCollections
import javafx.collections.ObservableList import javafx.collections.MapChangeListener
import javafx.collections.ObservableMap
import javafx.scene.image.ImageView import javafx.scene.image.ImageView
import tornadofx.* import tornadofx.*
import java.util.concurrent.atomic.AtomicInteger
/** /**
@ -30,36 +32,31 @@ class HVView : View(title = "High voltage time plot", icon = ImageView(dfIcon))
center = PlotContainer(frame).root center = PlotContainer(frame).root
} }
private val data: ObservableList<NumassSet> = FXCollections.observableArrayList() private val data: ObservableMap<String, NumassSet> = FXCollections.observableHashMap()
val isEmpty = booleanBinding(data) { data.isEmpty() } val isEmpty = booleanBinding(data) { data.isEmpty() }
init { init {
data.onChange { change -> data.addListener { change: MapChangeListener.Change<out String, out NumassSet> ->
frame.plots.clear() if (change.wasRemoved()) {
container.sideBarExpanded = false frame.remove(change.key)
}
val progress = AtomicInteger(0); if (change.wasAdded()) {
runLater { container.progress = -1.0 } runLater { container.progress = -1.0 }
runGoal("hvData[${change.key}]") {
change.list.forEach { data -> change.valueAdded.hvData
runAsync {
val res = data.hvData
runLater { container.progress = progress.incrementAndGet().toDouble() / change.list.size }
res
} ui { hvData -> } ui { hvData ->
hvData.ifPresent { hvData.ifPresent {
for (dp in it) { for (dp in it) {
val blockName = dp.getString("block", "default").replace(".", "_"); //val blockName = dp.getString("block", "default").replace(".", "_");
//val opt = frame.opt(blockName) //val opt = frame.opt(blockName)
val plot = frame.opt(blockName).orElseGet { val plot = frame.opt(change.key).orElseGet {
TimePlot(blockName).configure { TimePlot(change.key).configure {
"connectionType" to "step" "connectionType" to "step"
"thickness" to 2 "thickness" to 2
"showLine" to true "showLine" to true
"showSymbol" to false "showSymbol" to false
"showErrors" to false "showErrors" to false
} }.apply { frame.add(this) }
.apply { frame.add(this) }
} as TimePlot; } as TimePlot;
plot.put(dp.getValue("timestamp").timeValue(), dp.getValue("value")) plot.put(dp.getValue("timestamp").timeValue(), dp.getValue("value"))
} }
@ -67,20 +64,17 @@ class HVView : View(title = "High voltage time plot", icon = ImageView(dfIcon))
container.progress = 1.0; container.progress = 1.0;
} }
} }
} }
} }
fun update(vararg sets: NumassSet) { fun add(id: String, set: NumassSet) {
data.setAll(*sets) data.put(id, set)
} }
fun add(set: NumassSet) { fun remove(id: String) {
this.data.add(set) data.remove(id);
}
fun remove(set: NumassSet) {
this.data.remove(set);
} }

View File

@ -3,6 +3,8 @@ package inr.numass.viewer
import hep.dataforge.kodex.configure import hep.dataforge.kodex.configure
import hep.dataforge.kodex.fx.dfIcon import hep.dataforge.kodex.fx.dfIcon
import hep.dataforge.kodex.fx.plots.PlotContainer import hep.dataforge.kodex.fx.plots.PlotContainer
import hep.dataforge.kodex.fx.runGoal
import hep.dataforge.kodex.fx.ui
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.plots.PlotFrame import hep.dataforge.plots.PlotFrame
import hep.dataforge.plots.data.DataPlot import hep.dataforge.plots.data.DataPlot
@ -145,7 +147,9 @@ class SpectrumView(
frame.remove(change.key); frame.remove(change.key);
} }
updateView() if (change.wasAdded()) {
updateView()
}
} }
} }
@ -166,7 +170,7 @@ class SpectrumView(
} }
} as DataPlot } as DataPlot
runAsync { runGoal("spectrumData[$name]") {
set.points.map { point -> set.points.map { point ->
val count = NumassAnalyzer.countInWindow(getSpectrum(point), loChannel.toShort(), upChannel.toShort()); val count = NumassAnalyzer.countInWindow(getSpectrum(point), loChannel.toShort(), upChannel.toShort());
val seconds = point.length.toMillis() / 1000.0; val seconds = point.length.toMillis() / 1000.0;

View File

@ -2,9 +2,11 @@ package inr.numass.viewer
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.context.Global import hep.dataforge.context.Global
import hep.dataforge.exceptions.StorageException import hep.dataforge.fx.fragments.FragmentWindow
import hep.dataforge.fx.fragments.LogFragment
import hep.dataforge.kodex.fx.dfIcon import hep.dataforge.kodex.fx.dfIcon
import hep.dataforge.kodex.fx.runGoal import hep.dataforge.kodex.fx.runGoal
import hep.dataforge.kodex.fx.ui
import hep.dataforge.storage.api.Loader import hep.dataforge.storage.api.Loader
import hep.dataforge.storage.api.Storage import hep.dataforge.storage.api.Storage
import hep.dataforge.storage.filestorage.FileStorageFactory import hep.dataforge.storage.filestorage.FileStorageFactory
@ -13,7 +15,7 @@ import inr.numass.data.api.NumassPoint
import inr.numass.data.api.NumassSet import inr.numass.data.api.NumassSet
import inr.numass.data.storage.NumassDataLoader import inr.numass.data.storage.NumassDataLoader
import inr.numass.data.storage.NumassStorage import inr.numass.data.storage.NumassStorage
import javafx.application.Platform import javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty import javafx.beans.property.SimpleStringProperty
import javafx.geometry.Insets import javafx.geometry.Insets
@ -45,13 +47,40 @@ class StorageView(private val context: Context = Global.instance()) : View(title
private val hvView: HVView by inject(); private val hvView: HVView by inject();
private val scView: SlowControlView by inject(); private val scView: SlowControlView by inject();
private data class NamedPoint(val id: String, val point: NumassPoint) private inner class Container(val id: String, val content: Any) {
val checkedProperty = SimpleBooleanProperty(false)
var checked by checkedProperty
init {
checkedProperty.onChange { selected ->
when (content) {
is NumassPoint -> {
if (selected) {
ampView.add(id, content)
} else {
ampView.remove(id)
}
}
is NumassSet -> {
if (selected) {
spectrumView.add(id, content)
hvView.add(id, content)
} else {
spectrumView.remove(id)
hvView.remove(id)
}
}
}
}
}
}
override val root = borderpane { override val root = borderpane {
top { top {
toolbar { toolbar {
prefHeight = 40.0 prefHeight = 40.0
button("load") { button("Load") {
action { action {
val chooser = DirectoryChooser() val chooser = DirectoryChooser()
chooser.title = "Select numass storage root" chooser.title = "Select numass storage root"
@ -82,56 +111,43 @@ class StorageView(private val context: Context = Global.instance()) : View(title
hgrow = Priority.ALWAYS hgrow = Priority.ALWAYS
} }
togglebutton("Console") { togglebutton("Console") {
isSelected = false
FragmentWindow.build(this) {
LogFragment().apply {
addRootLogHandler()
}
}
} }
} }
} }
center { center {
splitpane { splitpane {
treeview<Any> { treeview<Container> {
storageProperty.onChange { storageProperty.onChange {
root = TreeItem(it) if (it != null) {
populate { parent -> root = TreeItem(Container("root", it))
val value = parent.value root.isExpanded = true
when (value) { populate { parent ->
is Storage -> value.shelves() + value.loaders() val value = parent.value.content
is NumassSet -> value.points.map { point -> NamedPoint("${getSetName(value)}/${point.voltage}", point) }.toList() when (value) {
else -> null is Storage -> (value.shelves() + value.loaders()).map { buildContainer(it, parent.value) }
is NumassSet -> value.points.map { buildContainer(it, parent.value) }.toList()
else -> null
}
} }
} }
} }
cellFormat { value -> cellFormat { value ->
when (value) { when (value.content) {
is Storage -> text = value.name is Storage -> text = value.id
is NumassSet -> { is NumassSet -> {
text = null text = null
graphic = checkbox { graphic = checkbox(value.id, value.checkedProperty)
text = value.name
val setName = getSetName(value)
selectedProperty().onChange { selected ->
if (selected) {
spectrumView.add(setName, value)
hvView.add(value)
} else {
spectrumView.remove(setName)
hvView.remove(value)
}
}
}
} }
is NamedPoint -> { is NumassPoint -> {
text = null text = null
graphic = checkbox { graphic = checkbox(value.id, value.checkedProperty)
text = value.id
selectedProperty().onChange { selected ->
if (selected) {
ampView.add(value.id, value.point)
} else {
ampView.remove(id)
}
}
}
} }
else -> { else -> {
text = (value as Loader).name text = (value as Loader).name
@ -139,18 +155,22 @@ class StorageView(private val context: Context = Global.instance()) : View(title
} }
} }
} }
tabpane { tabpane {
tab("Amplitude spectra", ampView.root) { tab("Amplitude spectra") {
content = ampView.root
isClosable = false isClosable = false
visibleWhen(ampView.isEmpty.not()) //visibleWhen(ampView.isEmpty.not())
} }
tab("HV", hvView.root) { tab("HV") {
content = hvView.root
isClosable = false isClosable = false
visibleWhen(hvView.isEmpty.not()) //visibleWhen(hvView.isEmpty.not())
} }
tab("Numass spectra", spectrumView.root) { tab("Numass spectra") {
content = spectrumView.root
isClosable = false isClosable = false
visibleWhen(spectrumView.isEmpty.not()) //visibleWhen(spectrumView.isEmpty.not())
} }
} }
setDividerPosition(0, 0.3); setDividerPosition(0, 0.3);
@ -162,46 +182,70 @@ class StorageView(private val context: Context = Global.instance()) : View(title
} }
private fun getSetName(value: NumassSet): String { private fun buildContainer(content: Any, parent: Container): Container {
return if (value is NumassDataLoader) { return when (content) {
value.path is Storage -> {
} else { Container(content.fullPath, content)
value.name }
is NumassSet -> {
val id = if (content is NumassDataLoader) {
content.path
} else {
content.name
}
Container(id, content)
}
is NumassPoint -> {
Container("${parent.id}/${content.voltage}".replace(".", "_"), content)
}
is Loader -> {
Container(content.path, content);
}
else -> throw IllegalArgumentException("Unknown content type: ${content::class.java}");
} }
} }
// private fun getSetName(value: NumassSet): String {
// return if (value is NumassDataLoader) {
// value.path
// } else {
// value.name
// }
// }
private fun loadDirectory(path: URI) { private fun loadDirectory(path: URI) {
runGoal("loadDirectory[$path]") { runGoal("loadDirectory[$path]") {
title = "Load storage ($path)" title = "Load storage ($path)"
progress = -1.0 progress = -1.0
message = "Building numass storage tree..." message = "Building numass storage tree..."
val root = NumassStorage(context, FileStorageFactory.buildStorageMeta(path, true, true)); NumassStorage(context, FileStorageFactory.buildStorageMeta(path, true, true)).also {
setRootStorage(root) progress = 1.0
Platform.runLater { storageName = "Storage: " + path }
progress = 1.0
}
}
fun setRootStorage(root: Storage) {
runGoal("loadStorage[${root.name}]") {
title = "Fill data to UI (" + root.name + ")"
progress = -1.0
runLater { statusBar.progress = -1.0 }
message = "Loading numass storage tree..."
runLater {
try {
storageProperty.set(root)
} catch (ex: StorageException) {
context.logger.error("Could not load the storage", ex);
}
} }
} ui {
storage = it
storageName = "Storage: " + path
// callback.setProgress(1, 1);
runLater { statusBar.progress = 0.0 }
message = "Numass storage tree loaded."
progress = 1.0
} }
} }
// fun setRootStorage(root: Storage) {
// runGoal("loadStorage[${root.name}]") {
// title = "Fill data to UI (" + root.name + ")"
// progress = -1.0
// runLater { statusBar.progress = -1.0 }
//
// message = "Loading numass storage tree..."
//
// runLater {
// storage = root
// }
//
// // callback.setProgress(1, 1);
// runLater { statusBar.progress = 0.0 }
// message = "Numass storage tree loaded."
// progress = 1.0
// }
// }
} }

View File

@ -3,25 +3,23 @@ package inr.numass.viewer
import ch.qos.logback.classic.Level import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger import ch.qos.logback.classic.Logger
import hep.dataforge.context.Global import hep.dataforge.context.Global
import hep.dataforge.kodex.fx.dfIcon
import hep.dataforge.storage.commons.StorageManager
import javafx.stage.Stage
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import tornadofx.* import tornadofx.*
/** /**
* Created by darksnake on 14-Apr-17. * Created by darksnake on 14-Apr-17.
*/ */
class Viewer : App(MainView::class) { class Viewer : App(StorageView::class) {
init{
override fun start(stage: Stage) {
stage.icons += dfIcon
(LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) as Logger).level = Level.INFO (LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) as Logger).level = Level.INFO
Global.setDefaultContext(Global.instance())
StorageManager().startGlobal()
super.start(stage)
} }
// override fun start(stage: Stage) {
// stage.icons += dfIcon
//// (LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) as Logger).level = Level.INFO
// super.start(stage)
// }
override fun stop() { override fun stop() {
super.stop() super.stop()
Global.terminate(); Global.terminate();

View File

@ -26,9 +26,9 @@ class ViewerComponentsTest : View(title = "Numass viewer test", icon = ImageView
private val cache: MutableMap<NumassPoint, Table> = ConcurrentHashMap(); private val cache: MutableMap<NumassPoint, Table> = ConcurrentHashMap();
val amp = AmplitudeView(cache = cache) val amp: AmplitudeView by inject(params = mapOf("cache" to cache))//= AmplitudeView(cache = cache)
val sp = SpectrumView(cache = cache) val sp: SpectrumView by inject(params = mapOf("cache" to cache))
val hv = HVView() val hv: HVView by inject()
override val root = borderpane { override val root = borderpane {
top { top {
@ -55,7 +55,7 @@ class ViewerComponentsTest : View(title = "Numass viewer test", icon = ImageView
fun update(set: NumassSet) { fun update(set: NumassSet) {
amp.setAll(set.points.filter { it.voltage != 16000.0 }.collect(Collectors.toMap({ "point_${it.voltage}" }, { it }))); amp.setAll(set.points.filter { it.voltage != 16000.0 }.collect(Collectors.toMap({ "point_${it.voltage}" }, { it })));
sp.add("test", set); sp.add("test", set);
hv.update(set) hv.add(set.name, set)
} }
} }