Add renderers
This commit is contained in:
parent
d1ddf89c6e
commit
7d053d4fa9
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,6 +4,6 @@
|
||||
out/
|
||||
.gradle
|
||||
build/
|
||||
|
||||
/notebooks/.ipynb_checkpoints
|
||||
|
||||
!gradle-wrapper.jar
|
@ -9,15 +9,15 @@ allprojects {
|
||||
}
|
||||
|
||||
group = "ru.inr.mass"
|
||||
version = "0.1.0-dev-1"
|
||||
version = "0.1.0"
|
||||
}
|
||||
|
||||
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 plotlyVersion: String by extra("0.5.0")
|
||||
|
||||
ksciencePublish{
|
||||
git("https://mipt-npm.jetbrains.space/p/numass/code/numass/")
|
||||
github("numass")
|
||||
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 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 {
|
||||
var left = range.first
|
||||
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() }
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
public var crFraction by double()
|
||||
public var min by double(0.0)
|
||||
public var crMin by double(0.0)
|
||||
public var crFraction: Double? by double()
|
||||
public var min: Double 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
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ru.inr.mass.data.analysis
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import ru.inr.mass.data.api.NumassBlock
|
||||
import ru.inr.mass.data.api.NumassEvent
|
||||
|
||||
@ -12,6 +13,30 @@ public fun interface NumassEventExtractor {
|
||||
* A default event extractor that ignores frames
|
||||
*/
|
||||
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 space.kscience.kmath.histogram.UnivariateHistogram
|
||||
import kotlin.math.max
|
||||
import kotlin.time.DurationUnit
|
||||
|
||||
public fun <T, R> Flow<T>.zipWithNext(block: (l: T, r: T) -> R): Flow<R> {
|
||||
var current: T? = null
|
||||
@ -26,7 +27,7 @@ public fun NumassBlock.timeHistogram(
|
||||
runBlocking {
|
||||
extractor.extract(this@timeHistogram).zipWithNext { l, r ->
|
||||
if(l.owner == r.owner) {
|
||||
max((r.getTime() - l.getTime()).inWholeMicroseconds,0L)
|
||||
max((r.getTime() - l.getTime()).toDouble(DurationUnit.SECONDS),0.0)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
package ru.inr.mass.data.api
|
||||
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlin.time.Duration
|
||||
|
||||
|
||||
/**
|
||||
* The continuous frame of digital detector data
|
||||
* 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 signal The buffered signal shape in ticks
|
||||
*/
|
||||
public class NumassFrame(
|
||||
public val time: Instant,
|
||||
public val timeOffset: Long,
|
||||
public val tickSize: Duration,
|
||||
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.
|
||||
*
|
||||
|
@ -19,9 +19,7 @@ package ru.inr.mass.data.proto
|
||||
import io.ktor.utils.io.core.readBytes
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.datetime.DateTimeUnit
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.plus
|
||||
import okio.ByteString
|
||||
import org.slf4j.LoggerFactory
|
||||
import ru.inr.mass.data.api.*
|
||||
@ -202,9 +200,9 @@ public class ProtoNumassBlock(
|
||||
get() {
|
||||
val tickSize = block.bin_size.nanoseconds
|
||||
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_
|
||||
NumassFrame(time, tickSize, frameData.toShortArray())
|
||||
NumassFrame(frame.time, tickSize, frameData.toShortArray())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ class TestNumassDirectory {
|
||||
fun testTQDCRead() = runBlocking {
|
||||
val pointPath = Path.of("src/test/resources", "testData/tqdc")
|
||||
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) ->
|
||||
println("$channel: $block")
|
||||
if(block is ParentBlock){
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.jvm")
|
||||
id("com.github.johnrengelman.shadow") version "7.1.1"
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ kotlin {
|
||||
val dataforgeVersion: String by rootProject.extra
|
||||
val plotlyVersion: String by rootProject.extra
|
||||
val kmathVersion: String by rootProject.extra
|
||||
val tablesVersion: String by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
implementation(projects.numassDataProto)
|
||||
@ -19,6 +20,7 @@ dependencies {
|
||||
implementation("space.kscience:dataforge-workspace:$dataforgeVersion")
|
||||
implementation("space.kscience:plotlykt-jupyter:$plotlyVersion")
|
||||
implementation("space.kscience:kmath-jupyter:$kmathVersion")
|
||||
implementation("space.kscience:tables-kt:$tablesVersion")
|
||||
}
|
||||
|
||||
kscience{
|
||||
|
@ -4,10 +4,17 @@ package ru.inr.mass.notebook
|
||||
import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
|
||||
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.proto.NumassDirectorySet
|
||||
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.scatter
|
||||
import space.kscience.plotly.toHTML
|
||||
import space.kscience.plotly.toPage
|
||||
|
||||
internal class NumassJupyter : JupyterIntegration() {
|
||||
override fun Builder.onLoaded() {
|
||||
@ -30,11 +37,26 @@ internal class NumassJupyter : JupyterIntegration() {
|
||||
|
||||
|
||||
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 ->
|
||||
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.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.await
|
||||
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 testSet = NUMASS.context.readNumassDirectory(dataPath)
|
||||
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
|
||||
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.html.h2
|
||||
import kotlinx.html.p
|
||||
import kotlinx.serialization.json.Json
|
||||
import ru.inr.mass.workspace.Numass.readNumassDirectory
|
||||
import ru.inr.mass.workspace.listFrames
|
||||
import space.kscience.dataforge.meta.MetaSerializer
|
||||
import space.kscience.plotly.*
|
||||
|
||||
suspend fun main() {
|
||||
//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 frames = point.frames.toList()
|
||||
val frames = point.listFrames()
|
||||
Plotly.page {
|
||||
p { +"${frames.size} frames" }
|
||||
h2 { +"Random frames" }
|
||||
@ -23,7 +23,7 @@ suspend fun main() {
|
||||
repeat(10) {
|
||||
val frame = frames.random(random)
|
||||
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 {
|
||||
histogram {
|
||||
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 {
|
||||
|
@ -1,8 +1,10 @@
|
||||
package ru.inr.mass.workspace
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import ru.inr.mass.data.api.NumassBlock
|
||||
import ru.inr.mass.data.api.NumassSet
|
||||
import ru.inr.mass.data.proto.NumassDirectorySet
|
||||
import ru.inr.mass.data.proto.readNumassDirectory
|
||||
@ -45,3 +47,7 @@ object Numass {
|
||||
operator fun DataSet<NumassSet>.get(name: String): NumassSet? = runBlocking {
|
||||
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.amplitudeSpectrum
|
||||
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.title
|
||||
import ru.inr.mass.data.proto.HVData
|
||||
import ru.inr.mass.data.proto.NumassDirectorySet
|
||||
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.plotly.*
|
||||
import space.kscience.plotly.models.*
|
||||
import kotlin.time.DurationUnit
|
||||
|
||||
/**
|
||||
* Plot a kmath histogram
|
||||
@ -52,47 +56,89 @@ fun Plot.hvData(data: HVData): Trace = scatter {
|
||||
y.numbers = data.map { it.value }
|
||||
}
|
||||
|
||||
fun Plotly.numassSet(
|
||||
|
||||
fun Plotly.plotNumassBlock(
|
||||
block: NumassBlock,
|
||||
amplitudeBinSize: UInt = 20U,
|
||||
eventExtractor: NumassEventExtractor = NumassEventExtractor.EVENTS_ONLY,
|
||||
splitChannels: Boolean = true
|
||||
): PlotlyFragment = Plotly.fragment {
|
||||
plot {
|
||||
runBlocking {
|
||||
if (splitChannels && block is NumassPoint) {
|
||||
block.getChannels().forEach { (channel, channelBlock) ->
|
||||
val spectrum = channelBlock.amplitudeSpectrum(eventExtractor)
|
||||
histogram(spectrum, amplitudeBinSize) {
|
||||
name = block.title + "[$channel]"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
scatter {
|
||||
val spectrum = block.amplitudeSpectrum(eventExtractor)
|
||||
histogram(spectrum, amplitudeBinSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Plotly.plotNumassSet(
|
||||
set: NumassSet,
|
||||
amplitudeBinSize: UInt = 20U,
|
||||
eventExtractor: NumassEventExtractor = NumassEventExtractor.EVENTS_ONLY,
|
||||
): PlotlyPage =
|
||||
Plotly.page {
|
||||
h1 {
|
||||
+"Numass point set ${ShapeType.path}"
|
||||
}
|
||||
h2 {
|
||||
+"Amplitude spectrum"
|
||||
): 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 {
|
||||
runBlocking {
|
||||
set.points.sortedBy { it.index }.forEach {
|
||||
histogram(it.amplitudeSpectrum(eventExtractor), amplitudeBinSize)
|
||||
spectra.forEach { (point, spectrum) ->
|
||||
histogram(spectrum, amplitudeBinSize) {
|
||||
name = point.title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
+"Time spectra"
|
||||
}
|
||||
h2 { +"Time spectra" }
|
||||
|
||||
plot {
|
||||
set.points.sortedBy { it.index }.forEach {
|
||||
histogram(it.timeHistogram(1e3))
|
||||
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"
|
||||
}
|
||||
h2 { +"HV" }
|
||||
plot {
|
||||
hvData(entries)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a number buffer accessor for Plotly trace values
|
||||
|
Loading…
Reference in New Issue
Block a user