diff --git a/numass-main/src/main/kotlin/inr/numass/NumassPlugin.kt b/numass-main/src/main/kotlin/inr/numass/NumassPlugin.kt index 709002e7..1ff7e9f9 100644 --- a/numass-main/src/main/kotlin/inr/numass/NumassPlugin.kt +++ b/numass-main/src/main/kotlin/inr/numass/NumassPlugin.kt @@ -97,7 +97,8 @@ class NumassPlugin : BasicPlugin() { math.registerBivariate("numass.resolutionTail.2017.mod") { meta -> BivariateFunction { E: Double, U: Double -> 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 } } } diff --git a/numass-main/src/main/kotlin/inr/numass/tasks/NumassTasks.kt b/numass-main/src/main/kotlin/inr/numass/tasks/NumassTasks.kt index 1cb8dbe0..610ab0d5 100644 --- a/numass-main/src/main/kotlin/inr/numass/tasks/NumassTasks.kt +++ b/numass-main/src/main/kotlin/inr/numass/tasks/NumassTasks.kt @@ -5,6 +5,7 @@ import hep.dataforge.data.DataSet import hep.dataforge.data.DataTree import hep.dataforge.data.DataUtils import hep.dataforge.description.ValueDef +import hep.dataforge.kodex.buildMeta import hep.dataforge.kodex.configure import hep.dataforge.kodex.fx.plots.PlotManager import hep.dataforge.kodex.fx.plots.plus @@ -161,15 +162,20 @@ val subtractEmptyTask = task("dif") { val builder = DataTree.builder(Table::class.java) val rootNode = data.getCheckedNode("data", Table::class.java) val empty = data.getCheckedNode
("empty", Table::class.java).data + 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) } res.goal.onComplete { r, _ -> if (r != null) { context.io().out("numass.merge", input.name + "_subtract").use { - NumassUtils.write(it, empty.meta(), r) + NumassUtils.write(it, resMeta, r) } } } diff --git a/numass-server/src/main/java/inr/numass/server/NumassServer.java b/numass-server/src/main/java/inr/numass/server/NumassServer.java index b1c35d1c..0ac97c44 100644 --- a/numass-server/src/main/java/inr/numass/server/NumassServer.java +++ b/numass-server/src/main/java/inr/numass/server/NumassServer.java @@ -16,7 +16,7 @@ package inr.numass.server; import hep.dataforge.context.Context; -import hep.dataforge.context.Encapsulated; +import hep.dataforge.context.ContextAware; import hep.dataforge.exceptions.StorageException; import hep.dataforge.io.envelopes.Envelope; import hep.dataforge.meta.Meta; @@ -37,7 +37,7 @@ import java.io.IOException; /** * @author darksnake */ -public class NumassServer extends AbstractNetworkListener implements Encapsulated { +public class NumassServer extends AbstractNetworkListener implements ContextAware { public static final String DEFAULT_RUN_PATH = "default"; private final Logger logger = LoggerFactory.getLogger("NUMASS-STORAGE"); diff --git a/numass-viewer/src/main/kotlin/inr/numass/viewer/AmplitudeView.kt b/numass-viewer/src/main/kotlin/inr/numass/viewer/AmplitudeView.kt index b90d280e..468edd09 100644 --- a/numass-viewer/src/main/kotlin/inr/numass/viewer/AmplitudeView.kt +++ b/numass-viewer/src/main/kotlin/inr/numass/viewer/AmplitudeView.kt @@ -1,8 +1,11 @@ package inr.numass.viewer +import hep.dataforge.goals.Goal +import hep.dataforge.kodex.Coal import hep.dataforge.kodex.configure import hep.dataforge.kodex.fx.dfIcon import hep.dataforge.kodex.fx.plots.PlotContainer +import hep.dataforge.kodex.fx.ui import hep.dataforge.meta.Meta import hep.dataforge.plots.PlotFrame 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.NumassPoint import javafx.beans.Observable +import javafx.beans.binding.DoubleBinding import javafx.beans.property.SimpleBooleanProperty import javafx.beans.property.SimpleObjectProperty import javafx.collections.FXCollections import javafx.collections.ObservableMap -import javafx.concurrent.Task import javafx.scene.control.CheckBox import javafx.scene.control.ChoiceBox import javafx.scene.image.ImageView @@ -64,27 +67,34 @@ class AmplitudeView( addToSideBar(0, binnintSelector, normalizeSwitch) } - private val data: MutableMap = HashMap(); - private val taskMap: ObservableMap> = FXCollections.observableHashMap(); + private val data: ObservableMap = FXCollections.observableHashMap() + private val plots: ObservableMap> = FXCollections.observableHashMap() + + private val progress = object : DoubleBinding() { + init { + bind(plots) + } + + override fun computeValue(): Double { + return plots.values.count { it.isDone }.toDouble() / data.size; + } + + } + init { + data.addListener { _: Observable -> + invalidate() + } + binningProperty.onChange { - putAll(data) + reset() } normalizeProperty.onChange { - putAll(data) + reset() } - taskMap.addListener { _: Observable -> - runLater { - val running = taskMap.values.count { it.isRunning } - if (running == 0) { - container.progress = 1.0 - } else { - container.progress = running.toDouble() / taskMap.size - } - } - } + container.progressProperty.bind(progress) } override val root = borderpane { @@ -94,67 +104,65 @@ class AmplitudeView( /** * 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()) } - - } - - fun cleanTasks() { - runLater { - taskMap.entries.filter { !it.value.isRunning }.forEach { taskMap.remove(it.key) } - } } /** * Put or replace current plot with name `key` */ - fun putOne(key: String, point: NumassPoint): Task { - val valueAxis = if (normalize) { - NumassAnalyzer.COUNT_RATE_KEY - } else { - NumassAnalyzer.COUNT_KEY - } - + fun putOne(key: String, point: NumassPoint) { 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): Map> { - cleanTasks() - return data.mapValues { entry -> - putOne(entry.key, entry.value) + fun putAll(data: Map) { + this.data.putAll(data); + } + + private fun invalidate() { + data.forEach { key, point -> + plots.computeIfAbsent(key) { + Coal { + 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. */ fun remove(name: String) { frame.remove(name); - taskMap[name]?.cancel(); - taskMap.remove(name); + plots[name]?.cancel(); + plots.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. */ fun setAll(map: Map) { - taskMap.clear(); + plots.clear(); //Remove obsolete keys data.keys.filter { !map.containsKey(it) }.forEach { remove(it) diff --git a/numass-viewer/src/main/kotlin/inr/numass/viewer/SpectrumView.kt b/numass-viewer/src/main/kotlin/inr/numass/viewer/SpectrumView.kt index 9124216c..5922c9e4 100644 --- a/numass-viewer/src/main/kotlin/inr/numass/viewer/SpectrumView.kt +++ b/numass-viewer/src/main/kotlin/inr/numass/viewer/SpectrumView.kt @@ -17,7 +17,7 @@ import javafx.beans.property.SimpleIntegerProperty import javafx.geometry.Insets import javafx.geometry.Orientation import javafx.scene.image.ImageView -import javafx.util.converter.IntegerStringConverter +import javafx.util.converter.NumberStringConverter import org.controlsfx.control.RangeSlider import tornadofx.* import java.util.concurrent.ConcurrentHashMap @@ -99,18 +99,20 @@ class SpectrumView( vbox { label("Lo channel") textfield { - prefWidth= 60.0 - textProperty().bindBidirectional(loChannelProperty.asObject(), IntegerStringConverter()) + prefWidth = 60.0 + textProperty().bindBidirectional(loChannelProperty, NumberStringConverter()) } } items += RangeSlider().apply { padding = Insets(0.0, 10.0, 0.0, 10.0) prefWidth = 300.0 - lowValue = 500.0 - highValue = 3100.0 highValueProperty().bindBidirectional(upChannelProperty) lowValueProperty().bindBidirectional(loChannelProperty) + + lowValue = 500.0 + highValue = 3100.0 + majorTickUnit = 500.0 max = 4000.0 minorTickCount = 5 @@ -122,8 +124,9 @@ class SpectrumView( vbox { label("Up channel") textfield { - prefWidth= 60.0 - textProperty().bindBidirectional(upChannelProperty.asObject(), IntegerStringConverter()) + isEditable = true; + prefWidth = 60.0 + textProperty().bindBidirectional(upChannelProperty, NumberStringConverter()) } } separator(Orientation.VERTICAL) diff --git a/numass-viewer/src/main/kotlin/inr/numass/viewer/StorageView.kt b/numass-viewer/src/main/kotlin/inr/numass/viewer/StorageView.kt index 125b9b2d..bdfc53d6 100644 --- a/numass-viewer/src/main/kotlin/inr/numass/viewer/StorageView.kt +++ b/numass-viewer/src/main/kotlin/inr/numass/viewer/StorageView.kt @@ -107,7 +107,6 @@ class StorageView : View(title = "Numass storage", icon = ImageView(dfIcon)) { } fun setRootStorage(root: NumassStorage) { - runAsync { updateTitle("Fill data to UI (" + root.name + ")") updateProgress(-1.0, 1.0)