fix parallel computation for spectrum in viewer

This commit is contained in:
Alexander Nozik 2021-12-05 17:24:53 +03:00
parent 48c7c27af4
commit cadfc20e54
6 changed files with 35 additions and 42 deletions

View File

@ -112,36 +112,28 @@ class PlotGroup(override val name: String, descriptor: NodeDescriptor = NodeDes
} }
@ProvidesNames(PLOT_TARGET) @ProvidesNames(PLOT_TARGET)
fun list(): Stream<String> { fun list(): Stream<String> = stream().map { it.first.toString() }
return stream().map { it.first.toString() }
}
/** /**
* Recursive stream of all plots excluding intermediate nodes * Recursive stream of all plots excluding intermediate nodes
* *
* @return * @return
*/ */
fun stream(recursive: Boolean = true): Stream<Pair<Name, Plottable>> { fun stream(recursive: Boolean = true): Stream<Pair<Name, Plottable>> = plots.stream().flatMap {
return plots.stream().flatMap { if (recursive && it is PlotGroup) {
if (recursive && it is PlotGroup) { it.stream().map { pair -> Pair(Name.ofSingle(it.name) + pair.first, pair.second) }
it.stream().map { pair -> Pair(Name.ofSingle(it.name) + pair.first, pair.second) } } else {
} else { Stream.of(Pair(Name.ofSingle(it.name), it))
Stream.of(Pair(Name.ofSingle(it.name), it))
}
} }
} }
@Provides(PLOT_TARGET) @Provides(PLOT_TARGET)
operator fun get(name: String): Plottable? { operator fun get(name: String): Plottable? = get(Name.of(name))
return get(Name.of(name))
}
operator fun get(name: Name): Plottable? { operator fun get(name: Name): Plottable? = when (name.length) {
return when { 0 -> this
name.length == 0 -> this 1 -> plots.find { it.name == name.unescaped }
name.length == 1 -> plots.find { it.name == name.unescaped } else -> (get(name.cutLast()) as? PlotGroup)?.get(name.last)
else -> (get(name.cutLast()) as? PlotGroup)?.get(name.last)
}
} }
/** /**
@ -203,9 +195,7 @@ class PlotGroup(override val name: String, descriptor: NodeDescriptor = NodeDes
* *
* @return * @return
*/ */
override fun iterator(): Iterator<Plottable> { override fun iterator(): Iterator<Plottable> = this.plots.iterator()
return this.plots.iterator()
}
class Wrapper : hep.dataforge.io.envelopes.Wrapper<PlotGroup> { class Wrapper : hep.dataforge.io.envelopes.Wrapper<PlotGroup> {

View File

@ -19,7 +19,7 @@ application {
mainClass.set("inr.numass.viewer.Viewer") mainClass.set("inr.numass.viewer.Viewer")
} }
version = "0.6.1" version = "0.6.2"
description = "The viewer for numass data" description = "The viewer for numass data"

View File

@ -12,6 +12,7 @@ import inr.numass.data.analyzers.NumassAnalyzer
import inr.numass.data.analyzers.withBinning import inr.numass.data.analyzers.withBinning
import javafx.beans.binding.DoubleBinding import javafx.beans.binding.DoubleBinding
import javafx.beans.property.SimpleBooleanProperty import javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.collections.FXCollections import javafx.collections.FXCollections
import javafx.collections.MapChangeListener import javafx.collections.MapChangeListener
@ -49,17 +50,17 @@ class AmplitudeView : View(title = "Numass amplitude spectrum plot", icon = Imag
}.setType<DataPlot>() }.setType<DataPlot>()
} }
val binningProperty = SimpleObjectProperty(20) val binningProperty = SimpleIntegerProperty(2)
var binning by binningProperty var binning: Int by binningProperty
val normalizeProperty = SimpleBooleanProperty(true) val normalizeProperty = SimpleBooleanProperty(true)
var normalize by normalizeProperty var normalize by normalizeProperty
private val plotContainer = PlotContainer(frame).apply { private val plotContainer = PlotContainer(frame).apply {
val binningSelector: ChoiceBox<Int> = ChoiceBox(FXCollections.observableArrayList(1, 2, 8, 16, 32, 50)).apply { val binningSelector: ChoiceBox<Int> = ChoiceBox(FXCollections.observableArrayList(1, 2, 8, 16, 32)).apply {
minWidth = 0.0 minWidth = 0.0
selectionModel.selectLast() selectionModel.select(binning as Int?)
binningProperty.bind(this.selectionModel.selectedItemProperty()) binningProperty.bind(this.selectionModel.selectedItemProperty())
} }
val normalizeSwitch: CheckBox = CheckBox("Normalize").apply { val normalizeSwitch: CheckBox = CheckBox("Normalize").apply {
@ -106,7 +107,11 @@ class AmplitudeView : View(title = "Numass amplitude spectrum plot", icon = Imag
private fun replotOne(key: String, point: DataController.CachedPoint) { private fun replotOne(key: String, point: DataController.CachedPoint) {
plotJobs[key]?.cancel() plotJobs[key]?.cancel()
frame.plots.remove(Name.ofSingle(key))
plotJobs[key] = app.context.launch { plotJobs[key] = app.context.launch {
withContext(Dispatchers.JavaFx) {
progress.invalidate()
}
val valueAxis = if (normalize) { val valueAxis = if (normalize) {
NumassAnalyzer.COUNT_RATE_KEY NumassAnalyzer.COUNT_RATE_KEY
} else { } else {
@ -134,7 +139,6 @@ class AmplitudeView : View(title = "Numass amplitude spectrum plot", icon = Imag
} }
group group
} }
ensureActive()
withContext(Dispatchers.JavaFx) { withContext(Dispatchers.JavaFx) {
frame.add(plot) frame.add(plot)
} }

View File

@ -40,15 +40,15 @@ class DataController : Controller(), ContextAware {
val meta = point.meta val meta = point.meta
val channelSpectra: Deferred<Map<Int, Table>> = context.async { val channelSpectra: Deferred<Map<Int, Table>> = context.async(start = CoroutineStart.LAZY) {
point.channels.mapValues { (_, value) -> analyzer.getAmplitudeSpectrum(value) } point.channels.mapValues { (_, value) -> analyzer.getAmplitudeSpectrum(value) }
} }
val spectrum: Deferred<Table> = context.async { val spectrum: Deferred<Table> = context.async(start = CoroutineStart.LAZY){
analyzer.getAmplitudeSpectrum(point) analyzer.getAmplitudeSpectrum(point)
} }
val timeSpectrum: Deferred<Table> = context.async { val timeSpectrum: Deferred<Table> = context.async(start = CoroutineStart.LAZY) {
val cr = spectrum.await().sumOf { val cr = spectrum.await().sumOf {
it.getValue(NumassAnalyzer.COUNT_KEY).int it.getValue(NumassAnalyzer.COUNT_KEY).int
}.toDouble() / point.length.toMillis() * 1000 }.toDouble() / point.length.toMillis() * 1000

View File

@ -40,7 +40,7 @@ class DirectoryWatchView : View(title = "Numass storage", icon = dfIconView) {
val name = Name.of(path.map { it.toString().asName() }) val name = Name.of(path.map { it.toString().asName() })
text = null text = null
graphic = checkbox(path.fileName.toString()).apply { graphic = checkbox(path.fileName.toString()).apply {
isSelected = false isSelected = dataController.points.containsKey(name)
selectedProperty().onChange { selectedProperty().onChange {
if (it) { if (it) {
app.context.launch { app.context.launch {

View File

@ -15,10 +15,8 @@ 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.NumberStringConverter import javafx.util.converter.NumberStringConverter
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.*
import kotlinx.coroutines.javafx.JavaFx import kotlinx.coroutines.javafx.JavaFx
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.controlsfx.control.RangeSlider import org.controlsfx.control.RangeSlider
import tornadofx.* import tornadofx.*
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
@ -117,18 +115,19 @@ class SpectrumView : View(title = "Numass spectrum plot", icon = ImageView(dfIco
val totalProgress = data.values.stream().mapToInt { it.points.size }.sum() val totalProgress = data.values.stream().mapToInt { it.points.size }.sum()
data.forEach { (name, set) -> data.forEach { (name, set) ->
val plot: DataPlot = val plot: DataPlot = frame.plots[name] as DataPlot? ?: DataPlot(name.toString()).apply {
frame.plots[name] as DataPlot? ?: DataPlot(name.toString()).apply { frame.add(this) } frame.add(this)
}
app.context.launch { app.context.launch {
val points = set.points.map { val points = set.points.map { point ->
dataController.getCachedPoint(Name.join("$name","${it.voltage}[${it.index}]"), it) dataController.getCachedPoint(Name.join("$name","${point.voltage}[${point.index}]"), point).also {
it.spectrum.start()
}
}.map { cachedPoint -> }.map { cachedPoint ->
val count = cachedPoint.spectrum.await().countInWindow(loChannel.toShort(), upChannel.toShort()) val count = cachedPoint.spectrum.await().countInWindow(loChannel.toShort(), upChannel.toShort())
val seconds = cachedPoint.length.toMillis() / 1000.0 val seconds = cachedPoint.length.toMillis() / 1000.0
launch(Dispatchers.JavaFx) {
container.progress = progress.incrementAndGet().toDouble() / totalProgress
}
Adapters.buildXYDataPoint( Adapters.buildXYDataPoint(
cachedPoint.voltage, cachedPoint.voltage,
(count / seconds), (count / seconds),