diff --git a/dataforge-core/src/main/kotlin/hep/dataforge/workspace/FileBasedWorkspace.kt b/dataforge-core/src/main/kotlin/hep/dataforge/workspace/FileBasedWorkspace.kt index 4ddc61f6..a3ecac96 100644 --- a/dataforge-core/src/main/kotlin/hep/dataforge/workspace/FileBasedWorkspace.kt +++ b/dataforge-core/src/main/kotlin/hep/dataforge/workspace/FileBasedWorkspace.kt @@ -14,7 +14,10 @@ import java.security.MessageDigest /** * Dynamic workspace that is parsed from file using external algorithm. Workspace is reloaded only if file is changed */ -class FileBasedWorkspace(private val path: Path, private val parser: (Path) -> Workspace) : DynamicWorkspace(), AutoCloseable { +class FileBasedWorkspace( + private val path: Path, + private val parser: (Path) -> Workspace +) : DynamicWorkspace(), AutoCloseable { private var watchJob: Job? = null @@ -28,7 +31,7 @@ class FileBasedWorkspace(private val path: Path, private val parser: (Path) -> W watchJob = GlobalScope.launch { while (true) { fileMonitor.pollEvents().forEach { - if(it.context() == path) { + if (it.context() == path) { logger.info("Workspace configuration changed. Invalidating.") invalidate() } @@ -69,15 +72,19 @@ class FileBasedWorkspace(private val path: Path, private val parser: (Path) -> W */ @JvmOverloads @JvmStatic - fun build(context: Context, path: Path, transformation: (Workspace.Builder) -> Workspace = { it.build() }): FileBasedWorkspace { + fun build( + context: Context, + path: Path, + transformation: (Workspace.Builder) -> Workspace = { it.build() } + ): FileBasedWorkspace { val fileName = path.fileName.toString() return context.serviceStream(WorkspaceParser::class.java) - .filter { parser -> parser.listExtensions().stream().anyMatch { fileName.endsWith(it) } } - .findFirst() - .map { parser -> - FileBasedWorkspace(path) { p -> transformation(parser.parse(context, p)) } - } - .orElseThrow { RuntimeException("Workspace parser for $path not found") } + .filter { parser -> parser.listExtensions().stream().anyMatch { fileName.endsWith(it) } } + .findFirst() + .map { parser -> + FileBasedWorkspace(path) { p -> transformation(parser.parse(context, p)) } + } + .orElseThrow { RuntimeException("Workspace parser for $path not found") } } fun build(path: Path): Workspace { diff --git a/dataforge-gui/gui-demo/build.gradle b/dataforge-gui/gui-demo/build.gradle index d5bc2f99..a1f2a95a 100644 --- a/dataforge-gui/gui-demo/build.gradle +++ b/dataforge-gui/gui-demo/build.gradle @@ -1,9 +1,15 @@ plugins{ id "application" id "com.github.johnrengelman.shadow" + id "org.openjfx.javafxplugin" } apply plugin: 'kotlin' +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" +} + if (!hasProperty('mainClass')) { ext.mainClass = 'hep.dataforge.plots.demo.DemoApp'//"inr.numass.viewer.test.TestApp" } diff --git a/dataforge-plots/plots-jfc/build.gradle b/dataforge-plots/plots-jfc/build.gradle deleted file mode 100644 index 7cd2b25c..00000000 --- a/dataforge-plots/plots-jfc/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -//apply plugin: 'org.openjfx.javafxplugin' -// -//javafx { -// modules = [ 'javafx.controls' ] -//} - - -description = 'jFreeChart plugin' - -dependencies { - api 'org.jfree:jfreesvg:3.3' - // https://mvnrepository.com/artifact/org.jfree/jfreechart-fx - api group: 'org.jfree', name: 'jfreechart-fx', version: '1.0.1' - - api project(":dataforge-plots") -} \ No newline at end of file diff --git a/dataforge-plots/plots-jfc/build.gradle.kts b/dataforge-plots/plots-jfc/build.gradle.kts new file mode 100644 index 00000000..ff8cb75f --- /dev/null +++ b/dataforge-plots/plots-jfc/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + id("org.openjfx.javafxplugin") +} + +javafx { + modules = listOf("javafx.controls") + version = "11" +} + +description = "jFreeChart plugin" + +dependencies { + api("org.jfree:jfreesvg:3.4.2") + // https://mvnrepository.com/artifact/org.jfree/org.jfree.chart.fx + api(group= "org.jfree", name= "jfreechart-fx", version= "1.0.1") + + + api(project(":dataforge-plots")) +} \ No newline at end of file diff --git a/dataforge-plots/plots-viewer/build.gradle b/dataforge-plots/plots-viewer/build.gradle index a439114d..4e98362f 100644 --- a/dataforge-plots/plots-viewer/build.gradle +++ b/dataforge-plots/plots-viewer/build.gradle @@ -1,6 +1,12 @@ plugins { id "com.github.johnrengelman.shadow" id 'application' + id "org.openjfx.javafxplugin" +} + +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" } apply plugin: "kotlin" diff --git a/grind/grind-terminal/build.gradle b/grind/grind-terminal/build.gradle index fd1384b2..994d308f 100644 --- a/grind/grind-terminal/build.gradle +++ b/grind/grind-terminal/build.gradle @@ -2,6 +2,12 @@ plugins { id 'groovy' id 'application' id "com.github.johnrengelman.shadow" + id "org.openjfx.javafxplugin" +} + +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" } diff --git a/numass-control/build.gradle b/numass-control/build.gradle index ebe96e60..3275bc04 100644 --- a/numass-control/build.gradle +++ b/numass-control/build.gradle @@ -1,3 +1,13 @@ +plugins { + id("org.openjfx.javafxplugin") +} + +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" +} + + dependencies { api project(':dataforge-plots:plots-jfc') api project(':dataforge-control') diff --git a/numass-control/cryotemp/build.gradle b/numass-control/cryotemp/build.gradle index 0b8ff45f..34a8e7c6 100644 --- a/numass-control/cryotemp/build.gradle +++ b/numass-control/cryotemp/build.gradle @@ -1,3 +1,13 @@ + +plugins{ + id "org.openjfx.javafxplugin" +} + +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" +} + apply plugin: 'application' apply plugin: 'kotlin' diff --git a/numass-control/gun/build.gradle b/numass-control/gun/build.gradle index 0ffaeb30..91108f6b 100644 --- a/numass-control/gun/build.gradle +++ b/numass-control/gun/build.gradle @@ -1,17 +1,15 @@ -// -//plugins { -// id 'application' -// id 'org.openjfx.javafxplugin' version '0.0.5' -//} -// -//javafx { -// modules = [ 'javafx.controls' ] -//} -plugins { +plugins{ id 'application' + id "org.openjfx.javafxplugin" } +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" +} + + version = "0.1.0" if (!hasProperty('mainClass')) { diff --git a/numass-control/magnet/build.gradle b/numass-control/magnet/build.gradle index 3bc1e6de..513e2e00 100644 --- a/numass-control/magnet/build.gradle +++ b/numass-control/magnet/build.gradle @@ -1,4 +1,13 @@ -apply plugin: 'application' + +plugins{ + id 'application' + id "org.openjfx.javafxplugin" +} + +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" +} version = "0.3.0" diff --git a/numass-control/msp/build.gradle b/numass-control/msp/build.gradle index dfe63f8d..d84fd71a 100644 --- a/numass-control/msp/build.gradle +++ b/numass-control/msp/build.gradle @@ -1,4 +1,12 @@ -apply plugin: 'application' +plugins{ + id 'application' + id "org.openjfx.javafxplugin" +} + +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" +} version = "0.4.0" diff --git a/numass-control/vac/build.gradle b/numass-control/vac/build.gradle index 8fc97f47..9e727fc0 100644 --- a/numass-control/vac/build.gradle +++ b/numass-control/vac/build.gradle @@ -1,4 +1,12 @@ -apply plugin: 'application' +plugins{ + id 'application' + id "org.openjfx.javafxplugin" +} + +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" +} version = "0.6.0" diff --git a/numass-control/vac/src/main/kotlin/inr/numass/control/readvac/MeradatVacDevice.kt b/numass-control/vac/src/main/kotlin/inr/numass/control/readvac/MeradatVacDevice.kt index ff1428d0..43630e76 100644 --- a/numass-control/vac/src/main/kotlin/inr/numass/control/readvac/MeradatVacDevice.kt +++ b/numass-control/vac/src/main/kotlin/inr/numass/control/readvac/MeradatVacDevice.kt @@ -81,9 +81,9 @@ class MeradatVacDevice(context: Context, meta: Meta) : PortSensor(context, meta) * String is Hex String, need to convert in ASCII. */ val bytes = BigInteger(inputString, 16).toByteArray() - val checksum = bytes.sumBy { it.toInt() } + val checksum = bytes.sumOf { it.toInt() } var value = Integer.toHexString(-checksum) - value = value.substring(value.length - 2).toUpperCase() + value = value.substring(value.length - 2).uppercase() if (value.length < 2) { value = "0$value" } diff --git a/numass-control/vac/src/main/kotlin/inr/numass/control/readvac/ThyroContVacDevice.kt b/numass-control/vac/src/main/kotlin/inr/numass/control/readvac/ThyroContVacDevice.kt index 130cc294..a213aeb2 100644 --- a/numass-control/vac/src/main/kotlin/inr/numass/control/readvac/ThyroContVacDevice.kt +++ b/numass-control/vac/src/main/kotlin/inr/numass/control/readvac/ThyroContVacDevice.kt @@ -23,7 +23,7 @@ class ThyroContVacDevice(context: Context, meta: Meta) : PortSensor(context, met return GenericPortController(context, port) { it.endsWith("\r") } } - private fun String.checksum(): Char = (sumBy { it.code } % 64 + 64).toChar() + private fun String.checksum(): Char = (sumOf { it.code } % 64 + 64).toChar() private fun wrap(str: String): String = buildString { append(str) diff --git a/numass-core/src/main/kotlin/inr/numass/data/analyzers/AbstractAnalyzer.kt b/numass-core/src/main/kotlin/inr/numass/data/analyzers/AbstractAnalyzer.kt index 9a288d0f..f7c1eceb 100644 --- a/numass-core/src/main/kotlin/inr/numass/data/analyzers/AbstractAnalyzer.kt +++ b/numass-core/src/main/kotlin/inr/numass/data/analyzers/AbstractAnalyzer.kt @@ -59,7 +59,7 @@ abstract class AbstractAnalyzer @JvmOverloads constructor(private val processor: protected fun getAllEvents(block: NumassBlock): Stream { return when { block.frames.count() == 0L -> block.events - processor == null -> throw IllegalArgumentException("Signal processor needed to analyze frames") + processor == null -> block.events//throw IllegalArgumentException("Signal processor needed to analyze frames") else -> Stream.concat(block.events, block.frames.flatMap { processor.process(block, it) }) } } diff --git a/numass-main/build.gradle b/numass-main/build.gradle index 2e9f254d..a895c4a5 100644 --- a/numass-main/build.gradle +++ b/numass-main/build.gradle @@ -1,6 +1,12 @@ plugins { id 'groovy' id 'application' + id "org.openjfx.javafxplugin" +} + +javafx { + modules = ["javafx.controls", "javafx.web"] + version = "11" } apply plugin: 'kotlin' diff --git a/numass-main/src/main/kotlin/inr/numass/scripts/analysis/test_data.kt b/numass-main/src/main/kotlin/inr/numass/scripts/analysis/test_data.kt new file mode 100644 index 00000000..eb49dd95 --- /dev/null +++ b/numass-main/src/main/kotlin/inr/numass/scripts/analysis/test_data.kt @@ -0,0 +1,29 @@ +package inr.numass.scripts.analysis + +import hep.dataforge.context.Global +import hep.dataforge.fx.output.FXOutputManager +import hep.dataforge.plots.jfreechart.JFreeChartPlugin +import inr.numass.data.ProtoNumassPoint +import java.io.File + +fun main() { + Global.output = FXOutputManager() + JFreeChartPlugin().startGlobal() + + val file = File("C:\\Users\\darksnake\\Desktop\\test-data\\p20211012142003(20s)").toPath() + val point = ProtoNumassPoint.readFile(file) + + point.events.forEach { + println("channel: ${it.owner.channel}, startTime: ${it.owner.startTime} timeOffset: ${it.timeOffset}\t amp: ${it.amplitude}") + } + +// Global.plotFrame("compare") { +// plotAmplitudeSpectrum(point, "cut") { +// "t0" to 3e3 +// "sortEvents" to true +// } +// plotAmplitudeSpectrum(point, "uncut") +// } +// +// readLine() +} \ No newline at end of file diff --git a/numass-main/src/main/kotlin/inr/numass/scripts/models/detectionEfficiency.kt b/numass-main/src/main/kotlin/inr/numass/scripts/models/detectionEfficiency.kt index 3fa8c47a..8d6c6355 100644 --- a/numass-main/src/main/kotlin/inr/numass/scripts/models/detectionEfficiency.kt +++ b/numass-main/src/main/kotlin/inr/numass/scripts/models/detectionEfficiency.kt @@ -18,6 +18,7 @@ package inr.numass.scripts.models import hep.dataforge.buildContext import hep.dataforge.configure +import hep.dataforge.data.NamedData import hep.dataforge.fx.FXPlugin import hep.dataforge.fx.output.FXOutputManager import hep.dataforge.meta.Meta @@ -26,23 +27,23 @@ import hep.dataforge.plots.data.DataPlot import hep.dataforge.plots.jfreechart.JFreeChartPlugin import hep.dataforge.plots.output.plotFrame import hep.dataforge.plots.plotFunction +import hep.dataforge.stat.fit.FitHelper import hep.dataforge.stat.fit.FitManager import hep.dataforge.stat.fit.FitStage -import hep.dataforge.stat.fit.FitState import hep.dataforge.stat.fit.ParamSet import hep.dataforge.stat.models.XYModel import hep.dataforge.step -import hep.dataforge.tables.Adapters.X_AXIS +import hep.dataforge.tables.Adapters import hep.dataforge.tables.Table -import hep.dataforge.values.ValueMap +import hep.dataforge.workspace.FileBasedWorkspace import inr.numass.NumassPlugin -import inr.numass.data.SpectrumAdapter -import inr.numass.data.SpectrumGenerator +import inr.numass.data.analyzers.NumassAnalyzer +import inr.numass.data.api.NumassPoint import inr.numass.models.NBkgSpectrum import inr.numass.models.sterile.NumassResolution import inr.numass.models.sterile.SterileNeutrinoSpectrum import org.apache.commons.math3.analysis.interpolation.SplineInterpolator -import java.io.PrintWriter +import java.io.File private fun getCustomResolution(): NumassResolution { val correctionDataString = """ @@ -84,16 +85,19 @@ fun main() { JFreeChartPlugin::class.java ) { output = FXOutputManager() + properties { + setValue("cache.enabled", false) + } } val params = ParamSet().apply { - setPar("N", 8e5, 6.0, 0.0, Double.POSITIVE_INFINITY) - setPar("bkg", 2.0, 0.03) + setPar("N", 8e5, 1e4, 0.0, Double.POSITIVE_INFINITY) + setPar("bkg", 3.0, 0.03) setPar("E0", 18575.0, 1.0) setPar("mnu2", 0.0, 1.0) setParValue("msterile2", (1000 * 1000).toDouble()) setPar("U2", 0.0, 1e-3) - setPar("X", 0.0, 0.01) + setPar("X", 0.1, 0.01) setPar("trap", 1.0, 0.01) } @@ -122,36 +126,63 @@ fun main() { val t = 30 * 50 // time in seconds per point - val adapter = SpectrumAdapter(Meta.empty()) + val adapter = Adapters.buildXYAdapter( + NumassPoint.HV_KEY, + NumassAnalyzer.COUNT_RATE_KEY, + NumassAnalyzer.COUNT_RATE_ERROR_KEY + ) + val fm = context.getOrLoad(FitManager::class.java) val x = (14000.0..18500.0).step(100.0).toList() - val dataModel = XYModel(Meta.empty(), adapter, dataSpectrum) - val generator = SpectrumGenerator(dataModel, params, 12316) - - val configuration = x.map { ValueMap.ofPairs(X_AXIS to it, "time" to t) } - val data: Table = generator.generateData(configuration) + // define the data model + val modifiedModel = XYModel(Meta.empty(), adapter, dataSpectrum) +// // Simulating data via model +// val generator = SpectrumGenerator(dataModel, params, 12316) +// val configuration = x.map { ValueMap.ofPairs(X_AXIS to it, "time" to t) } +// val simulatedData: Table = generator.generateData(configuration) +// +// // Creating a model which does not know about distortion val modelSpectrum = NBkgSpectrum(SterileNeutrinoSpectrum(context, Meta.empty(), resolution = NumassResolution())) val fitModel = XYModel(Meta.empty(), adapter, modelSpectrum) +// +// context.plotFrame("fit", stage = "plots") { +// plots.configure { +// "showLine" to true +// "showSymbol" to false +// "showErrors" to false +// "thickness" to 4.0 +// } +// plots.setType() +// +dataModel.plot("Data", params) +// +fitModel.plot("Fit-start", params) +// } +// +// //fitting +// val state = FitState(simulatedData, fitModel, params) +// val res = fm.runStage(state, "QOW", FitStage.TASK_RUN, "N", "E0", "bkg") +// res.printState(PrintWriter(System.out)) +// val resWithTrap = fm.runStage(state, "QOW", FitStage.TASK_RUN, "N", "E0", "bkg", "trap") +// resWithTrap.printState(PrintWriter(System.out)) +// val resWithU2 = fm.runStage(resWithTrap.optState().get(), "QOW", FitStage.TASK_RUN, "N", "E0", "bkg", "trap", "U2") +// resWithU2.printState(PrintWriter(System.out)) - context.plotFrame("fit", stage = "plots") { - plots.configure { - "showLine" to true - "showSymbol" to false - "showErrors" to false - "thickness" to 4.0 - } - plots.setType() - +dataModel.plot("Data", params) - +fitModel.plot("Fit-start", params) - } + // loading real data + val configPath = File("D:\\Work\\Numass\\sterile2017_11\\workspace.groovy").toPath() + val workspace = FileBasedWorkspace.build(context, configPath) + + val data = workspace.runTask("filter", "fill_2").first() as NamedData + val table = data.get() + + //fitting + FitHelper(context).fit(table).apply { + model(modifiedModel) + report("fit") + params(params) + stage("QOW", FitStage.TASK_RUN, "N", "E0", "bkg") + stage("QOW", FitStage.TASK_RUN, "N", "E0", "bkg", "trap") + stage("QOW", FitStage.TASK_RUN, "N", "E0", "bkg", "trap", "U2") + }.run() - val state = FitState(data, fitModel, params) - val res = fm.runStage(state, "QOW", FitStage.TASK_RUN, "N", "E0", "bkg") - res.printState(PrintWriter(System.out)) - val resWithTrap = fm.runStage(state, "QOW", FitStage.TASK_RUN, "N", "E0", "bkg", "trap") - resWithTrap.printState(PrintWriter(System.out)) - val resWithU2 = fm.runStage(resWithTrap.optState().get(), "QOW", FitStage.TASK_RUN, "N", "E0", "bkg", "trap", "U2") - resWithU2.printState(PrintWriter(System.out)) } \ No newline at end of file