Fixed numass Viewer tools

This commit is contained in:
Alexander Nozik 2017-10-26 17:03:45 +03:00
parent fd8255a654
commit 7a519e3b81
6 changed files with 90 additions and 73 deletions

View File

@ -97,7 +97,8 @@ class NumassPlugin : BasicPlugin() {
math.registerBivariate("numass.resolutionTail.2017.mod") { meta -> math.registerBivariate("numass.resolutionTail.2017.mod") { meta ->
BivariateFunction { E: Double, U: Double -> BivariateFunction { E: Double, U: Double ->
val D = E - U val D = E - U
(0.99797 - 3.05346E-7 * D - 5.45738E-10 * Math.pow(D, 2.0) - 6.36105E-14 * Math.pow(D, 3.0)) * (1 - 5e-3 * Math.sqrt(E / 1000)) val factor = 7.33 - E / 1000.0 / 3.0
return@BivariateFunction 1.0 - (3.05346E-7 * D - 5.45738E-10 * Math.pow(D, 2.0) - 6.36105E-14 * Math.pow(D, 3.0))*factor
} }
} }
} }

View File

@ -5,6 +5,7 @@ import hep.dataforge.data.DataSet
import hep.dataforge.data.DataTree import hep.dataforge.data.DataTree
import hep.dataforge.data.DataUtils import hep.dataforge.data.DataUtils
import hep.dataforge.description.ValueDef import hep.dataforge.description.ValueDef
import hep.dataforge.kodex.buildMeta
import hep.dataforge.kodex.configure import hep.dataforge.kodex.configure
import hep.dataforge.kodex.fx.plots.PlotManager import hep.dataforge.kodex.fx.plots.PlotManager
import hep.dataforge.kodex.fx.plots.plus import hep.dataforge.kodex.fx.plots.plus
@ -161,15 +162,20 @@ val subtractEmptyTask = task("dif") {
val builder = DataTree.builder(Table::class.java) val builder = DataTree.builder(Table::class.java)
val rootNode = data.getCheckedNode<Table>("data", Table::class.java) val rootNode = data.getCheckedNode<Table>("data", Table::class.java)
val empty = data.getCheckedNode<Table>("empty", Table::class.java).data val empty = data.getCheckedNode<Table>("empty", Table::class.java).data
rootNode.forEachData(Table::class.java, { input -> rootNode.forEachData(Table::class.java, { input ->
val res = DataUtils.combine(input, empty, Table::class.java, input.meta()) { mergeData, emptyData -> val resMeta = buildMeta {
node("data", input.meta)
node("empty", empty.meta)
}
val res = DataUtils.combine(input, empty, Table::class.java, resMeta) { mergeData, emptyData ->
subtract(context, mergeData, emptyData) subtract(context, mergeData, emptyData)
} }
res.goal.onComplete { r, _ -> res.goal.onComplete { r, _ ->
if (r != null) { if (r != null) {
context.io().out("numass.merge", input.name + "_subtract").use { context.io().out("numass.merge", input.name + "_subtract").use {
NumassUtils.write(it, empty.meta(), r) NumassUtils.write(it, resMeta, r)
} }
} }
} }

View File

@ -16,7 +16,7 @@
package inr.numass.server; package inr.numass.server;
import hep.dataforge.context.Context; import hep.dataforge.context.Context;
import hep.dataforge.context.Encapsulated; import hep.dataforge.context.ContextAware;
import hep.dataforge.exceptions.StorageException; import hep.dataforge.exceptions.StorageException;
import hep.dataforge.io.envelopes.Envelope; import hep.dataforge.io.envelopes.Envelope;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
@ -37,7 +37,7 @@ import java.io.IOException;
/** /**
* @author darksnake * @author darksnake
*/ */
public class NumassServer extends AbstractNetworkListener implements Encapsulated { public class NumassServer extends AbstractNetworkListener implements ContextAware {
public static final String DEFAULT_RUN_PATH = "default"; public static final String DEFAULT_RUN_PATH = "default";
private final Logger logger = LoggerFactory.getLogger("NUMASS-STORAGE"); private final Logger logger = LoggerFactory.getLogger("NUMASS-STORAGE");

View File

@ -1,8 +1,11 @@
package inr.numass.viewer package inr.numass.viewer
import hep.dataforge.goals.Goal
import hep.dataforge.kodex.Coal
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.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
@ -14,11 +17,11 @@ import inr.numass.data.analyzers.SimpleAnalyzer
import inr.numass.data.api.NumassAnalyzer import inr.numass.data.api.NumassAnalyzer
import inr.numass.data.api.NumassPoint import inr.numass.data.api.NumassPoint
import javafx.beans.Observable import javafx.beans.Observable
import javafx.beans.binding.DoubleBinding
import javafx.beans.property.SimpleBooleanProperty import javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.collections.FXCollections import javafx.collections.FXCollections
import javafx.collections.ObservableMap import javafx.collections.ObservableMap
import javafx.concurrent.Task
import javafx.scene.control.CheckBox import javafx.scene.control.CheckBox
import javafx.scene.control.ChoiceBox import javafx.scene.control.ChoiceBox
import javafx.scene.image.ImageView import javafx.scene.image.ImageView
@ -64,27 +67,34 @@ class AmplitudeView(
addToSideBar(0, binnintSelector, normalizeSwitch) addToSideBar(0, binnintSelector, normalizeSwitch)
} }
private val data: MutableMap<String, NumassPoint> = HashMap(); private val data: ObservableMap<String, NumassPoint> = FXCollections.observableHashMap()
private val taskMap: ObservableMap<String, Task<DataPlot>> = FXCollections.observableHashMap(); private val plots: ObservableMap<String, Goal<DataPlot>> = FXCollections.observableHashMap()
private val progress = object : DoubleBinding() {
init {
bind(plots)
}
override fun computeValue(): Double {
return plots.values.count { it.isDone }.toDouble() / data.size;
}
}
init { init {
data.addListener { _: Observable ->
invalidate()
}
binningProperty.onChange { binningProperty.onChange {
putAll(data) reset()
} }
normalizeProperty.onChange { normalizeProperty.onChange {
putAll(data) reset()
} }
taskMap.addListener { _: Observable ->
runLater {
val running = taskMap.values.count { it.isRunning }
if (running == 0) { container.progressProperty.bind(progress)
container.progress = 1.0
} else {
container.progress = running.toDouble() / taskMap.size
}
}
}
} }
override val root = borderpane { override val root = borderpane {
@ -94,67 +104,65 @@ class AmplitudeView(
/** /**
* Calculate or get spectrum from the cache * Calculate or get spectrum from the cache
*/ */
private fun getSpectrum(point: NumassPoint): Table { private suspend fun getSpectrum(point: NumassPoint): Table {
return cache.computeIfAbsent(point) { analyzer.getSpectrum(point, Meta.empty()) } return cache.computeIfAbsent(point) { analyzer.getSpectrum(point, Meta.empty()) }
}
fun cleanTasks() {
runLater {
taskMap.entries.filter { !it.value.isRunning }.forEach { taskMap.remove(it.key) }
}
} }
/** /**
* Put or replace current plot with name `key` * Put or replace current plot with name `key`
*/ */
fun putOne(key: String, point: NumassPoint): Task<DataPlot> { fun putOne(key: String, point: NumassPoint) {
val valueAxis = if (normalize) {
NumassAnalyzer.COUNT_RATE_KEY
} else {
NumassAnalyzer.COUNT_KEY
}
data.put(key, point) data.put(key, point)
val res = runAsync {
val seriesName = String.format("%s: %.2f", key, point.voltage)
DataPlot.plot(
seriesName,
XYAdapter(NumassAnalyzer.CHANNEL_KEY, valueAxis),
NumassDataUtils.spectrumWithBinning(getSpectrum(point), binning)
).configure {
"connectionType" to "step"
"thickness" to 2
"showLine" to true
"showSymbol" to false
"showErrors" to false
"JFreeChart.cache" to true
}
} ui { plot ->
frame.add(plot)
//detectorDataExportButton.isDisable = false
}
taskMap.put(key, res);
return res;
} }
fun putAll(data: Map<String, NumassPoint>): Map<String, Task<DataPlot>> { fun putAll(data: Map<String, NumassPoint>) {
cleanTasks() this.data.putAll(data);
return data.mapValues { entry -> }
putOne(entry.key, entry.value)
private fun invalidate() {
data.forEach { key, point ->
plots.computeIfAbsent(key) {
Coal<DataPlot> {
val valueAxis = if (normalize) {
NumassAnalyzer.COUNT_RATE_KEY
} else {
NumassAnalyzer.COUNT_KEY
}
val seriesName = String.format("%s: %.2f", key, point.voltage)
DataPlot.plot(
seriesName,
XYAdapter(NumassAnalyzer.CHANNEL_KEY, valueAxis),
NumassDataUtils.spectrumWithBinning(getSpectrum(point), binning)
).configure {
"connectionType" to "step"
"thickness" to 2
"showLine" to true
"showSymbol" to false
"showErrors" to false
"JFreeChart.cache" to true
}
}.ui { plot ->
frame.add(plot)
progress.invalidate()
}.start()
}
plots.keys.filter { !data.containsKey(it) }.forEach { remove(it) }
} }
} }
private fun reset() {
frame.plots.clear()
plots.clear()
invalidate()
}
/** /**
* Remove the plot and cancel loading task if it is in progress. * Remove the plot and cancel loading task if it is in progress.
*/ */
fun remove(name: String) { fun remove(name: String) {
frame.remove(name); frame.remove(name);
taskMap[name]?.cancel(); plots[name]?.cancel();
taskMap.remove(name); plots.remove(name);
data.remove(name) data.remove(name)
} }
@ -162,7 +170,7 @@ class AmplitudeView(
* Set frame content to the given map. All keys not in the map are removed. * Set frame content to the given map. All keys not in the map are removed.
*/ */
fun setAll(map: Map<String, NumassPoint>) { fun setAll(map: Map<String, NumassPoint>) {
taskMap.clear(); plots.clear();
//Remove obsolete keys //Remove obsolete keys
data.keys.filter { !map.containsKey(it) }.forEach { data.keys.filter { !map.containsKey(it) }.forEach {
remove(it) remove(it)

View File

@ -17,7 +17,7 @@ import javafx.beans.property.SimpleIntegerProperty
import javafx.geometry.Insets import javafx.geometry.Insets
import javafx.geometry.Orientation import javafx.geometry.Orientation
import javafx.scene.image.ImageView import javafx.scene.image.ImageView
import javafx.util.converter.IntegerStringConverter import javafx.util.converter.NumberStringConverter
import org.controlsfx.control.RangeSlider import org.controlsfx.control.RangeSlider
import tornadofx.* import tornadofx.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@ -99,18 +99,20 @@ class SpectrumView(
vbox { vbox {
label("Lo channel") label("Lo channel")
textfield { textfield {
prefWidth= 60.0 prefWidth = 60.0
textProperty().bindBidirectional(loChannelProperty.asObject(), IntegerStringConverter()) textProperty().bindBidirectional(loChannelProperty, NumberStringConverter())
} }
} }
items += RangeSlider().apply { items += RangeSlider().apply {
padding = Insets(0.0, 10.0, 0.0, 10.0) padding = Insets(0.0, 10.0, 0.0, 10.0)
prefWidth = 300.0 prefWidth = 300.0
lowValue = 500.0
highValue = 3100.0
highValueProperty().bindBidirectional(upChannelProperty) highValueProperty().bindBidirectional(upChannelProperty)
lowValueProperty().bindBidirectional(loChannelProperty) lowValueProperty().bindBidirectional(loChannelProperty)
lowValue = 500.0
highValue = 3100.0
majorTickUnit = 500.0 majorTickUnit = 500.0
max = 4000.0 max = 4000.0
minorTickCount = 5 minorTickCount = 5
@ -122,8 +124,9 @@ class SpectrumView(
vbox { vbox {
label("Up channel") label("Up channel")
textfield { textfield {
prefWidth= 60.0 isEditable = true;
textProperty().bindBidirectional(upChannelProperty.asObject(), IntegerStringConverter()) prefWidth = 60.0
textProperty().bindBidirectional(upChannelProperty, NumberStringConverter())
} }
} }
separator(Orientation.VERTICAL) separator(Orientation.VERTICAL)

View File

@ -107,7 +107,6 @@ class StorageView : View(title = "Numass storage", icon = ImageView(dfIcon)) {
} }
fun setRootStorage(root: NumassStorage) { fun setRootStorage(root: NumassStorage) {
runAsync { runAsync {
updateTitle("Fill data to UI (" + root.name + ")") updateTitle("Fill data to UI (" + root.name + ")")
updateProgress(-1.0, 1.0) updateProgress(-1.0, 1.0)