Add renderers
This commit is contained in:
parent
d1ddf89c6e
commit
7d053d4fa9
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,6 +4,6 @@
|
|||||||
out/
|
out/
|
||||||
.gradle
|
.gradle
|
||||||
build/
|
build/
|
||||||
|
/notebooks/.ipynb_checkpoints
|
||||||
|
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
@ -9,15 +9,15 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "ru.inr.mass"
|
group = "ru.inr.mass"
|
||||||
version = "0.1.0-dev-1"
|
version = "0.1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion by extra("0.5.2")
|
val dataforgeVersion by extra("0.5.2")
|
||||||
val tablesVersion: String by extra("0.1.1")
|
val tablesVersion: String by extra("0.1.2")
|
||||||
val kmathVersion by extra("0.3.0-dev-17")
|
val kmathVersion by extra("0.3.0-dev-17")
|
||||||
val plotlyVersion: String by extra("0.5.0")
|
val plotlyVersion: String by extra("0.5.0")
|
||||||
|
|
||||||
ksciencePublish{
|
ksciencePublish{
|
||||||
git("https://mipt-npm.jetbrains.space/p/numass/code/numass/")
|
github("numass")
|
||||||
space("https://maven.pkg.jetbrains.space/mipt-npm/p/numass/maven")
|
space("https://maven.pkg.jetbrains.space/mipt-npm/p/numass/maven")
|
||||||
}
|
}
|
140
notebooks/jupyter-demo.ipynb
Normal file
140
notebooks/jupyter-demo.ipynb
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "2a640dcc-4696-408f-b1f0-0cdf917e4719",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"@file:Repository(\"https://repo.kotlin.link\")\n",
|
||||||
|
"@file:Repository(\"*mavenLocal\")\n",
|
||||||
|
"@file:DependsOn(\"ru.inr.mass:numass-workspace:0.1.0\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "2d193fb2-6c18-4c64-b5c3-3e9ed4099d5b",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"val repo: DataTree<NumassDirectorySet> = Numass.readNumassRepository(\"D:\\\\Work\\\\Numass\\\\data\\\\test\")\n",
|
||||||
|
"repo"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "373de92b-2533-4cfc-820b-ca90b9d028fc",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"val numassSet = repo[\"set_7\"]\n",
|
||||||
|
"numassSet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "d0845a15-2928-4e6e-a891-fee130ef5326",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"val point = numassSet.points.first{it.voltage == 14000.0}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "842dfbcb-17f0-4df9-b5d4-2835f15f3a50",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"point"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "50df6925-82f5-4330-a1c2-3e43fb9cd17d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"Plotly.plotNumassBlock(point, eventExtractor = NumassEventExtractor.TQDC)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "196f94ca-0439-4190-bda7-8d692c37b2db",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"val frames = point.listFrames()\n",
|
||||||
|
"Plotly.page {\n",
|
||||||
|
" p { +\"${frames.size} frames\" }\n",
|
||||||
|
" h2 { +\"Random frames\" }\n",
|
||||||
|
" plot {\n",
|
||||||
|
" val random = kotlin.random.Random(1234)\n",
|
||||||
|
"\n",
|
||||||
|
" repeat(10) {\n",
|
||||||
|
" val frame = frames.random(random)\n",
|
||||||
|
" scatter {\n",
|
||||||
|
" y.numbers = frame.signal.map { (it.toUShort().toInt() - Short.MAX_VALUE).toShort() }\n",
|
||||||
|
" }\n",
|
||||||
|
" }\n",
|
||||||
|
" }\n",
|
||||||
|
" h2 { +\"Analysis\" }\n",
|
||||||
|
" plot {\n",
|
||||||
|
" histogram {\n",
|
||||||
|
" name = \"max\"\n",
|
||||||
|
" x.numbers = frames.map { frame -> frame.signal.maxOf { (it.toUShort().toInt() - Short.MAX_VALUE).toShort() } }\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" histogram {\n",
|
||||||
|
" name = \"max-min\"\n",
|
||||||
|
" xbins {\n",
|
||||||
|
" size = 2.0\n",
|
||||||
|
" }\n",
|
||||||
|
" x.numbers = frames.map { frame ->\n",
|
||||||
|
" frame.signal.maxOf { it.toUShort().toInt() - Short.MAX_VALUE } -\n",
|
||||||
|
" frame.signal.minOf { it.toUShort().toInt() - Short.MAX_VALUE }\n",
|
||||||
|
" }\n",
|
||||||
|
" }\n",
|
||||||
|
" }\n",
|
||||||
|
"}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "5320d9d5-eae3-469b-a1f2-5d33d3db286c",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Kotlin",
|
||||||
|
"language": "kotlin",
|
||||||
|
"name": "kotlin"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": "text/x-kotlin",
|
||||||
|
"file_extension": ".kt",
|
||||||
|
"mimetype": "text/x-kotlin",
|
||||||
|
"name": "kotlin",
|
||||||
|
"nbconvert_exporter": "",
|
||||||
|
"pygments_lexer": "kotlin",
|
||||||
|
"version": "1.6.20-dev-6372"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"imports": [
|
|
||||||
"kscience.plotly.*",
|
|
||||||
"kscience.plotly.models.*",
|
|
||||||
"kscience.plotly.JupyterPlotly",
|
|
||||||
"space.kscience.dataforge.meta.*",
|
|
||||||
"kotlinx.html.*",
|
|
||||||
"ru.inr.mass.workspace.*"
|
|
||||||
],
|
|
||||||
"repositories": [
|
|
||||||
"*mavenLocal",
|
|
||||||
"https://dl.bintray.com/mipt-npm/dataforge",
|
|
||||||
"https://dl.bintray.com/mipt-npm/kscience",
|
|
||||||
"https://dl.bintray.com/mipt-npm/dev",
|
|
||||||
"https://kotlin.bintray.com/kotlinx"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"v": "0.1.0-SNAPSHOT"
|
|
||||||
},
|
|
||||||
"link": "https://mipt-npm.jetbrains.space/p/numass/code/numass",
|
|
||||||
"dependencies": [
|
|
||||||
"ru.inr.mass:numass-workspace:$v"
|
|
||||||
],
|
|
||||||
"init": [
|
|
||||||
"DISPLAY(HTML(JupyterPlotly.loadJs().toString()))",
|
|
||||||
"DISPLAY(HTML(\"<p>Plotly.kt jupyter integration is in the development phase. Expect glitches!</p>\"))"
|
|
||||||
],
|
|
||||||
"renderers": {
|
|
||||||
"kscience.plotly.HtmlFragment": "HTML($it.toString())",
|
|
||||||
"kscience.plotly.Plot": "HTML(JupyterPlotly.renderPlot($it))",
|
|
||||||
"kscience.plotly.PlotlyFragment": "HTML(JupyterPlotly.renderFragment($it))",
|
|
||||||
"kscience.plotly.PlotlyPage": "HTML(JupyterPlotly.renderPage($it), true)",
|
|
||||||
"ru.inr.mass.data.proto.NumassDirectorySet": "HTML(JupyterPlotly.renderPage(${it.plotlyPage()}), true)"
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,7 +12,9 @@ public class NumassAmplitudeSpectrum(public val amplitudes: Map<UShort, ULong>)
|
|||||||
public val minChannel: UShort by lazy { amplitudes.keys.minOf { it } }
|
public val minChannel: UShort by lazy { amplitudes.keys.minOf { it } }
|
||||||
public val maxChannel: UShort by lazy { amplitudes.keys.maxOf { it } }
|
public val maxChannel: UShort by lazy { amplitudes.keys.maxOf { it } }
|
||||||
|
|
||||||
public fun binned(binSize: UInt, range: UIntRange = minChannel..maxChannel): Map<UIntRange, Double> {
|
public val channels: UIntRange by lazy { minChannel..maxChannel }
|
||||||
|
|
||||||
|
public fun binned(binSize: UInt, range: UIntRange = channels): Map<UIntRange, Double> {
|
||||||
val keys = sequence {
|
val keys = sequence {
|
||||||
var left = range.first
|
var left = range.first
|
||||||
do {
|
do {
|
||||||
@ -24,6 +26,9 @@ public class NumassAmplitudeSpectrum(public val amplitudes: Map<UShort, ULong>)
|
|||||||
|
|
||||||
return keys.associateWith { bin -> amplitudes.filter { it.key in bin }.values.sum().toDouble() }
|
return keys.associateWith { bin -> amplitudes.filter { it.key in bin }.values.sum().toDouble() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun sum(range: UIntRange = channels): ULong =
|
||||||
|
amplitudes.filter { it.key in range }.values.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,9 +15,9 @@ public class TimeAnalyzerParameters : Scheme() {
|
|||||||
/**
|
/**
|
||||||
* The relative fraction of events that should be removed by time cut
|
* The relative fraction of events that should be removed by time cut
|
||||||
*/
|
*/
|
||||||
public var crFraction by double()
|
public var crFraction: Double? by double()
|
||||||
public var min by double(0.0)
|
public var min: Double by double(0.0)
|
||||||
public var crMin by double(0.0)
|
public var crMin: Double by double(0.0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of events in chunk to split the chain into. If null, no chunks are used
|
* The number of events in chunk to split the chain into. If null, no chunks are used
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ru.inr.mass.data.analysis
|
package ru.inr.mass.data.analysis
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import ru.inr.mass.data.api.NumassBlock
|
import ru.inr.mass.data.api.NumassBlock
|
||||||
import ru.inr.mass.data.api.NumassEvent
|
import ru.inr.mass.data.api.NumassEvent
|
||||||
|
|
||||||
@ -12,6 +13,30 @@ public fun interface NumassEventExtractor {
|
|||||||
* A default event extractor that ignores frames
|
* A default event extractor that ignores frames
|
||||||
*/
|
*/
|
||||||
public val EVENTS_ONLY: NumassEventExtractor = NumassEventExtractor { it.events }
|
public val EVENTS_ONLY: NumassEventExtractor = NumassEventExtractor { it.events }
|
||||||
|
public val TQDC: NumassEventExtractor = NumassEventExtractor { block ->
|
||||||
|
block.frames.map { frame ->
|
||||||
|
var max = 0
|
||||||
|
var min = 0
|
||||||
|
var indexOfMax = 0
|
||||||
|
|
||||||
|
frame.signal.forEachIndexed { index, sh ->
|
||||||
|
val corrected = sh.toUShort().toInt() - Short.MAX_VALUE
|
||||||
|
if (corrected >= max) {
|
||||||
|
max = corrected
|
||||||
|
indexOfMax = index
|
||||||
|
}
|
||||||
|
if (corrected <= min) {
|
||||||
|
min = corrected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NumassEvent(
|
||||||
|
(max - min).toShort().toUShort(),
|
||||||
|
frame.timeOffset + frame.tickSize.inWholeNanoseconds * indexOfMax,
|
||||||
|
block
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import ru.inr.mass.data.api.NumassBlock
|
|||||||
import ru.inr.mass.data.api.getTime
|
import ru.inr.mass.data.api.getTime
|
||||||
import space.kscience.kmath.histogram.UnivariateHistogram
|
import space.kscience.kmath.histogram.UnivariateHistogram
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
import kotlin.time.DurationUnit
|
||||||
|
|
||||||
public fun <T, R> Flow<T>.zipWithNext(block: (l: T, r: T) -> R): Flow<R> {
|
public fun <T, R> Flow<T>.zipWithNext(block: (l: T, r: T) -> R): Flow<R> {
|
||||||
var current: T? = null
|
var current: T? = null
|
||||||
@ -26,7 +27,7 @@ public fun NumassBlock.timeHistogram(
|
|||||||
runBlocking {
|
runBlocking {
|
||||||
extractor.extract(this@timeHistogram).zipWithNext { l, r ->
|
extractor.extract(this@timeHistogram).zipWithNext { l, r ->
|
||||||
if(l.owner == r.owner) {
|
if(l.owner == r.owner) {
|
||||||
max((r.getTime() - l.getTime()).inWholeMicroseconds,0L)
|
max((r.getTime() - l.getTime()).toDouble(DurationUnit.SECONDS),0.0)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package ru.inr.mass.data.api
|
package ru.inr.mass.data.api
|
||||||
|
|
||||||
import kotlinx.datetime.Instant
|
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The continuous frame of digital detector data
|
* The continuous frame of digital detector data
|
||||||
* Created by darksnake on 06-Jul-17.
|
* Created by darksnake on 06-Jul-17.
|
||||||
* @param time The absolute start time of the frame
|
* @param timeOffset The time offset relative to block start in nanos
|
||||||
* @param tickSize The time interval per tick
|
* @param tickSize The time interval per tick
|
||||||
* @param signal The buffered signal shape in ticks
|
* @param signal The buffered signal shape in ticks
|
||||||
*/
|
*/
|
||||||
public class NumassFrame(
|
public class NumassFrame(
|
||||||
public val time: Instant,
|
public val timeOffset: Long,
|
||||||
public val tickSize: Duration,
|
public val tickSize: Duration,
|
||||||
public val signal: ShortArray,
|
public val signal: ShortArray,
|
||||||
) {
|
) {
|
||||||
|
@ -89,6 +89,8 @@ public interface NumassPoint : ParentBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public val NumassPoint.title: String get() = "p$index(HV=$voltage)"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the first block if it exists. Throw runtime exception otherwise.
|
* Get the first block if it exists. Throw runtime exception otherwise.
|
||||||
*
|
*
|
||||||
|
@ -19,9 +19,7 @@ package ru.inr.mass.data.proto
|
|||||||
import io.ktor.utils.io.core.readBytes
|
import io.ktor.utils.io.core.readBytes
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.datetime.DateTimeUnit
|
|
||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
import kotlinx.datetime.plus
|
|
||||||
import okio.ByteString
|
import okio.ByteString
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import ru.inr.mass.data.api.*
|
import ru.inr.mass.data.api.*
|
||||||
@ -202,9 +200,9 @@ public class ProtoNumassBlock(
|
|||||||
get() {
|
get() {
|
||||||
val tickSize = block.bin_size.nanoseconds
|
val tickSize = block.bin_size.nanoseconds
|
||||||
return block.frames.asFlow().map { frame ->
|
return block.frames.asFlow().map { frame ->
|
||||||
val time = startTime.plus(frame.time, DateTimeUnit.NANOSECOND)
|
//val time = startTime.plus(frame.time, DateTimeUnit.NANOSECOND)
|
||||||
val frameData = frame.data_
|
val frameData = frame.data_
|
||||||
NumassFrame(time, tickSize, frameData.toShortArray())
|
NumassFrame(frame.time, tickSize, frameData.toShortArray())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class TestNumassDirectory {
|
|||||||
fun testTQDCRead() = runBlocking {
|
fun testTQDCRead() = runBlocking {
|
||||||
val pointPath = Path.of("src/test/resources", "testData/tqdc")
|
val pointPath = Path.of("src/test/resources", "testData/tqdc")
|
||||||
val set: NumassSet = context.readNumassDirectory(pointPath)
|
val set: NumassSet = context.readNumassDirectory(pointPath)
|
||||||
val point = set.first { it.voltage == 16000.0 }
|
val point = set.first { it.voltage == 18200.0 }
|
||||||
point.getChannels().forEach { (channel, block) ->
|
point.getChannels().forEach { (channel, block) ->
|
||||||
println("$channel: $block")
|
println("$channel: $block")
|
||||||
if(block is ParentBlock){
|
if(block is ParentBlock){
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
id("ru.mipt.npm.gradle.jvm")
|
||||||
id("ru.mipt.npm.gradle.common")
|
id("com.github.johnrengelman.shadow") version "7.1.1"
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11,6 +11,7 @@ kotlin {
|
|||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
val plotlyVersion: String by rootProject.extra
|
val plotlyVersion: String by rootProject.extra
|
||||||
val kmathVersion: String by rootProject.extra
|
val kmathVersion: String by rootProject.extra
|
||||||
|
val tablesVersion: String by rootProject.extra
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(projects.numassDataProto)
|
implementation(projects.numassDataProto)
|
||||||
@ -19,6 +20,7 @@ dependencies {
|
|||||||
implementation("space.kscience:dataforge-workspace:$dataforgeVersion")
|
implementation("space.kscience:dataforge-workspace:$dataforgeVersion")
|
||||||
implementation("space.kscience:plotlykt-jupyter:$plotlyVersion")
|
implementation("space.kscience:plotlykt-jupyter:$plotlyVersion")
|
||||||
implementation("space.kscience:kmath-jupyter:$kmathVersion")
|
implementation("space.kscience:kmath-jupyter:$kmathVersion")
|
||||||
|
implementation("space.kscience:tables-kt:$tablesVersion")
|
||||||
}
|
}
|
||||||
|
|
||||||
kscience{
|
kscience{
|
||||||
|
@ -4,10 +4,17 @@ package ru.inr.mass.notebook
|
|||||||
import org.jetbrains.kotlinx.jupyter.api.HTML
|
import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||||
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
|
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
|
||||||
import ru.inr.mass.data.api.NumassBlock
|
import ru.inr.mass.data.api.NumassBlock
|
||||||
|
import ru.inr.mass.data.api.NumassFrame
|
||||||
import ru.inr.mass.data.api.NumassSet
|
import ru.inr.mass.data.api.NumassSet
|
||||||
|
import ru.inr.mass.data.proto.NumassDirectorySet
|
||||||
import ru.inr.mass.workspace.Numass
|
import ru.inr.mass.workspace.Numass
|
||||||
import ru.inr.mass.workspace.numassSet
|
import ru.inr.mass.workspace.plotNumassBlock
|
||||||
|
import ru.inr.mass.workspace.plotNumassSet
|
||||||
|
import space.kscience.dataforge.data.DataTree
|
||||||
import space.kscience.plotly.Plotly
|
import space.kscience.plotly.Plotly
|
||||||
|
import space.kscience.plotly.scatter
|
||||||
|
import space.kscience.plotly.toHTML
|
||||||
|
import space.kscience.plotly.toPage
|
||||||
|
|
||||||
internal class NumassJupyter : JupyterIntegration() {
|
internal class NumassJupyter : JupyterIntegration() {
|
||||||
override fun Builder.onLoaded() {
|
override fun Builder.onLoaded() {
|
||||||
@ -30,11 +37,26 @@ internal class NumassJupyter : JupyterIntegration() {
|
|||||||
|
|
||||||
|
|
||||||
render<NumassBlock> {
|
render<NumassBlock> {
|
||||||
|
HTML(Plotly.plotNumassBlock(it).toPage().render())
|
||||||
|
}
|
||||||
|
|
||||||
|
render<NumassFrame> { numassFrame ->
|
||||||
|
HTML(
|
||||||
|
Plotly.plot {
|
||||||
|
scatter {
|
||||||
|
x.numbers = numassFrame.signal.indices.map { numassFrame.tickSize.times(it).inWholeNanoseconds }
|
||||||
|
y.numbers = numassFrame.signal.toList()
|
||||||
|
}
|
||||||
|
}.toHTML()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
render<NumassSet> { numassSet ->
|
render<NumassSet> { numassSet ->
|
||||||
HTML(Plotly.numassSet(numassSet).render(), true)
|
HTML(Plotly.plotNumassSet(numassSet).toPage().render())
|
||||||
|
}
|
||||||
|
|
||||||
|
render<DataTree<NumassDirectorySet>> { tree ->
|
||||||
|
HTML("TODO: render repository tree")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ package ru.inr.mass.scripts
|
|||||||
|
|
||||||
import ru.inr.mass.data.proto.NumassDirectorySet
|
import ru.inr.mass.data.proto.NumassDirectorySet
|
||||||
import ru.inr.mass.workspace.Numass.readNumassRepository
|
import ru.inr.mass.workspace.Numass.readNumassRepository
|
||||||
import ru.inr.mass.workspace.numassSet
|
import ru.inr.mass.workspace.plotNumassSet
|
||||||
import space.kscience.dataforge.data.DataTree
|
import space.kscience.dataforge.data.DataTree
|
||||||
import space.kscience.dataforge.data.await
|
import space.kscience.dataforge.data.await
|
||||||
import space.kscience.dataforge.data.getData
|
import space.kscience.dataforge.data.getData
|
||||||
@ -14,5 +14,5 @@ suspend fun main() {
|
|||||||
//val dataPath = Path.of("D:\\Work\\Numass\\data\\2018_04\\Adiabacity_19\\set_4\\")
|
//val dataPath = Path.of("D:\\Work\\Numass\\data\\2018_04\\Adiabacity_19\\set_4\\")
|
||||||
//val testSet = NUMASS.context.readNumassDirectory(dataPath)
|
//val testSet = NUMASS.context.readNumassDirectory(dataPath)
|
||||||
val testSet = repo.getData("Adiabacity_19.set_3")?.await() ?: error("Not found")
|
val testSet = repo.getData("Adiabacity_19.set_3")?.await() ?: error("Not found")
|
||||||
Plotly.numassSet(testSet).makeFile()
|
Plotly.plotNumassSet(testSet).makeFile()
|
||||||
}
|
}
|
@ -1,19 +1,19 @@
|
|||||||
package ru.inr.mass.scripts
|
package ru.inr.mass.scripts
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.toList
|
|
||||||
import kotlinx.html.h2
|
import kotlinx.html.h2
|
||||||
import kotlinx.html.p
|
import kotlinx.html.p
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import ru.inr.mass.workspace.Numass.readNumassDirectory
|
import ru.inr.mass.workspace.Numass.readNumassDirectory
|
||||||
|
import ru.inr.mass.workspace.listFrames
|
||||||
import space.kscience.dataforge.meta.MetaSerializer
|
import space.kscience.dataforge.meta.MetaSerializer
|
||||||
import space.kscience.plotly.*
|
import space.kscience.plotly.*
|
||||||
|
|
||||||
suspend fun main() {
|
suspend fun main() {
|
||||||
//val repo: DataTree<NumassDirectorySet> = readNumassRepository("D:\\Work\\numass-data\\")
|
//val repo: DataTree<NumassDirectorySet> = readNumassRepository("D:\\Work\\numass-data\\")
|
||||||
val directory = readNumassDirectory("D:\\Work\\numass-data\\set_3\\")
|
val directory = readNumassDirectory("D:\\Work\\Numass\\data\\test\\set_7")
|
||||||
val point = directory.points.first()
|
val point = directory.points.first()
|
||||||
|
|
||||||
val frames = point.frames.toList()
|
val frames = point.listFrames()
|
||||||
Plotly.page {
|
Plotly.page {
|
||||||
p { +"${frames.size} frames" }
|
p { +"${frames.size} frames" }
|
||||||
h2 { +"Random frames" }
|
h2 { +"Random frames" }
|
||||||
@ -23,7 +23,7 @@ suspend fun main() {
|
|||||||
repeat(10) {
|
repeat(10) {
|
||||||
val frame = frames.random(random)
|
val frame = frames.random(random)
|
||||||
scatter {
|
scatter {
|
||||||
y.numbers = frame.signal.map { it.toUShort().toInt() - Short.MAX_VALUE }
|
y.numbers = frame.signal.map { (it.toUShort().toInt() - Short.MAX_VALUE).toShort() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ suspend fun main() {
|
|||||||
plot {
|
plot {
|
||||||
histogram {
|
histogram {
|
||||||
name = "max"
|
name = "max"
|
||||||
x.numbers = frames.map { frame -> frame.signal.maxOf { it.toUShort().toInt() - Short.MAX_VALUE } }
|
x.numbers = frames.map { frame -> frame.signal.maxOf { (it.toUShort().toInt() - Short.MAX_VALUE).toShort() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
histogram {
|
histogram {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package ru.inr.mass.workspace
|
package ru.inr.mass.workspace
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.toList
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import ru.inr.mass.data.api.NumassBlock
|
||||||
import ru.inr.mass.data.api.NumassSet
|
import ru.inr.mass.data.api.NumassSet
|
||||||
import ru.inr.mass.data.proto.NumassDirectorySet
|
import ru.inr.mass.data.proto.NumassDirectorySet
|
||||||
import ru.inr.mass.data.proto.readNumassDirectory
|
import ru.inr.mass.data.proto.readNumassDirectory
|
||||||
@ -45,3 +47,7 @@ object Numass {
|
|||||||
operator fun DataSet<NumassSet>.get(name: String): NumassSet? = runBlocking {
|
operator fun DataSet<NumassSet>.get(name: String): NumassSet? = runBlocking {
|
||||||
getData(Name.parse(name))?.await()
|
getData(Name.parse(name))?.await()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun NumassBlock.listFrames() = runBlocking { frames.toList() }
|
||||||
|
|
||||||
|
fun NumassBlock.listEvents() = runBlocking { events.toList() }
|
@ -7,7 +7,10 @@ import ru.inr.mass.data.analysis.NumassAmplitudeSpectrum
|
|||||||
import ru.inr.mass.data.analysis.NumassEventExtractor
|
import ru.inr.mass.data.analysis.NumassEventExtractor
|
||||||
import ru.inr.mass.data.analysis.amplitudeSpectrum
|
import ru.inr.mass.data.analysis.amplitudeSpectrum
|
||||||
import ru.inr.mass.data.analysis.timeHistogram
|
import ru.inr.mass.data.analysis.timeHistogram
|
||||||
|
import ru.inr.mass.data.api.NumassBlock
|
||||||
|
import ru.inr.mass.data.api.NumassPoint
|
||||||
import ru.inr.mass.data.api.NumassSet
|
import ru.inr.mass.data.api.NumassSet
|
||||||
|
import ru.inr.mass.data.api.title
|
||||||
import ru.inr.mass.data.proto.HVData
|
import ru.inr.mass.data.proto.HVData
|
||||||
import ru.inr.mass.data.proto.NumassDirectorySet
|
import ru.inr.mass.data.proto.NumassDirectorySet
|
||||||
import space.kscience.dataforge.values.asValue
|
import space.kscience.dataforge.values.asValue
|
||||||
@ -20,6 +23,7 @@ import space.kscience.kmath.structures.Buffer
|
|||||||
import space.kscience.kmath.structures.DoubleBuffer
|
import space.kscience.kmath.structures.DoubleBuffer
|
||||||
import space.kscience.plotly.*
|
import space.kscience.plotly.*
|
||||||
import space.kscience.plotly.models.*
|
import space.kscience.plotly.models.*
|
||||||
|
import kotlin.time.DurationUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plot a kmath histogram
|
* Plot a kmath histogram
|
||||||
@ -52,47 +56,89 @@ fun Plot.hvData(data: HVData): Trace = scatter {
|
|||||||
y.numbers = data.map { it.value }
|
y.numbers = data.map { it.value }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Plotly.numassSet(
|
|
||||||
set: NumassSet,
|
fun Plotly.plotNumassBlock(
|
||||||
|
block: NumassBlock,
|
||||||
amplitudeBinSize: UInt = 20U,
|
amplitudeBinSize: UInt = 20U,
|
||||||
eventExtractor: NumassEventExtractor = NumassEventExtractor.EVENTS_ONLY,
|
eventExtractor: NumassEventExtractor = NumassEventExtractor.EVENTS_ONLY,
|
||||||
): PlotlyPage =
|
splitChannels: Boolean = true
|
||||||
Plotly.page {
|
): PlotlyFragment = Plotly.fragment {
|
||||||
h1 {
|
plot {
|
||||||
+"Numass point set ${ShapeType.path}"
|
runBlocking {
|
||||||
}
|
if (splitChannels && block is NumassPoint) {
|
||||||
h2 {
|
block.getChannels().forEach { (channel, channelBlock) ->
|
||||||
+"Amplitude spectrum"
|
val spectrum = channelBlock.amplitudeSpectrum(eventExtractor)
|
||||||
}
|
histogram(spectrum, amplitudeBinSize) {
|
||||||
plot {
|
name = block.title + "[$channel]"
|
||||||
runBlocking {
|
}
|
||||||
set.points.sortedBy { it.index }.forEach {
|
|
||||||
histogram(it.amplitudeSpectrum(eventExtractor), amplitudeBinSize)
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
scatter {
|
||||||
|
val spectrum = block.amplitudeSpectrum(eventExtractor)
|
||||||
h2 {
|
histogram(spectrum, amplitudeBinSize)
|
||||||
+"Time spectra"
|
|
||||||
}
|
|
||||||
plot {
|
|
||||||
set.points.sortedBy { it.index }.forEach {
|
|
||||||
histogram(it.timeHistogram(1e3))
|
|
||||||
}
|
|
||||||
layout.yaxis.type = AxisType.log
|
|
||||||
|
|
||||||
}
|
|
||||||
if (set is NumassDirectorySet) {
|
|
||||||
set.getHvData()?.let { entries ->
|
|
||||||
h2 {
|
|
||||||
+"HV"
|
|
||||||
}
|
|
||||||
plot {
|
|
||||||
hvData(entries)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Plotly.plotNumassSet(
|
||||||
|
set: NumassSet,
|
||||||
|
amplitudeBinSize: UInt = 20U,
|
||||||
|
eventExtractor: NumassEventExtractor = NumassEventExtractor.EVENTS_ONLY,
|
||||||
|
): PlotlyFragment = Plotly.fragment {
|
||||||
|
|
||||||
|
h1 { +"Numass point set ${(set as? NumassDirectorySet)?.path ?: ""}" }
|
||||||
|
|
||||||
|
//TODO do in parallel
|
||||||
|
val spectra = runBlocking {
|
||||||
|
set.points.sortedBy { it.index }.map { it to it.amplitudeSpectrum(eventExtractor) }
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 { +"Amplitude spectrum" }
|
||||||
|
|
||||||
|
plot {
|
||||||
|
spectra.forEach { (point, spectrum) ->
|
||||||
|
histogram(spectrum, amplitudeBinSize) {
|
||||||
|
name = point.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 { +"Time spectra" }
|
||||||
|
|
||||||
|
plot {
|
||||||
|
spectra.forEach { (point,spectrum) ->
|
||||||
|
val countRate = runBlocking {
|
||||||
|
spectrum.sum().toDouble() / point.getLength().toDouble(DurationUnit.SECONDS)
|
||||||
|
}
|
||||||
|
val binSize = 1.0 / countRate / 10.0
|
||||||
|
histogram(point.timeHistogram(binSize)) {
|
||||||
|
name = point.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layout.yaxis.type = AxisType.log
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 { +"Integral spectrum" }
|
||||||
|
|
||||||
|
plot {
|
||||||
|
scatter {
|
||||||
|
mode = ScatterMode.markers
|
||||||
|
x.numbers = spectra.map { it.first.voltage }
|
||||||
|
y.numbers = spectra.map { it.second.sum().toLong() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set is NumassDirectorySet) {
|
||||||
|
set.getHvData()?.let { entries ->
|
||||||
|
h2 { +"HV" }
|
||||||
|
plot {
|
||||||
|
hvData(entries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a number buffer accessor for Plotly trace values
|
* Add a number buffer accessor for Plotly trace values
|
||||||
|
Loading…
Reference in New Issue
Block a user