Compare commits
3 Commits
f76de70cd2
...
0dded083ba
| Author | SHA1 | Date | |
|---|---|---|---|
| 0dded083ba | |||
| 1764eef183 | |||
| 232669af80 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
.kotlin
|
||||
gradlew
|
||||
gradlew.bat
|
||||
|
||||
|
||||
@@ -9,12 +9,11 @@ allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven("https://repo.kotlin.link")
|
||||
maven("https://maven.sciprog.center")
|
||||
// maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||
maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||
}
|
||||
|
||||
group = "ru.inr.mass"
|
||||
version = "0.1.4-dev-2"
|
||||
version = "0.1.5"
|
||||
}
|
||||
|
||||
val dataforgeVersion by extra("0.10.1")
|
||||
@@ -23,13 +22,14 @@ val kmathVersion by extra("0.4.2")
|
||||
val visionForgeVersion: String by rootProject.extra("0.4.2")
|
||||
|
||||
|
||||
//ksciencePublish {
|
||||
// pom("https://spc.jetbrains.space/p/numass/repositories/numass/") {
|
||||
// useApache2Licence()
|
||||
// useSPCTeam()
|
||||
// }
|
||||
// space("https://maven.pkg.jetbrains.space/spc/p/numass/maven")
|
||||
//}
|
||||
ksciencePublish {
|
||||
pom("https://spc.jetbrains.space/p/numass/repositories/numass/") {
|
||||
useApache2Licence()
|
||||
useSPCTeam()
|
||||
}
|
||||
//space("https://maven.pkg.jetbrains.space/spc/p/numass/maven")
|
||||
//repository("spc","https://maven.sciprog.center/spc")
|
||||
}
|
||||
|
||||
apiValidation {
|
||||
validationDisabled = true
|
||||
|
||||
@@ -11,5 +11,5 @@ org.gradle.configureondemand=true
|
||||
org.gradle.parallel=true
|
||||
org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G
|
||||
|
||||
toolsVersion=0.14.10-kotlin-1.9.0
|
||||
compose.version=1.5.1
|
||||
toolsVersion=0.16.1-kotlin-2.1.0
|
||||
compose.version=1.7.3
|
||||
|
||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,7 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
//
|
||||
package ru.inr.mass.data.analysis
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import ru.inr.mass.data.analysis.TimeAnalyzerParameters.AveragingMethod
|
||||
import ru.inr.mass.data.api.NumassBlock
|
||||
import ru.inr.mass.data.api.NumassEvent
|
||||
import ru.inr.mass.data.api.ParentBlock
|
||||
import space.kscience.kmath.streaming.asFlow
|
||||
import space.kscience.kmath.streaming.chunked
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import kotlin.math.*
|
||||
|
||||
|
||||
@@ -31,6 +29,7 @@ import kotlin.math.*
|
||||
* An analyzer which uses time information from events
|
||||
* Created by darksnake on 11.07.2017.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
public open class TimeAnalyzer(
|
||||
override val extractor: NumassEventExtractor = NumassEventExtractor.EVENTS_ONLY,
|
||||
) : NumassAnalyzer() {
|
||||
@@ -60,7 +59,7 @@ public open class TimeAnalyzer(
|
||||
// }
|
||||
else -> block.flowFilteredEvents(parameters)
|
||||
.byPairs(parameters.t0.inverted)
|
||||
.chunked(chunkSize, Buffer.Companion::auto)
|
||||
.chunked(chunkSize)
|
||||
.map { it.asFlow().analyze(t0) }
|
||||
.toList()
|
||||
.combineResults(parameters.t0.averagingMethod)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("space.kscience.gradle.jvm")
|
||||
id("com.squareup.wire") version "4.9.1"
|
||||
id("com.squareup.wire") version "5.3.1"
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
// Code generated by Wire protocol buffer compiler, do not edit.
|
||||
// Source: ru.inr.mass.data.proto.Point in numass-proto.proto
|
||||
@file:Suppress(
|
||||
"DEPRECATION",
|
||||
"RUNTIME_ANNOTATION_NOT_SUPPORTED",
|
||||
)
|
||||
|
||||
package ru.inr.mass.`data`.proto
|
||||
|
||||
import com.squareup.wire.FieldEncoding
|
||||
import com.squareup.wire.Message
|
||||
import com.squareup.wire.ProtoAdapter
|
||||
import com.squareup.wire.ProtoReader
|
||||
import com.squareup.wire.ProtoWriter
|
||||
import com.squareup.wire.ReverseProtoWriter
|
||||
import com.squareup.wire.*
|
||||
import com.squareup.wire.Syntax.PROTO_3
|
||||
import com.squareup.wire.WireField
|
||||
import com.squareup.wire.`internal`.JvmField
|
||||
import com.squareup.wire.`internal`.immutableCopyOf
|
||||
import com.squareup.wire.`internal`.redactElements
|
||||
import kotlin.Any
|
||||
import kotlin.AssertionError
|
||||
import kotlin.Boolean
|
||||
import kotlin.Deprecated
|
||||
import kotlin.DeprecationLevel
|
||||
import kotlin.Int
|
||||
import kotlin.Long
|
||||
import kotlin.Nothing
|
||||
import kotlin.String
|
||||
import kotlin.collections.List
|
||||
import com.squareup.wire.internal.immutableCopyOf
|
||||
import com.squareup.wire.internal.redactElements
|
||||
import okio.ByteString
|
||||
|
||||
public class Point(
|
||||
@@ -44,8 +32,7 @@ public class Point(
|
||||
message = "Shouldn't be used in Kotlin",
|
||||
level = DeprecationLevel.HIDDEN,
|
||||
)
|
||||
override fun newBuilder(): Nothing = throw
|
||||
AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
override fun newBuilder(): Nothing = throw AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other === this) return true
|
||||
@@ -71,8 +58,7 @@ public class Point(
|
||||
return result.joinToString(prefix = "Point{", separator = ", ", postfix = "}")
|
||||
}
|
||||
|
||||
public fun copy(channels: List<Channel> = this.channels, unknownFields: ByteString =
|
||||
this.unknownFields): Point = Point(channels, unknownFields)
|
||||
public fun copy(channels: List<Channel> = this.channels, unknownFields: ByteString = this.unknownFields): Point = Point(channels, unknownFields)
|
||||
|
||||
public companion object {
|
||||
@JvmField
|
||||
@@ -155,8 +141,7 @@ public class Point(
|
||||
message = "Shouldn't be used in Kotlin",
|
||||
level = DeprecationLevel.HIDDEN,
|
||||
)
|
||||
override fun newBuilder(): Nothing = throw
|
||||
AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
override fun newBuilder(): Nothing = throw AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other === this) return true
|
||||
@@ -203,13 +188,17 @@ public class Point(
|
||||
) {
|
||||
override fun encodedSize(`value`: Channel): Int {
|
||||
var size = value.unknownFields.size
|
||||
if (value.id != 0L) size += ProtoAdapter.UINT64.encodedSizeWithTag(1, value.id)
|
||||
if (value.id != 0L) {
|
||||
size += ProtoAdapter.UINT64.encodedSizeWithTag(1, value.id)
|
||||
}
|
||||
size += Block.ADAPTER.asRepeated().encodedSizeWithTag(2, value.blocks)
|
||||
return size
|
||||
}
|
||||
|
||||
override fun encode(writer: ProtoWriter, `value`: Channel) {
|
||||
if (value.id != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.id)
|
||||
if (value.id != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.id)
|
||||
}
|
||||
Block.ADAPTER.asRepeated().encodeWithTag(writer, 2, value.blocks)
|
||||
writer.writeBytes(value.unknownFields)
|
||||
}
|
||||
@@ -217,7 +206,9 @@ public class Point(
|
||||
override fun encode(writer: ReverseProtoWriter, `value`: Channel) {
|
||||
writer.writeBytes(value.unknownFields)
|
||||
Block.ADAPTER.asRepeated().encodeWithTag(writer, 2, value.blocks)
|
||||
if (value.id != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.id)
|
||||
if (value.id != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.id)
|
||||
}
|
||||
}
|
||||
|
||||
override fun decode(reader: ProtoReader): Channel {
|
||||
@@ -309,8 +300,7 @@ public class Point(
|
||||
message = "Shouldn't be used in Kotlin",
|
||||
level = DeprecationLevel.HIDDEN,
|
||||
)
|
||||
override fun newBuilder(): Nothing = throw
|
||||
AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
override fun newBuilder(): Nothing = throw AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other === this) return true
|
||||
@@ -369,31 +359,54 @@ public class Point(
|
||||
) {
|
||||
override fun encodedSize(`value`: Block): Int {
|
||||
var size = value.unknownFields.size
|
||||
if (value.time != 0L) size += ProtoAdapter.UINT64.encodedSizeWithTag(1, value.time)
|
||||
if (value.time != 0L) {
|
||||
size += ProtoAdapter.UINT64.encodedSizeWithTag(1, value.time)
|
||||
}
|
||||
size += Frame.ADAPTER.asRepeated().encodedSizeWithTag(2, value.frames)
|
||||
if (value.events != null) size += Events.ADAPTER.encodedSizeWithTag(3, value.events)
|
||||
if (value.length != 0L) size += ProtoAdapter.UINT64.encodedSizeWithTag(4, value.length)
|
||||
if (value.bin_size != 0L) size += ProtoAdapter.UINT64.encodedSizeWithTag(5,
|
||||
value.bin_size)
|
||||
if (value.events != null) {
|
||||
size += Events.ADAPTER.encodedSizeWithTag(3, value.events)
|
||||
}
|
||||
if (value.length != 0L) {
|
||||
size += ProtoAdapter.UINT64.encodedSizeWithTag(4, value.length)
|
||||
}
|
||||
if (value.bin_size != 0L) {
|
||||
size += ProtoAdapter.UINT64.encodedSizeWithTag(5, value.bin_size)
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
override fun encode(writer: ProtoWriter, `value`: Block) {
|
||||
if (value.time != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
|
||||
if (value.time != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
|
||||
}
|
||||
Frame.ADAPTER.asRepeated().encodeWithTag(writer, 2, value.frames)
|
||||
if (value.events != null) Events.ADAPTER.encodeWithTag(writer, 3, value.events)
|
||||
if (value.length != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 4, value.length)
|
||||
if (value.bin_size != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 5, value.bin_size)
|
||||
if (value.events != null) {
|
||||
Events.ADAPTER.encodeWithTag(writer, 3, value.events)
|
||||
}
|
||||
if (value.length != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 4, value.length)
|
||||
}
|
||||
if (value.bin_size != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 5, value.bin_size)
|
||||
}
|
||||
writer.writeBytes(value.unknownFields)
|
||||
}
|
||||
|
||||
override fun encode(writer: ReverseProtoWriter, `value`: Block) {
|
||||
writer.writeBytes(value.unknownFields)
|
||||
if (value.bin_size != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 5, value.bin_size)
|
||||
if (value.length != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 4, value.length)
|
||||
if (value.events != null) Events.ADAPTER.encodeWithTag(writer, 3, value.events)
|
||||
if (value.bin_size != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 5, value.bin_size)
|
||||
}
|
||||
if (value.length != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 4, value.length)
|
||||
}
|
||||
if (value.events != null) {
|
||||
Events.ADAPTER.encodeWithTag(writer, 3, value.events)
|
||||
}
|
||||
Frame.ADAPTER.asRepeated().encodeWithTag(writer, 2, value.frames)
|
||||
if (value.time != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
|
||||
if (value.time != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
|
||||
}
|
||||
}
|
||||
|
||||
override fun decode(reader: ProtoReader): Block {
|
||||
@@ -463,8 +476,7 @@ public class Point(
|
||||
message = "Shouldn't be used in Kotlin",
|
||||
level = DeprecationLevel.HIDDEN,
|
||||
)
|
||||
override fun newBuilder(): Nothing = throw
|
||||
AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
override fun newBuilder(): Nothing = throw AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other === this) return true
|
||||
@@ -511,24 +523,33 @@ public class Point(
|
||||
) {
|
||||
override fun encodedSize(`value`: Frame): Int {
|
||||
var size = value.unknownFields.size
|
||||
if (value.time != 0L) size += ProtoAdapter.UINT64.encodedSizeWithTag(1, value.time)
|
||||
if (value.data_ != ByteString.EMPTY) size += ProtoAdapter.BYTES.encodedSizeWithTag(2,
|
||||
value.data_)
|
||||
if (value.time != 0L) {
|
||||
size += ProtoAdapter.UINT64.encodedSizeWithTag(1, value.time)
|
||||
}
|
||||
if (value.data_ != okio.ByteString.EMPTY) {
|
||||
size += ProtoAdapter.BYTES.encodedSizeWithTag(2, value.data_)
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
override fun encode(writer: ProtoWriter, `value`: Frame) {
|
||||
if (value.time != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
|
||||
if (value.data_ != ByteString.EMPTY) ProtoAdapter.BYTES.encodeWithTag(writer, 2,
|
||||
value.data_)
|
||||
if (value.time != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
|
||||
}
|
||||
if (value.data_ != okio.ByteString.EMPTY) {
|
||||
ProtoAdapter.BYTES.encodeWithTag(writer, 2, value.data_)
|
||||
}
|
||||
writer.writeBytes(value.unknownFields)
|
||||
}
|
||||
|
||||
override fun encode(writer: ReverseProtoWriter, `value`: Frame) {
|
||||
writer.writeBytes(value.unknownFields)
|
||||
if (value.data_ != ByteString.EMPTY) ProtoAdapter.BYTES.encodeWithTag(writer, 2,
|
||||
value.data_)
|
||||
if (value.time != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
|
||||
if (value.data_ != okio.ByteString.EMPTY) {
|
||||
ProtoAdapter.BYTES.encodeWithTag(writer, 2, value.data_)
|
||||
}
|
||||
if (value.time != 0L) {
|
||||
ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
|
||||
}
|
||||
}
|
||||
|
||||
override fun decode(reader: ProtoReader): Frame {
|
||||
@@ -593,8 +614,7 @@ public class Point(
|
||||
message = "Shouldn't be used in Kotlin",
|
||||
level = DeprecationLevel.HIDDEN,
|
||||
)
|
||||
override fun newBuilder(): Nothing = throw
|
||||
AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
override fun newBuilder(): Nothing = throw AssertionError("Builders are deprecated and only available in a javaInterop build; see https://square.github.io/wire/wire_compiler/#kotlin")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other === this) return true
|
||||
|
||||
@@ -5,7 +5,7 @@ import space.kscience.dataforge.context.AbstractPlugin
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.PluginFactory
|
||||
import space.kscience.dataforge.context.PluginTag
|
||||
import space.kscience.dataforge.data.DataSource
|
||||
import space.kscience.dataforge.data.Data
|
||||
import space.kscience.dataforge.data.DataTree
|
||||
import space.kscience.dataforge.data.static
|
||||
import space.kscience.dataforge.io.EnvelopeFormatFactory
|
||||
@@ -53,7 +53,8 @@ public fun NumassProtoPlugin.readNumassDirectory(path: Path): NumassDirectorySet
|
||||
}
|
||||
|
||||
public fun NumassProtoPlugin.readNumassDirectory(path: String): NumassDirectorySet = readNumassDirectory(Path.of(path))
|
||||
public suspend fun NumassProtoPlugin.readRepository(path: Path): DataTree<NumassDirectorySet> = DataSource {
|
||||
|
||||
public suspend fun NumassProtoPlugin.readRepository(path: Path): DataTree<NumassDirectorySet> = DataTree.static {
|
||||
Files.walk(path).filter {
|
||||
it.isDirectory() && it.resolve("meta").exists()
|
||||
}.forEach { childPath ->
|
||||
@@ -61,7 +62,7 @@ public suspend fun NumassProtoPlugin.readRepository(path: Path): DataTree<Numass
|
||||
NameToken(segment.fileName.toString())
|
||||
})
|
||||
val value = readNumassDirectory(childPath)
|
||||
static(name, value, value.meta)
|
||||
data(name, Data(value, value.meta))
|
||||
}
|
||||
|
||||
//TODO add file watcher
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
|
||||
package ru.inr.mass.data.proto
|
||||
|
||||
import io.ktor.utils.io.core.readBytes
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.toInstant
|
||||
import kotlinx.io.asInputStream
|
||||
import kotlinx.io.readByteArray
|
||||
import okio.ByteString
|
||||
import org.slf4j.LoggerFactory
|
||||
import ru.inr.mass.data.api.NumassBlock
|
||||
@@ -126,7 +127,7 @@ internal class ProtoNumassPoint(
|
||||
val inflater = Inflater()
|
||||
|
||||
val array: ByteArray = data?.read {
|
||||
readBytes()
|
||||
readByteArray()
|
||||
} ?: ByteArray(0)
|
||||
|
||||
inflater.setInput(array)
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
package ru.inr.mass.data.proto
|
||||
|
||||
import io.ktor.utils.io.core.*
|
||||
import kotlinx.io.*
|
||||
import kotlinx.io.bytestring.encodeToByteString
|
||||
import kotlinx.io.bytestring.endsWith
|
||||
import kotlinx.io.bytestring.startsWith
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.invoke
|
||||
import space.kscience.dataforge.io.*
|
||||
@@ -25,21 +28,20 @@ import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.string
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.parseAsName
|
||||
import java.util.*
|
||||
|
||||
|
||||
public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeFormat {
|
||||
|
||||
private fun Tag.toBinary() = Binary {
|
||||
writeRawString(START_SEQUENCE)
|
||||
writeRawString("DFNU")
|
||||
write(START_SEQUENCE.toByteArray())
|
||||
writeString("DFNU")
|
||||
writeShort(metaFormatKey)
|
||||
writeUInt(metaSize)
|
||||
writeUInt(dataSize.toUInt())
|
||||
writeRawString(END_SEQUENCE)
|
||||
write(END_SEQUENCE.toByteArray())
|
||||
}
|
||||
|
||||
override fun writeObject(output: Output, obj: Envelope) {
|
||||
override fun writeTo(output: Sink, obj: Envelope) {
|
||||
error("Don't write legacy formats")
|
||||
}
|
||||
|
||||
@@ -49,12 +51,12 @@ public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeForm
|
||||
* @param input an input to read from
|
||||
* @param formats a collection of meta formats to resolve
|
||||
*/
|
||||
override fun readObject(input: Input): Envelope {
|
||||
override fun readFrom(input: Source): Envelope {
|
||||
val tag = input.readTag()
|
||||
|
||||
val metaFormat = io.resolveMetaFormat(tag.metaFormatKey) ?: JsonMetaFormat
|
||||
|
||||
val meta: Meta = metaFormat.readObjectFrom(input.readBinary(tag.metaSize.toInt()))
|
||||
val meta: Meta = metaFormat.readFrom(input.readBinary(tag.metaSize.toInt()))
|
||||
|
||||
val data = input.readBinary(tag.dataSize.toInt())
|
||||
|
||||
@@ -88,8 +90,8 @@ public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeForm
|
||||
// }
|
||||
|
||||
public companion object : EnvelopeFormatFactory {
|
||||
private const val START_SEQUENCE = "#!"
|
||||
private const val END_SEQUENCE = "!#\r\n"
|
||||
private val START_SEQUENCE = "#!".encodeToByteString()
|
||||
private val END_SEQUENCE = "!#\r\n".encodeToByteString()
|
||||
|
||||
override val name: Name = "envelope.numass".parseAsName()
|
||||
|
||||
@@ -103,23 +105,23 @@ public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeForm
|
||||
return TaggedNumassEnvelopeFormat(io)
|
||||
}
|
||||
|
||||
private fun Input.readTag(): Tag {
|
||||
val start = readRawString(2)
|
||||
private fun Source.readTag(): Tag {
|
||||
val start = readByteString(2)
|
||||
if (start != START_SEQUENCE) error("The input is not an envelope")
|
||||
val versionString = readRawString(4)
|
||||
val versionString = readByteString(4)
|
||||
val junk1 = readInt()
|
||||
val metaFormatKey = readShort()
|
||||
val junk2 = readShort()
|
||||
val metaLength = readUInt()
|
||||
val dataLength: ULong = readULong()
|
||||
val end = readRawString(4)
|
||||
val end = readByteString(4)
|
||||
if (end != END_SEQUENCE) error("The input is not an envelope")
|
||||
return Tag(metaFormatKey, metaLength, dataLength)
|
||||
}
|
||||
|
||||
override fun peekFormat(io: IOPlugin, binary: Binary): EnvelopeFormat? = try {
|
||||
binary.read {
|
||||
val header = readRawString(30)
|
||||
val header = readByteString(30)
|
||||
if (header.startsWith(START_SEQUENCE) && header.endsWith(END_SEQUENCE)) {
|
||||
TaggedNumassEnvelopeFormat(io)
|
||||
} else {
|
||||
@@ -132,11 +134,11 @@ public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeForm
|
||||
|
||||
private val default by lazy { invoke() }
|
||||
|
||||
override fun writeObject(output: Output, obj: Envelope) {
|
||||
override fun writeTo(output: Sink, obj: Envelope) {
|
||||
error("Don't write legacy formats")
|
||||
}
|
||||
|
||||
|
||||
override fun readObject(input: Input): Envelope = default.readObject(input)
|
||||
override fun readFrom(input: Source): Envelope = default.readFrom(input)
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,37 @@
|
||||
package ru.inr.mass.data.proto
|
||||
|
||||
import io.ktor.utils.io.core.*
|
||||
import java.io.InputStream
|
||||
import kotlinx.io.Source
|
||||
|
||||
// TODO move to dataforge-io
|
||||
|
||||
/**
|
||||
* Sequentially read Utf8 lines from the input until it is exhausted
|
||||
*/
|
||||
public fun Input.lines(): Sequence<String> = sequence {
|
||||
while (!endOfInput) {
|
||||
readUTF8Line()?.let { yield(it) }
|
||||
}
|
||||
public fun Source.lines(): Sequence<String> = sequence {
|
||||
do {
|
||||
val line = readLine()
|
||||
if (line != null) yield(line)
|
||||
} while (line != null)
|
||||
}
|
||||
|
||||
private class InputAsInputStream(val input: Input) : InputStream() {
|
||||
|
||||
|
||||
override fun read(): Int = input.run {
|
||||
if (endOfInput) {
|
||||
-1
|
||||
} else {
|
||||
readUByte().toInt()
|
||||
}
|
||||
}
|
||||
|
||||
override fun readAllBytes(): ByteArray = input.readBytes()
|
||||
|
||||
override fun read(b: ByteArray): Int = input.readAvailable(b)
|
||||
|
||||
override fun close() {
|
||||
input.close()
|
||||
}
|
||||
}
|
||||
|
||||
public fun Input.asInputStream(): InputStream = InputAsInputStream(this)
|
||||
//private class InputAsInputStream(val input: Source) : InputStream() {
|
||||
//
|
||||
//
|
||||
// override fun read(): Int = input.run {
|
||||
// if (endOfInput) {
|
||||
// -1
|
||||
// } else {
|
||||
// readUByte().toInt()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun readAllBytes(): ByteArray = input.readBytes()
|
||||
//
|
||||
// override fun read(b: ByteArray): Int = input.readAvailable(b)
|
||||
//
|
||||
// override fun close() {
|
||||
// input.close()
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//public fun Source.asInputStream(): InputStream = InputAsInputStream(this)
|
||||
@@ -1,6 +1,7 @@
|
||||
plugins {
|
||||
id("space.kscience.gradle.mpp")
|
||||
id("org.jetbrains.compose")
|
||||
alias(spclibs.plugins.compose.compiler)
|
||||
alias(spclibs.plugins.compose.jb)
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
@@ -19,28 +20,32 @@ kscience {
|
||||
useContextReceivers()
|
||||
useKtor()
|
||||
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation(project(":numass-data-model"))
|
||||
implementation("space.kscience:visionforge-core:$visionForgeVersion")
|
||||
implementation("space.kscience:visionforge-plotly:$visionForgeVersion")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
kotlin{
|
||||
sourceSets{
|
||||
getByName("jvmMain"){
|
||||
commonMain {
|
||||
dependencies {
|
||||
api(compose.runtime)
|
||||
implementation(project(":numass-data-model"))
|
||||
implementation("space.kscience:visionforge-core:$visionForgeVersion")
|
||||
implementation("space.kscience:visionforge-plotly:$visionForgeVersion")
|
||||
}
|
||||
}
|
||||
|
||||
jvmMain{
|
||||
dependencies{
|
||||
implementation(compose.runtime)
|
||||
implementation(project(":numass-data-proto"))
|
||||
implementation("io.ktor:ktor-server-cio")
|
||||
implementation("io.ktor:ktor-server-html-builder")
|
||||
implementation("space.kscience:visionforge-plotly:$visionForgeVersion")
|
||||
}
|
||||
}
|
||||
getByName("jsMain"){
|
||||
|
||||
jsMain{
|
||||
dependencies{
|
||||
implementation("org.jetbrains.kotlin-wrappers:kotlin-extensions:1.0.1-pre.823")
|
||||
implementation(compose.html.core)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ public class NumassCommonPlugin(meta: Meta = Meta.EMPTY) : VisionPlugin(meta) {
|
||||
subclass(VisionOfNumassHv.serializer())
|
||||
subclass(VisionOfNumassPoint.serializer())
|
||||
subclass(VisionOfNumassSet.serializer())
|
||||
subclass(VisionOfNumassSetRef.serializer())
|
||||
subclass(VisionOfNumassRepository.serializer())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@ package ru.inr.mass.data.server
|
||||
import kotlinx.serialization.Serializable
|
||||
import ru.inr.mass.data.api.NumassSet
|
||||
import space.kscience.dataforge.data.DataTree
|
||||
import space.kscience.dataforge.data.DataTreeItem
|
||||
import space.kscience.dataforge.misc.Named
|
||||
import space.kscience.dataforge.data.await
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.NameToken
|
||||
import space.kscience.dataforge.names.plus
|
||||
import space.kscience.visionforge.AbstractVision
|
||||
import space.kscience.visionforge.AbstractVisionGroup
|
||||
|
||||
@Serializable
|
||||
@@ -16,20 +14,15 @@ public class VisionOfNumassRepository : AbstractVisionGroup() {
|
||||
override fun createGroup(): VisionOfNumassRepository = VisionOfNumassRepository()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public class VisionOfNumassSetRef(
|
||||
override val name: Name,
|
||||
) : Named, AbstractVision()
|
||||
|
||||
public suspend fun VisionOfNumassRepository(
|
||||
repoName: Name,
|
||||
tree: DataTree<NumassSet>,
|
||||
): VisionOfNumassRepository = VisionOfNumassRepository().apply {
|
||||
tree.items.forEach { (key: NameToken, value) ->
|
||||
children[key] = when (value) {
|
||||
is DataTreeItem.Leaf -> VisionOfNumassSetRef(repoName + key)
|
||||
is DataTreeItem.Node -> VisionOfNumassRepository(repoName + key, value.tree)
|
||||
}
|
||||
tree.data?.let {
|
||||
VisionOfNumassSet(repoName, it.await())
|
||||
}
|
||||
tree.items.forEach { (key: NameToken, subtree) ->
|
||||
children[key] = VisionOfNumassRepository(repoName + key, subtree)
|
||||
}
|
||||
//TODO listen to changes
|
||||
}
|
||||
@@ -12,15 +12,18 @@ import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.plotly.models.LineShape
|
||||
import space.kscience.plotly.models.ScatterMode
|
||||
import space.kscience.plotly.plotElement
|
||||
import space.kscience.plotly.plotDiv
|
||||
import space.kscience.plotly.scatter
|
||||
import space.kscience.visionforge.ElementVisionRenderer
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.VisionClient
|
||||
import space.kscience.visionforge.html.ElementVisionRenderer
|
||||
import space.kscience.visionforge.html.JsVisionClient
|
||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||
|
||||
public class NumassJsPlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
public val client: VisionClient by require(VisionClient)
|
||||
override fun toString(): String = "NumassJsPlugin"
|
||||
|
||||
public val client: VisionClient by require(JsVisionClient)
|
||||
public val numassCommon: NumassCommonPlugin by require(NumassCommonPlugin)
|
||||
public val plotly: PlotlyPlugin by require(PlotlyPlugin)
|
||||
|
||||
@@ -59,7 +62,7 @@ public class NumassJsPlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
|
||||
is VisionOfNumassPoint -> element.append {
|
||||
h1 { +"Point" }
|
||||
plotElement {
|
||||
plotDiv {
|
||||
vision.spectra.forEach { (channel, spectrum) ->
|
||||
val pairs = spectrum.entries.sortedBy { it.key }
|
||||
scatter {
|
||||
|
||||
@@ -4,7 +4,7 @@ import org.jetbrains.compose.web.dom.Div
|
||||
import org.jetbrains.compose.web.renderComposable
|
||||
import org.w3c.dom.Document
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.visionforge.Application
|
||||
import space.kscience.visionforge.html.Application
|
||||
|
||||
public class NumassViewerApplication : Application {
|
||||
private val context = Context("NumassViewer") {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package ru.inr.mass.data.server
|
||||
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.runVisionClient
|
||||
import space.kscience.visionforge.html.runVisionClient
|
||||
|
||||
|
||||
@DFExperimental
|
||||
|
||||
@@ -3,11 +3,10 @@ package ru.inr.mass.data.server
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.application.Application
|
||||
import io.ktor.server.application.call
|
||||
import io.ktor.server.cio.CIO
|
||||
import io.ktor.server.engine.embeddedServer
|
||||
import io.ktor.server.html.respondHtml
|
||||
import io.ktor.server.http.content.resources
|
||||
import io.ktor.server.http.content.staticResources
|
||||
import io.ktor.server.response.respondText
|
||||
import io.ktor.server.routing.get
|
||||
import io.ktor.server.routing.routing
|
||||
@@ -20,9 +19,10 @@ import ru.inr.mass.data.proto.NumassDirectorySet
|
||||
import ru.inr.mass.data.proto.NumassProtoPlugin
|
||||
import ru.inr.mass.data.proto.readRepository
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.dataforge.context.request
|
||||
import space.kscience.dataforge.data.DataTree
|
||||
import space.kscience.dataforge.data.await
|
||||
import space.kscience.dataforge.data.get
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.NameToken
|
||||
import space.kscience.dataforge.names.cutLast
|
||||
@@ -41,15 +41,14 @@ public fun Application.numassModule(repositoryName: String = "D:\\Work\\Numass\\
|
||||
plugin(NumassCommonPlugin)
|
||||
}
|
||||
|
||||
val numassProto = context.fetch(NumassProtoPlugin)
|
||||
val numassCommon = context.fetch(NumassCommonPlugin)
|
||||
val numassProto = context.request(NumassProtoPlugin)
|
||||
val numassCommon = context.request(NumassCommonPlugin)
|
||||
|
||||
val visionManager = numassCommon.visionManager
|
||||
val repository: DataTree<NumassDirectorySet> = runBlocking { numassProto.readRepository(repositoryName) }
|
||||
|
||||
routing {
|
||||
resources()
|
||||
|
||||
staticResources("/","")
|
||||
get("/") {
|
||||
call.respondHtml {
|
||||
head {
|
||||
|
||||
@@ -4,7 +4,7 @@ import ru.inr.mass.data.api.NumassPoint
|
||||
import ru.inr.mass.data.proto.NumassProtoPlugin
|
||||
import ru.inr.mass.data.proto.readNumassPointFile
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.dataforge.context.request
|
||||
import java.nio.file.Path
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public suspend fun main() {
|
||||
plugin(NumassCommonPlugin)
|
||||
}
|
||||
|
||||
val numassProto = context.fetch(NumassProtoPlugin)
|
||||
val numassProto = context.request(NumassProtoPlugin)
|
||||
|
||||
val pointPath = Path.of("D:\\Work\\Numass\\data\\test\\set_7\\p120(30s)(HV1=13300)")
|
||||
val point: NumassPoint = numassProto.readNumassPointFile(pointPath)!!
|
||||
|
||||
@@ -22,7 +22,7 @@ import space.kscience.kmath.expressions.symbol
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class NBkgSpectrum(public val source: Spectrum) : DifferentiableSpectrum {
|
||||
public class NBkgSpectrum(public val source: Spectrum) : DifferentiableSpectrum {
|
||||
override fun invoke(x: Double, arguments: Map<Symbol, Double>): Double {
|
||||
val normValue = arguments[norm] ?: 1.0
|
||||
val bkgValue = arguments[bkg] ?: 0.0
|
||||
@@ -32,8 +32,8 @@ public abstract class NBkgSpectrum(public val source: Spectrum) : Differentiable
|
||||
override fun derivativeOrNull(symbols: List<Symbol>): Spectrum? = when {
|
||||
symbols.isEmpty() -> this
|
||||
symbols.size == 1 -> when (symbols.first()) {
|
||||
norm -> Spectrum { x: Double, arguments: Map<Symbol, Double> -> source(x, arguments) }
|
||||
bkg -> Spectrum { _: Double, _: Map<Symbol, Double> -> 1.0 }
|
||||
norm -> Spectrum { x, arguments -> source(x, arguments) }
|
||||
bkg -> Spectrum { _, _ -> 1.0 }
|
||||
else -> (source as? DifferentiableSpectrum)?.derivativeOrNull(symbols)?.let { NBkgSpectrum(it) }
|
||||
}
|
||||
else -> null
|
||||
@@ -48,4 +48,4 @@ public abstract class NBkgSpectrum(public val source: Spectrum) : Differentiable
|
||||
/**
|
||||
* Apply transformation adding norming-factor and the background
|
||||
*/
|
||||
public fun Spectrum.withNBkg(): NBkgSpectrum = NBkgSpectrum(this)
|
||||
public fun Spectrum.withNBkg(): NBkgSpectrum = NBkgSpectrum(this)
|
||||
@@ -5,15 +5,19 @@
|
||||
*/
|
||||
package ru.inr.mass.models
|
||||
|
||||
import space.kscience.dataforge.misc.ThreadSafe
|
||||
import space.kscience.kmath.expressions.Symbol
|
||||
import space.kscience.kmath.expressions.symbol
|
||||
import space.kscience.kmath.functions.Function1D
|
||||
import space.kscience.kmath.functions.PiecewisePolynomial
|
||||
import space.kscience.kmath.functions.asFunction
|
||||
import space.kscience.kmath.integration.*
|
||||
import space.kscience.kmath.integration.IntegrandMaxCalls
|
||||
import space.kscience.kmath.integration.integrate
|
||||
import space.kscience.kmath.integration.simpsonIntegrator
|
||||
import space.kscience.kmath.integration.value
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import kotlin.jvm.Synchronized
|
||||
import kotlin.math.*
|
||||
import kotlin.math.exp
|
||||
import kotlin.math.ln
|
||||
|
||||
|
||||
/**
|
||||
@@ -265,10 +269,13 @@ public class NumassTransmission(
|
||||
* @param loss
|
||||
* @return
|
||||
*/
|
||||
@Synchronized
|
||||
@ThreadSafe
|
||||
private fun getNextLoss(margin: Double, loss: Function1D<Double>): PiecewisePolynomial<Double> {
|
||||
val res = { x: Double ->
|
||||
DoubleField.simpsonIntegrator.integrate(5.0..margin, IntegrandMaxCalls(200)) { y ->
|
||||
DoubleField.simpsonIntegrator.integrate(
|
||||
5.0..margin,
|
||||
attributeBuilder = { IntegrandMaxCalls(200) }
|
||||
) { y ->
|
||||
loss(x - y) * singleScatterFunction(y)
|
||||
}.value
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package ru.inr.mass.models
|
||||
|
||||
import space.kscience.attributes.SafeType
|
||||
import space.kscience.attributes.safeTypeOf
|
||||
import space.kscience.kmath.expressions.Expression
|
||||
import space.kscience.kmath.expressions.SpecialDifferentiableExpression
|
||||
import space.kscience.kmath.expressions.Symbol
|
||||
|
||||
public fun interface Spectrum : Expression<Double> {
|
||||
override val type: SafeType<Double> get() = safeTypeOf<Double>()
|
||||
|
||||
public val abscissa: Symbol get() = Symbol.x
|
||||
|
||||
public operator fun invoke(x: Double, arguments: Map<Symbol, Double>): Double
|
||||
@@ -16,6 +20,7 @@ public fun interface Spectrum : Expression<Double> {
|
||||
public interface DifferentiableSpectrum : SpecialDifferentiableExpression<Double, Spectrum>, Spectrum
|
||||
|
||||
public fun interface Kernel : Expression<Double> {
|
||||
override val type: SafeType<Double> get() = safeTypeOf<Double>()
|
||||
public val x: Symbol get() = Symbol.x
|
||||
public val y: Symbol get() = Symbol.y
|
||||
|
||||
@@ -38,6 +43,6 @@ public fun Kernel.withFixedY(y: Double): Spectrum = Spectrum { x, arguments ->
|
||||
invoke(x, y, arguments)
|
||||
}
|
||||
|
||||
public fun <T> Expression<T>.withDefault(default: Map<Symbol, T>): Expression<T> = Expression { args ->
|
||||
public fun <T> Expression<T>.withDefault(default: Map<Symbol, T>): Expression<T> = Expression(type) { args ->
|
||||
invoke(default + args)
|
||||
}
|
||||
@@ -12,12 +12,11 @@ import ru.inr.mass.models.NumassBeta.msterile2
|
||||
import ru.inr.mass.models.NumassBeta.u2
|
||||
import ru.inr.mass.models.NumassTransmission.Companion.thickness
|
||||
import ru.inr.mass.models.NumassTransmission.Companion.trap
|
||||
import space.kscience.attributes.AttributesBuilder
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.expressions.Symbol
|
||||
import space.kscience.kmath.expressions.derivative
|
||||
import space.kscience.kmath.integration.UnivariateIntegrandRanges
|
||||
import space.kscience.kmath.integration.gaussIntegrator
|
||||
import space.kscience.kmath.integration.integrate
|
||||
import space.kscience.kmath.integration.value
|
||||
import space.kscience.kmath.integration.*
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.real.step
|
||||
import space.kscience.kmath.structures.toDoubleArray
|
||||
@@ -28,7 +27,8 @@ import space.kscience.kmath.structures.toDoubleArray
|
||||
* @param transmission variables:Ein,Eout; parameters: "A"
|
||||
* @param resolution variables:Eout,U; parameters: "X", "trap"
|
||||
*/
|
||||
public open class SterileNeutrinoSpectrum(
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public class SterileNeutrinoSpectrum(
|
||||
public val source: DifferentiableKernel = NumassBeta,
|
||||
public val transmission: DifferentiableKernel = NumassTransmission(),
|
||||
public val resolution: DifferentiableKernel = NumassResolution(),
|
||||
@@ -54,9 +54,11 @@ public open class SterileNeutrinoSpectrum(
|
||||
u2, msterile2, mnu2, e0 -> Spectrum { u, arguments ->
|
||||
convolute(u, source.derivative(symbols), transRes, arguments)
|
||||
}
|
||||
|
||||
thickness, trap -> Spectrum { u, arguments ->
|
||||
convolute(u, source, transRes.derivative(symbols), arguments)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -94,14 +96,17 @@ public open class SterileNeutrinoSpectrum(
|
||||
// }
|
||||
|
||||
return DoubleField.gaussIntegrator.integrate(
|
||||
u..eMax, generateRanges(
|
||||
u..eMax,
|
||||
u + 2.0,
|
||||
u + 7.0,
|
||||
u + 15.0,
|
||||
u + 30.0,
|
||||
*((u + 50)..(u + 6000) step 25.0).toDoubleArray()
|
||||
)
|
||||
range = u..eMax,
|
||||
attributeBuilder = {
|
||||
multiRange(
|
||||
u..eMax,
|
||||
u + 2.0,
|
||||
u + 7.0,
|
||||
u + 15.0,
|
||||
u + 30.0,
|
||||
*((u + 50)..(u + 6000) step 25.0).toDoubleArray()
|
||||
)
|
||||
}
|
||||
) { eIn ->
|
||||
sumByFSS(eIn, sourceFunction, arguments) * transResFunction(eIn, u, arguments)
|
||||
}.value
|
||||
@@ -138,14 +143,17 @@ public open class SterileNeutrinoSpectrum(
|
||||
u: Double,
|
||||
arguments: Map<Symbol, Double>,
|
||||
): Double = DoubleField.gaussIntegrator.integrate(
|
||||
u..eIn, generateRanges(
|
||||
u..eIn,
|
||||
u + 2.0,
|
||||
u + 7.0,
|
||||
u + 15.0,
|
||||
u + 30.0,
|
||||
*((u + 50)..(u + 6000) step 30.0).toDoubleArray()
|
||||
)
|
||||
range = u..eIn,
|
||||
attributeBuilder = {
|
||||
multiRange(
|
||||
u..eIn,
|
||||
u + 2.0,
|
||||
u + 7.0,
|
||||
u + 15.0,
|
||||
u + 30.0,
|
||||
*((u + 50)..(u + 6000) step 30.0).toDoubleArray()
|
||||
)
|
||||
}
|
||||
) { eOut: Double ->
|
||||
transFunc(eIn, eOut, arguments) * resolution(eOut, u, arguments)
|
||||
}.value
|
||||
@@ -154,19 +162,25 @@ public open class SterileNeutrinoSpectrum(
|
||||
public companion object
|
||||
}
|
||||
|
||||
|
||||
internal fun generateRanges(
|
||||
internal fun AttributesBuilder<UnivariateIntegrand<*>>.multiRange(
|
||||
range: ClosedFloatingPointRange<Double>,
|
||||
vararg borders: Double,
|
||||
points: Int = 5,
|
||||
): UnivariateIntegrandRanges {
|
||||
if (borders.isEmpty() || borders.first() > range.endInclusive) return UnivariateIntegrandRanges(range to points)
|
||||
val ranges = listOf(
|
||||
range.start,
|
||||
*borders.filter { it in range }.sorted().toTypedArray(),
|
||||
range.endInclusive
|
||||
).zipWithNext { l, r ->
|
||||
l..r to points
|
||||
) {
|
||||
val ranges: UnivariateIntegrandRanges = if (borders.isEmpty() || borders.first() > range.endInclusive) {
|
||||
UnivariateIntegrandRanges(range to points)
|
||||
} else {
|
||||
UnivariateIntegrandRanges(
|
||||
listOf(
|
||||
range.start,
|
||||
*borders.filter { it in range }.sorted().toTypedArray(),
|
||||
range.endInclusive
|
||||
).zipWithNext { l, r ->
|
||||
l..r to points
|
||||
}
|
||||
)
|
||||
}
|
||||
return UnivariateIntegrandRanges(ranges)
|
||||
UnivariateIntegrandRanges.invoke(
|
||||
ranges
|
||||
)
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import space.kscience.kmath.functions.Function1D
|
||||
import space.kscience.kmath.functions.PiecewisePolynomial
|
||||
import space.kscience.kmath.interpolation.SplineInterpolator
|
||||
import space.kscience.kmath.interpolation.interpolatePolynomials
|
||||
import space.kscience.kmath.operations.Float64Field
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import kotlin.math.abs
|
||||
|
||||
@@ -16,6 +16,6 @@ public fun Function1D<Double>.cache(
|
||||
val length = abs(range.endInclusive - range.start)
|
||||
val grid = Float64Buffer(numCachePoints) { range.start + length / (numCachePoints - 1) * it }
|
||||
val vals = Float64Buffer(grid.size) { invoke(grid[it]) }
|
||||
val interpolator = SplineInterpolator(Float64Field)
|
||||
val interpolator = SplineInterpolator(DoubleField)
|
||||
return interpolator.interpolatePolynomials(grid, vals)
|
||||
}
|
||||
@@ -1,12 +1,18 @@
|
||||
package ru.inr.mass.models
|
||||
|
||||
import space.kscience.attributes.Attributes
|
||||
import space.kscience.kmath.integration.UnivariateIntegrand
|
||||
import space.kscience.kmath.integration.UnivariateIntegrandRanges
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
internal class TestGenerateRanges {
|
||||
@Test
|
||||
fun simpleRanges() {
|
||||
val ranges = generateRanges(0.0..100.0, 10.0, 55.0, 120.0)
|
||||
val attributes = Attributes<UnivariateIntegrand<*>>{
|
||||
multiRange(0.0..100.0, 10.0, 55.0, 120.0)
|
||||
}
|
||||
val ranges = attributes[UnivariateIntegrandRanges]!!
|
||||
assertEquals(3, ranges.ranges.size)
|
||||
assertEquals(55.0..100.0, ranges.ranges.last().first)
|
||||
assertEquals(10.0..55.0, ranges.ranges[1].first)
|
||||
|
||||
@@ -2,7 +2,6 @@ package ru.inr.mass.models
|
||||
|
||||
import space.kscience.kmath.real.div
|
||||
import space.kscience.kmath.real.sum
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
|
||||
private val defaultFss: FSS by lazy {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
plugins {
|
||||
id("space.kscience.gradle.jvm")
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
// `maven-publish`
|
||||
application
|
||||
kotlin("plugin.serialization")
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
id("org.graalvm.buildtools.native") version "0.10.5"
|
||||
`maven-publish`
|
||||
application
|
||||
}
|
||||
|
||||
kotlin {
|
||||
@@ -16,22 +16,20 @@ graalvmNative {
|
||||
}
|
||||
|
||||
val dataforgeVersion: String by rootProject.extra
|
||||
val plotlyKtVersion = "0.6.0"
|
||||
val visionForgeVersion: String by rootProject.extra
|
||||
val kmathVersion: String by rootProject.extra
|
||||
val tablesVersion: String by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
// implementation(projects.numassDataProto)
|
||||
implementation(projects.numassModel)
|
||||
implementation(projects.numassAnalysis)
|
||||
implementation("space.kscience:dataforge-workspace:$dataforgeVersion")
|
||||
|
||||
// implementation("space.kscience:kmath-jupyter:$kmathVersion")
|
||||
implementation("space.kscience:tables-kt:$tablesVersion")
|
||||
implementation("space.kscience:plotlykt-core:$plotlyKtVersion")
|
||||
|
||||
implementation("space.kscience:kmath-jupyter:$kmathVersion")
|
||||
implementation("space.kscience:tables-kt-csv:$tablesVersion")
|
||||
implementation("space.kscience:visionforge-plotly:$visionForgeVersion")
|
||||
implementation("com.charleskorn.kaml:kaml:0.45.0")
|
||||
implementation("com.github.ajalt.clikt:clikt:4.2.1")
|
||||
implementation("org.apache.commons:commons-csv:1.10.0")
|
||||
}
|
||||
|
||||
kscience{
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package ru.inr.mass.notebook
|
||||
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.html.*
|
||||
import kotlinx.html.stream.createHTML
|
||||
import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||
import org.jetbrains.kotlinx.jupyter.api.declare
|
||||
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.plotNumassBlock
|
||||
import ru.inr.mass.workspace.plotNumassSet
|
||||
import space.kscience.dataforge.data.DataTree
|
||||
import space.kscience.dataforge.data.DataTreeItem
|
||||
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() {
|
||||
repositories(
|
||||
"https://repo.kotlin.link",
|
||||
"https://maven.pkg.jetbrains.space/spc/p/sci/dev"
|
||||
)
|
||||
|
||||
import(
|
||||
"ru.inr.mass.models.*",
|
||||
"ru.inr.mass.data.analysis.*",
|
||||
"ru.inr.mass.workspace.*",
|
||||
"ru.inr.mass.data.api.*",
|
||||
"ru.inr.mass.data.proto.*",
|
||||
"space.kscience.dataforge.data.*",
|
||||
"kotlinx.coroutines.*",
|
||||
"kotlinx.coroutines.flow.*",
|
||||
)
|
||||
|
||||
import<Numass>()
|
||||
|
||||
onLoaded {
|
||||
declare("Numass" to Numass, "workspace" to Numass.workspace)
|
||||
}
|
||||
|
||||
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.plotNumassSet(numassSet).toPage().render())
|
||||
}
|
||||
|
||||
render<DataTree<NumassDirectorySet>> { tree ->
|
||||
HTML(createHTML().div { numassTree(tree) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FlowContent.numassTree(tree: DataTree<NumassDirectorySet>) {
|
||||
ul {
|
||||
runBlocking {
|
||||
tree.items.forEach { (token, treeItem) ->
|
||||
li {
|
||||
p { +token.toString() }
|
||||
when (treeItem) {
|
||||
is DataTreeItem.Leaf -> {}
|
||||
is DataTreeItem.Node -> numassTree(treeItem.tree)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ import kotlinx.html.*
|
||||
import ru.inr.mass.models.*
|
||||
import ru.inr.mass.workspace.buffer
|
||||
import ru.inr.mass.workspace.fitWith
|
||||
import ru.inr.mass.workspace.freeParameters
|
||||
import ru.inr.mass.workspace.iterations
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.data.XYErrorColumnarData
|
||||
import space.kscience.kmath.data.indices
|
||||
@@ -127,17 +129,19 @@ suspend fun fitNumassSpectrumCustom(
|
||||
spectrum: NBkgSpectrum,
|
||||
data: XYErrorColumnarData<Double, Double, Double>,
|
||||
fitParams: List<Symbol>,
|
||||
initial: Map<Symbol, Double>, vararg features: OptimizationFeature = emptyArray()): XYFit {
|
||||
initial: Map<Symbol, Double>,
|
||||
logger: Loggable
|
||||
): XYFit {
|
||||
|
||||
return data.fitWith(
|
||||
optimizer = QowOptimizer,
|
||||
modelExpression = spectrum,
|
||||
startingPoint = initial,
|
||||
*features,
|
||||
OptimizationParameters(
|
||||
fitParams
|
||||
),
|
||||
OptimizationIterations(30)
|
||||
attributesBuilder = {
|
||||
freeParameters(*fitParams.toTypedArray())
|
||||
iterations(30)
|
||||
OptimizationLog(logger)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -205,7 +209,7 @@ suspend fun processCustom(
|
||||
fitVars += rearWall
|
||||
}
|
||||
|
||||
val fit = fitNumassSpectrumCustom(spectrum, data, fitVars, fitParams, OptimizationLog(dumpLogger))
|
||||
val fit = fitNumassSpectrumCustom(spectrum, data, fitVars, fitParams, dumpLogger)
|
||||
|
||||
val dataPath = Path(spectrumFile)
|
||||
|
||||
@@ -224,12 +228,12 @@ suspend fun processCustom(
|
||||
name = "Initial"
|
||||
mode = ScatterMode.lines
|
||||
x.buffer = data.x
|
||||
y.numbers = x.doubles.map { spectrum(it, fitParams + fit.resultPoint) }
|
||||
y.numbers = x.doubles.map { spectrum(it, fitParams + fit.result) }
|
||||
File(dataPath.parent.toString(), dataPath.nameWithoutExtension + postfix + ".fit")
|
||||
.printWriter().use {
|
||||
out -> out.println("U_sp\tcounts\tresidials")
|
||||
data.indices.map{
|
||||
val value = spectrum(data.x[it], fitParams + fit.resultPoint)
|
||||
val value = spectrum(data.x[it], fitParams + fit.result)
|
||||
val dif = data.y[it] - value
|
||||
out.println("${data.x[it]}\t${data.y[it]}\t${dif/data.yErr[it]}")
|
||||
}
|
||||
@@ -239,7 +243,7 @@ suspend fun processCustom(
|
||||
name = "Fit"
|
||||
mode = ScatterMode.lines
|
||||
x.buffer = data.x
|
||||
y.numbers = data.x.toDoubleArray().map { spectrum(it, fitParams + fit.resultPoint) }
|
||||
y.numbers = data.x.toDoubleArray().map { spectrum(it, fitParams + fit.result) }
|
||||
}
|
||||
}
|
||||
plot{
|
||||
@@ -251,7 +255,7 @@ suspend fun processCustom(
|
||||
mode = ScatterMode.markers
|
||||
x.buffer = testData.x
|
||||
y.numbers = testData.indices.map{
|
||||
val value = spectrum(testData.x[it], fitParams + fit.resultPoint)
|
||||
val value = spectrum(testData.x[it], fitParams + fit.result)
|
||||
val dif = testData.y[it] - value
|
||||
dif/testData.yErr[it]
|
||||
}
|
||||
@@ -263,7 +267,7 @@ suspend fun processCustom(
|
||||
}
|
||||
histogram {
|
||||
x.numbers = data.indices.map{
|
||||
val value = spectrum(data.x[it], fitParams + fit.resultPoint)
|
||||
val value = spectrum(data.x[it], fitParams + fit.result)
|
||||
val dif = data.y[it] - value
|
||||
dif/data.yErr[it]
|
||||
}
|
||||
@@ -275,7 +279,7 @@ suspend fun processCustom(
|
||||
}
|
||||
br()
|
||||
p {
|
||||
+"fit result = ${fit.resultPoint}"
|
||||
+"fit result = ${fit.result}"
|
||||
}
|
||||
h4 {
|
||||
+"Fit log:"
|
||||
@@ -298,7 +302,7 @@ suspend fun processCustom(
|
||||
tr {
|
||||
td { +testData.x[it].toString() }
|
||||
td {
|
||||
val value = spectrum(testData.x[it], fitParams + fit.resultPoint)
|
||||
val value = spectrum(testData.x[it], fitParams + fit.result)
|
||||
val dif = testData.y[it] - value
|
||||
+(dif/testData.yErr[it]).toString()
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import kotlinx.html.*
|
||||
import ru.inr.mass.models.*
|
||||
import ru.inr.mass.workspace.buffer
|
||||
import ru.inr.mass.workspace.fitWith
|
||||
import ru.inr.mass.workspace.freeParameters
|
||||
import ru.inr.mass.workspace.iterations
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.data.XYErrorColumnarData
|
||||
import space.kscience.kmath.data.indices
|
||||
@@ -119,25 +121,20 @@ private fun main(args: Array<String>) = Args().main(args)
|
||||
private suspend fun fitNumassSpectrum(
|
||||
spectrum: NBkgSpectrum,
|
||||
data: XYErrorColumnarData<Double, Double, Double>,
|
||||
initial: Map<Symbol, Double>, vararg features: OptimizationFeature = emptyArray()): XYFit {
|
||||
initial: Map<Symbol, Double>,
|
||||
logger: Loggable): XYFit {
|
||||
|
||||
return data.fitWith(
|
||||
optimizer = QowOptimizer,
|
||||
modelExpression = spectrum,
|
||||
startingPoint = initial,
|
||||
*features,
|
||||
OptimizationParameters(
|
||||
NumassBeta.e0,
|
||||
NBkgSpectrum.norm,
|
||||
NBkgSpectrum.bkg,
|
||||
|
||||
// NumassBeta.u2,
|
||||
|
||||
// NumassBeta.mnu2,
|
||||
// NumassBeta.msterile2,
|
||||
NumassTransmission.trap,
|
||||
),
|
||||
OptimizationIterations(20)
|
||||
attributesBuilder = {
|
||||
freeParameters(NumassBeta.e0,
|
||||
NBkgSpectrum.norm,
|
||||
NBkgSpectrum.bkg)
|
||||
iterations(30)
|
||||
OptimizationLog(logger)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -170,7 +167,7 @@ private suspend fun process(spectrumFile: String, full: String?, postfix: String
|
||||
println("[$tag] ${block()}")
|
||||
}
|
||||
|
||||
val fit = fitNumassSpectrum(spectrum, data, fitParams, OptimizationLog(dumpLogger))
|
||||
val fit = fitNumassSpectrum(spectrum, data, fitParams, dumpLogger)
|
||||
|
||||
val dataPath = Path(spectrumFile)
|
||||
|
||||
@@ -189,12 +186,12 @@ private suspend fun process(spectrumFile: String, full: String?, postfix: String
|
||||
name = "Initial"
|
||||
mode = ScatterMode.lines
|
||||
x.buffer = data.x
|
||||
y.numbers = x.doubles.map { spectrum(it, fitParams + fit.resultPoint) }
|
||||
y.numbers = x.doubles.map { spectrum(it, fitParams + fit.result) }
|
||||
File(dataPath.parent.toString(), dataPath.nameWithoutExtension + postfix + ".fit")
|
||||
.printWriter().use {
|
||||
out -> out.println("U_sp\tcounts\tresidials")
|
||||
data.indices.map{
|
||||
val value = spectrum(data.x[it], fitParams + fit.resultPoint)
|
||||
val value = spectrum(data.x[it], fitParams + fit.result)
|
||||
val dif = data.y[it] - value
|
||||
out.println("${data.x[it]}\t${data.y[it]}\t${dif/data.yErr[it]}")
|
||||
}
|
||||
@@ -204,7 +201,7 @@ private suspend fun process(spectrumFile: String, full: String?, postfix: String
|
||||
name = "Fit"
|
||||
mode = ScatterMode.lines
|
||||
x.buffer = data.x
|
||||
y.numbers = data.x.toDoubleArray().map { spectrum(it, fitParams + fit.resultPoint) }
|
||||
y.numbers = data.x.toDoubleArray().map { spectrum(it, fitParams + fit.result) }
|
||||
}
|
||||
}
|
||||
plot{
|
||||
@@ -216,7 +213,7 @@ private suspend fun process(spectrumFile: String, full: String?, postfix: String
|
||||
mode = ScatterMode.markers
|
||||
x.buffer = testData.x
|
||||
y.numbers = testData.indices.map{
|
||||
val value = spectrum(testData.x[it], fitParams + fit.resultPoint)
|
||||
val value = spectrum(testData.x[it], fitParams + fit.result)
|
||||
val dif = testData.y[it] - value
|
||||
dif/testData.yErr[it]
|
||||
}
|
||||
@@ -228,7 +225,7 @@ private suspend fun process(spectrumFile: String, full: String?, postfix: String
|
||||
}
|
||||
histogram {
|
||||
x.numbers = data.indices.map{
|
||||
val value = spectrum(data.x[it], fitParams + fit.resultPoint)
|
||||
val value = spectrum(data.x[it], fitParams + fit.result)
|
||||
val dif = data.y[it] - value
|
||||
dif/data.yErr[it]
|
||||
}
|
||||
@@ -240,7 +237,7 @@ private suspend fun process(spectrumFile: String, full: String?, postfix: String
|
||||
}
|
||||
br()
|
||||
p {
|
||||
+"fit result = ${fit.resultPoint}"
|
||||
+"fit result = ${fit.result}"
|
||||
}
|
||||
h4 {
|
||||
+"Fit log:"
|
||||
@@ -263,7 +260,7 @@ private suspend fun process(spectrumFile: String, full: String?, postfix: String
|
||||
tr {
|
||||
td { +testData.x[it].toString() }
|
||||
td {
|
||||
val value = spectrum(testData.x[it], fitParams + fit.resultPoint)
|
||||
val value = spectrum(testData.x[it], fitParams + fit.result)
|
||||
val dif = testData.y[it] - value
|
||||
+(dif/testData.yErr[it]).toString()
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package ru.inr.mass.workspace
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import ru.inr.mass.data.api.NumassBlock
|
||||
import ru.inr.mass.data.api.NumassPoint
|
||||
import ru.inr.mass.data.proto.*
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.dataforge.data.DataTree
|
||||
import space.kscience.dataforge.workspace.Workspace
|
||||
import java.nio.file.Path
|
||||
|
||||
object Numass {
|
||||
val workspace = Workspace {
|
||||
context {
|
||||
plugin(NumassWorkspacePlugin)
|
||||
}
|
||||
}
|
||||
|
||||
val context get() = workspace.context
|
||||
|
||||
val numassProto by lazy { context.fetch(NumassProtoPlugin) }
|
||||
|
||||
fun readPoint(path: Path): NumassPoint =
|
||||
numassProto.readNumassPointFile(path) ?: error("Can't read numass point at $path")
|
||||
|
||||
fun readPoint(path: String): NumassPoint =
|
||||
numassProto.readNumassPointFile(path) ?: error("Can't read numass point at $path")
|
||||
|
||||
fun readDirectory(path: Path): NumassDirectorySet = numassProto.readNumassDirectory(path)
|
||||
|
||||
fun readDirectory(path: String): NumassDirectorySet = numassProto.readNumassDirectory(path)
|
||||
|
||||
fun readRepository(path: Path): DataTree<NumassDirectorySet> =
|
||||
runBlocking(Dispatchers.IO) { numassProto.readRepository(path) }
|
||||
|
||||
fun readRepository(path: String): DataTree<NumassDirectorySet> =
|
||||
runBlocking(Dispatchers.IO) { numassProto.readRepository(path) }
|
||||
|
||||
}
|
||||
|
||||
fun NumassBlock.listFrames() = runBlocking { frames.toList() }
|
||||
|
||||
fun NumassBlock.listEvents() = runBlocking { events.toList() }
|
||||
@@ -1,132 +0,0 @@
|
||||
package ru.inr.mass.workspace
|
||||
|
||||
import ru.inr.mass.data.analysis.NumassAnalyzerParameters
|
||||
import ru.inr.mass.data.analysis.NumassEventExtractor
|
||||
import ru.inr.mass.data.analysis.TimeAnalyzer
|
||||
import ru.inr.mass.data.analysis.analyzeSet
|
||||
import ru.inr.mass.data.api.NumassSet
|
||||
import ru.inr.mass.data.proto.NumassProtoPlugin
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.PluginFactory
|
||||
import space.kscience.dataforge.context.PluginTag
|
||||
import space.kscience.dataforge.data.filterByType
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.value
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.workspace.WorkspacePlugin
|
||||
import space.kscience.dataforge.workspace.pipeFrom
|
||||
import space.kscience.dataforge.workspace.task
|
||||
import space.kscience.tables.Table
|
||||
|
||||
class NumassWorkspacePlugin : WorkspacePlugin() {
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
val numassProtoPlugin by require(NumassProtoPlugin)
|
||||
|
||||
val selectSets by task<NumassSet>(
|
||||
descriptor = MetaDescriptor {
|
||||
info = "Select data from workspace data pool"
|
||||
value("forward", ValueType.BOOLEAN) {
|
||||
info = "Select only forward or only backward sets"
|
||||
}
|
||||
}
|
||||
) {
|
||||
val forward = meta["forward"]?.boolean
|
||||
val filtered = workspace.data.filterByType<NumassSet> { _, meta ->
|
||||
when (forward) {
|
||||
true -> meta["iteration_info.reverse"]?.boolean?.not() ?: false
|
||||
false -> meta["iteration_info.reverse"]?.boolean ?: false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
node(Name.EMPTY, filtered)
|
||||
}
|
||||
|
||||
|
||||
val analyzeSets by task<Table<Value>>(
|
||||
MetaDescriptor {
|
||||
info = "Count the number of events for each voltage and produce a table with the results"
|
||||
}
|
||||
) {
|
||||
pipeFrom(selectSets) { set, name, meta ->
|
||||
val res = TimeAnalyzer(NumassEventExtractor.EVENTS_ONLY).analyzeSet(
|
||||
set,
|
||||
NumassAnalyzerParameters.read(meta["analyzer"] ?: Meta.EMPTY)
|
||||
)
|
||||
val outputMeta = meta.toMutableMeta().apply {
|
||||
"data" put set.meta
|
||||
}
|
||||
// context.output.render(res, stage = "numass.analyze", name = name, meta = outputMeta)
|
||||
res
|
||||
}
|
||||
}
|
||||
//
|
||||
// val monitorTableTask: TaskReference<Table<Value>> by task(
|
||||
// MetaDescriptor {
|
||||
// value("showPlot", type = ValueType.BOOLEAN) {
|
||||
// info = "Show plot after complete"
|
||||
// }
|
||||
// value("monitorPoint", type = ValueType.NUMBER) {
|
||||
// info = "The voltage for monitor point"
|
||||
// }
|
||||
// }
|
||||
// ) {
|
||||
// val data = from(selectSets)
|
||||
//// model { meta ->
|
||||
//// dependsOn(selectTask, meta)
|
||||
////// if (meta.getBoolean("monitor.correctForThreshold", false)) {
|
||||
////// dependsOn(subThresholdTask, meta, "threshold")
|
||||
////// }
|
||||
//// configure(meta.getMetaOrEmpty("monitor"))
|
||||
//// configure {
|
||||
//// meta.useMeta("analyzer") { putNode(it) }
|
||||
//// setValue("@target", meta.getString("@target", meta.name))
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// val monitorVoltage = meta["monitorPoint"].double ?: 16000.0
|
||||
// val analyzer = TimeAnalyzer()
|
||||
// val analyzerMeta = meta["analyzer"]
|
||||
//
|
||||
// //val thresholdCorrection = da
|
||||
// //TODO add separator labels
|
||||
// val res = ListTable.Builder("timestamp", "count", "cr", "crErr", "index", "set")
|
||||
// .rows(
|
||||
// data.values.stream().flatMap { set ->
|
||||
// set.points.stream()
|
||||
// .filter { it.voltage == monitorVoltage }
|
||||
// .parallel()
|
||||
// .map { point ->
|
||||
// analyzer.analyzeParent(point, analyzerMeta).edit {
|
||||
// "index" to point.index
|
||||
// "set" to set.name
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// ).build()
|
||||
//
|
||||
// if (meta["showPlot"].boolean ?: true) {
|
||||
// val plot = DataPlot.plot(name, res, Adapters.buildXYAdapter("timestamp", "cr", "crErr"))
|
||||
// context.plot(plot, name, "numass.monitor") {
|
||||
// "xAxis.title" to "time"
|
||||
// "xAxis.type" to "time"
|
||||
// "yAxis.title" to "Count rate"
|
||||
// "yAxis.units" to "Hz"
|
||||
// }
|
||||
//
|
||||
// ((context.output["numass.monitor", name] as? PlotOutput)?.frame as? JFreeChartFrame)?.addSetMarkers(data.values)
|
||||
// }
|
||||
//
|
||||
// context.output.render(res, stage = "numass.monitor", name = name, meta = meta)
|
||||
//
|
||||
// data(Name.EMPTY, res)
|
||||
// }
|
||||
|
||||
companion object : PluginFactory<NumassWorkspacePlugin> {
|
||||
override val tag: PluginTag = PluginTag("numass", "ru.mipt.npm")
|
||||
override fun build(context: Context, meta: Meta): NumassWorkspacePlugin = NumassWorkspacePlugin()
|
||||
}
|
||||
}
|
||||
@@ -3,44 +3,95 @@
|
||||
package ru.inr.mass.workspace
|
||||
|
||||
import ru.inr.mass.models.Spectrum
|
||||
import space.kscience.attributes.Attributes
|
||||
import space.kscience.attributes.AttributesBuilder
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.data.XYColumnarData
|
||||
import space.kscience.kmath.data.XYErrorColumnarData
|
||||
import space.kscience.kmath.expressions.AutoDiffProcessor
|
||||
import space.kscience.kmath.expressions.DifferentiableExpression
|
||||
import space.kscience.kmath.expressions.ExpressionAlgebra
|
||||
import space.kscience.kmath.expressions.Symbol
|
||||
import space.kscience.kmath.misc.FeatureSet
|
||||
import space.kscience.kmath.misc.Loggable
|
||||
import space.kscience.kmath.operations.ExtendedField
|
||||
import space.kscience.kmath.optimization.*
|
||||
import space.kscience.kmath.random.RandomGenerator
|
||||
import space.kscience.kmath.samplers.PoissonSampler
|
||||
import space.kscience.kmath.stat.next
|
||||
import space.kscience.kmath.structures.Float64
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
import kotlin.math.sqrt
|
||||
|
||||
//public suspend fun XYColumnarData<Double, Double, Double>.fitWith(
|
||||
// optimizer: Optimizer<Double, XYFit>,
|
||||
// modelExpression: DifferentiableExpression<Double>,
|
||||
// startingPoint: Map<Symbol, Double>,
|
||||
// vararg features: OptimizationFeature = emptyArray(),
|
||||
// xSymbol: Symbol = Symbol.x,
|
||||
// pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
||||
// pointWeight: PointWeight = PointWeight.byYSigma,
|
||||
//): XYFit {
|
||||
// var actualFeatures = FeatureSet.of(*features, OptimizationStartPoint(startingPoint))
|
||||
//
|
||||
// if (actualFeatures.getFeature<OptimizationLog>() == null) {
|
||||
// actualFeatures = actualFeatures.with(OptimizationLog(Loggable.console))
|
||||
// }
|
||||
// val problem = XYFit(
|
||||
// this,
|
||||
// modelExpression,
|
||||
// actualFeatures,
|
||||
// pointToCurveDistance,
|
||||
// pointWeight,
|
||||
// xSymbol
|
||||
// )
|
||||
// return optimizer.optimize(problem)
|
||||
//}
|
||||
|
||||
public fun AttributesBuilder<OptimizationProblem<*>>.freeParameters(vararg symbols: Symbol) {
|
||||
OptimizationParameters(symbols.asList())
|
||||
}
|
||||
|
||||
public fun AttributesBuilder<OptimizationProblem<*>>.iterations(iterations: Int) {
|
||||
OptimizationIterations(iterations)
|
||||
}
|
||||
|
||||
public suspend fun XYColumnarData<Double, Double, Double>.fitWith(
|
||||
optimizer: Optimizer<Double, XYFit>,
|
||||
modelExpression: DifferentiableExpression<Double>,
|
||||
modelExpression: DifferentiableExpression<Float64>,
|
||||
startingPoint: Map<Symbol, Double>,
|
||||
vararg features: OptimizationFeature = emptyArray(),
|
||||
attributesBuilder: AttributesBuilder<XYFit>.() -> Unit,
|
||||
xSymbol: Symbol = Symbol.x,
|
||||
pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
||||
pointWeight: PointWeight = PointWeight.byYSigma,
|
||||
): XYFit {
|
||||
var actualFeatures = FeatureSet.of(*features, OptimizationStartPoint(startingPoint))
|
||||
): XYFit = fitWith(
|
||||
optimizer = optimizer,
|
||||
modelExpression = modelExpression,
|
||||
startingPoint = startingPoint,
|
||||
attributes = Attributes<XYFit>(attributesBuilder),
|
||||
xSymbol = xSymbol,
|
||||
pointToCurveDistance = pointToCurveDistance,
|
||||
pointWeight = pointWeight
|
||||
)
|
||||
|
||||
if (actualFeatures.getFeature<OptimizationLog>() == null) {
|
||||
actualFeatures = actualFeatures.with(OptimizationLog(Loggable.console))
|
||||
}
|
||||
val problem = XYFit(
|
||||
this,
|
||||
modelExpression,
|
||||
actualFeatures,
|
||||
pointToCurveDistance,
|
||||
pointWeight,
|
||||
xSymbol
|
||||
)
|
||||
return optimizer.optimize(problem)
|
||||
}
|
||||
|
||||
public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith(
|
||||
optimizer: Optimizer<Double, XYFit>,
|
||||
processor: AutoDiffProcessor<Double, I, A>,
|
||||
startingPoint: Map<Symbol, Double>,
|
||||
attributesBuilder: AttributesBuilder<XYFit>.() -> Unit,
|
||||
xSymbol: Symbol = Symbol.x,
|
||||
pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
||||
pointWeight: PointWeight = PointWeight.byYSigma,
|
||||
model: A.(I) -> I,
|
||||
): XYFit where A : ExtendedField<I>, A : ExpressionAlgebra<Double, I> = fitWith(
|
||||
optimizer = optimizer,
|
||||
processor = processor,
|
||||
startingPoint = startingPoint,
|
||||
attributes = Attributes<XYFit>(attributesBuilder),
|
||||
xSymbol = xSymbol,
|
||||
pointToCurveDistance = pointToCurveDistance,
|
||||
pointWeight = pointWeight,
|
||||
model = model
|
||||
)
|
||||
|
||||
public suspend fun Spectrum.generate(
|
||||
strategy: Map<Double, Double>,
|
||||
|
||||
@@ -1,147 +1,18 @@
|
||||
package ru.inr.mass.workspace
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.html.h1
|
||||
import kotlinx.html.h2
|
||||
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.*
|
||||
import ru.inr.mass.data.proto.HVData
|
||||
import ru.inr.mass.data.proto.NumassDirectorySet
|
||||
|
||||
import space.kscience.dataforge.meta.asValue
|
||||
import space.kscience.dataforge.meta.double
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.domains.center
|
||||
import space.kscience.kmath.histogram.Histogram1D
|
||||
import space.kscience.kmath.operations.asIterable
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.plotly.*
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import space.kscience.plotly.models.*
|
||||
import kotlin.time.DurationUnit
|
||||
|
||||
/**
|
||||
* Plot a kmath histogram
|
||||
*/
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
fun Plot.histogram(histogram: Histogram1D<Double, Double>, block: Scatter.() -> Unit = {}): Trace = scatter {
|
||||
x.numbers = histogram.bins.map { it.domain.center }
|
||||
y.numbers = histogram.bins.map { it.binValue }
|
||||
line.shape = LineShape.hv
|
||||
block()
|
||||
}
|
||||
|
||||
fun Plot.histogram(
|
||||
spectrum: NumassAmplitudeSpectrum,
|
||||
binSize: UInt = 20U,
|
||||
block: Scatter.() -> Unit = {},
|
||||
): Trace = scatter {
|
||||
val binned = spectrum.binned(binSize)
|
||||
x.numbers = binned.keys.map { (it.first + it.last).toDouble() / 2.0 }
|
||||
y.numbers = binned.values
|
||||
line.shape = LineShape.hv
|
||||
block()
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a plot from hv data
|
||||
*/
|
||||
fun Plot.hvData(data: HVData): Trace = scatter {
|
||||
x.strings = data.map { it.timestamp.toString() }
|
||||
y.numbers = data.map { it.value }
|
||||
}
|
||||
|
||||
|
||||
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.channels.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,
|
||||
): 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.hvData?.let { entries ->
|
||||
h2 { +"HV" }
|
||||
plot {
|
||||
hvData(entries)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a number buffer accessor for Plotly trace values
|
||||
*/
|
||||
public var TraceValues.buffer: Buffer<Number>
|
||||
get() = value?.list?.let { list -> DoubleBuffer(list.size) { list[it].double } } ?: DoubleBuffer()
|
||||
get() = value?.list?.let { list -> Float64Buffer(list.size) { list[it].double } } ?: Float64Buffer()
|
||||
set(value) {
|
||||
this.value = value.asIterable().map { it.asValue() }.asValue()
|
||||
}
|
||||
108
numass-workspace/src/main/resources/data/2023_events.tsv
Normal file
108
numass-workspace/src/main/resources/data/2023_events.tsv
Normal file
@@ -0,0 +1,108 @@
|
||||
U events error
|
||||
12000 6.452460E+07 8032.720335
|
||||
12050 6.308058E+07 7942.32812
|
||||
12100 6.166233E+07 7852.536369
|
||||
12150 6.026178E+07 7762.846435
|
||||
12200 5.888044E+07 7673.359382
|
||||
12250 5.752020E+07 7584.207129
|
||||
12300 5.618589E+07 7495.725049
|
||||
12350 5.486976E+07 7407.412404
|
||||
12400 5.357057E+07 7319.192132
|
||||
12450 5.229649E+07 7231.631507
|
||||
12500 5.104097E+07 7144.295993
|
||||
12550 4.980586E+07 7057.326711
|
||||
12600 4.858747E+07 6970.471306
|
||||
12650 4.739252E+07 6884.222328
|
||||
12700 4.621748E+07 6798.344134
|
||||
12750 4.505844E+07 6712.55872
|
||||
12800 4.392086E+07 6627.281125
|
||||
12850 4.280192E+07 6542.317643
|
||||
12900 4.170236E+07 6457.736238
|
||||
12950 4.062241E+07 6373.571204
|
||||
13000 3.955862E+07 6289.564579
|
||||
13050 3.851518E+07 6206.059556
|
||||
13100 3.748997E+07 6122.905734
|
||||
13150 3.648207E+07 6040.03875
|
||||
13200 3.549434E+07 5957.712236
|
||||
13250 3.452146E+07 5875.496153
|
||||
13300 3.356598E+07 5793.615159
|
||||
13350 3.263059E+07 5712.318869
|
||||
13400 3.171169E+07 5631.313607
|
||||
13450 3.080984E+07 5550.661274
|
||||
13500 2.992572E+07 5470.440919
|
||||
13550 2.905686E+07 5390.441869
|
||||
13600 2.820575E+07 5310.908839
|
||||
13650 2.737116E+07 5231.745008
|
||||
13700 2.655560E+07 5153.212589
|
||||
13750 2.575232E+07 5074.674515
|
||||
13800 2.496715E+07 4996.713422
|
||||
13850 2.419569E+07 4918.911404
|
||||
13900 2.344232E+07 4841.727268
|
||||
13950 2.270363E+07 4764.832291
|
||||
14000 2.198215E+07 4688.512852
|
||||
14050 2.127411E+07 4612.386446
|
||||
14100 2.058196E+07 4536.734227
|
||||
14150 1.990347E+07 4461.330615
|
||||
14200 1.924117E+07 4386.475463
|
||||
14250 1.859371E+07 4312.041926
|
||||
14300 1.796066E+07 4238.001528
|
||||
14350 1.734144E+07 4164.305627
|
||||
14400 1.673491E+07 4090.832005
|
||||
14450 1.614486E+07 4018.066921
|
||||
14500 1.556582E+07 3945.354348
|
||||
14550 1.500395E+07 3873.492826
|
||||
14600 1.445357E+07 3801.785423
|
||||
14650 1.391677E+07 3730.51812
|
||||
14700 1.339411E+07 3659.796472
|
||||
14750 1.288430E+07 3589.470303
|
||||
14800 1.238646E+07 3519.440284
|
||||
14850 1.190164E+07 3449.875909
|
||||
14900 1.143011E+07 3380.844281
|
||||
14950 1.097078E+07 3312.217027
|
||||
15000 1.052425E+07 3244.109423
|
||||
15050 1.008924E+07 3176.356172
|
||||
15100 9.665787E+06 3108.984892
|
||||
15150 9.254249E+06 3042.079724
|
||||
15200 8.854339E+06 2975.624154
|
||||
15250 8.467155E+06 2909.837666
|
||||
15300 8.090963E+06 2844.46187
|
||||
15350 7.725603E+06 2779.496931
|
||||
15400 7.370687E+06 2714.900844
|
||||
15450 7.028022E+06 2651.041609
|
||||
15500 6.694518E+06 2587.376647
|
||||
15550 6.372090E+06 2524.299879
|
||||
15600 6.058846E+06 2461.472259
|
||||
15650 5.758606E+06 2399.709617
|
||||
15700 5.466336E+06 2338.019685
|
||||
15750 5.183979E+06 2276.835393
|
||||
15800 4.912587E+06 2216.435542
|
||||
15850 4.648231E+06 2155.975548
|
||||
15900 4.396058E+06 2096.677784
|
||||
15950 4.151727E+06 2037.578662
|
||||
16000 3.916397E+06 1978.98901
|
||||
16100 3.473288E+06 1863.676016
|
||||
16200 3.065010E+06 1750.717128
|
||||
16300 2.688767E+06 1639.746111
|
||||
16400 2.344119E+06 1531.051707
|
||||
16500 2.029421E+06 1424.577365
|
||||
16600 1.743956E+06 1320.589413
|
||||
16700 1.487062E+06 1219.45145
|
||||
16800 1.255541E+06 1120.509421
|
||||
16900 1.049216E+06 1024.312329
|
||||
17000 8.724297E+05 934.0394267
|
||||
17100 7.157295E+05 846.0079518
|
||||
17200 5.750288E+05 758.3065238
|
||||
17300 4.560588E+05 675.3212528
|
||||
17400 3.553991E+05 596.1536111
|
||||
17500 2.697442E+05 519.3690855
|
||||
17600 2.005270E+05 447.8024159
|
||||
17700 1.434300E+05 378.7215839
|
||||
17800 9.860455E+04 314.0136092
|
||||
17900 6.354514E+04 252.0816166
|
||||
18000 3.898907E+04 197.456499
|
||||
18100 2.149273E+04 146.6039915
|
||||
18200 1.010559E+04 100.5265405
|
||||
18300 4.910901E+03 70.07781835
|
||||
18400 2.252190E+03 47.4572434
|
||||
18500 1.860929E+03 43.13848425
|
||||
18600 1.760000E+03 41.95235393
|
||||
|
@@ -33,7 +33,7 @@ dependencyResolutionManagement {
|
||||
}
|
||||
|
||||
versionCatalogs {
|
||||
create("npmlibs") {
|
||||
create("spclibs") {
|
||||
from("space.kscience:version-catalog:$toolsVersion")
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ dependencyResolutionManagement {
|
||||
|
||||
include(
|
||||
":numass-data-model",
|
||||
":numass-analysis",
|
||||
// ":numass-analysis",
|
||||
// ":numass-data-proto",
|
||||
// ":numass-data-server",
|
||||
":numass-workspace",
|
||||
|
||||
Reference in New Issue
Block a user