Compare commits

...

3 Commits

Author SHA1 Message Date
0dded083ba merge with dev 2025-03-17 11:06:37 +03:00
1764eef183 Update code to be used with latest ecosystem versions. 2025-03-16 16:43:14 +03:00
232669af80 Updates and fixes 2023-10-25 20:22:20 +03:00
37 changed files with 492 additions and 675 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.kotlin
gradlew
gradlew.bat

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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`
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
}
}

View File

@@ -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)

View File

@@ -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)
}
}

View File

@@ -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())
}
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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") {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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)!!

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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
)
}

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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{

View File

@@ -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)
}
}
}
}
}
}

View File

@@ -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()
}

View File

@@ -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()
}

View File

@@ -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() }

View File

@@ -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()
}
}

View File

@@ -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>,

View File

@@ -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()
}

View 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
1 U events error
2 12000 6.452460E+07 8032.720335
3 12050 6.308058E+07 7942.32812
4 12100 6.166233E+07 7852.536369
5 12150 6.026178E+07 7762.846435
6 12200 5.888044E+07 7673.359382
7 12250 5.752020E+07 7584.207129
8 12300 5.618589E+07 7495.725049
9 12350 5.486976E+07 7407.412404
10 12400 5.357057E+07 7319.192132
11 12450 5.229649E+07 7231.631507
12 12500 5.104097E+07 7144.295993
13 12550 4.980586E+07 7057.326711
14 12600 4.858747E+07 6970.471306
15 12650 4.739252E+07 6884.222328
16 12700 4.621748E+07 6798.344134
17 12750 4.505844E+07 6712.55872
18 12800 4.392086E+07 6627.281125
19 12850 4.280192E+07 6542.317643
20 12900 4.170236E+07 6457.736238
21 12950 4.062241E+07 6373.571204
22 13000 3.955862E+07 6289.564579
23 13050 3.851518E+07 6206.059556
24 13100 3.748997E+07 6122.905734
25 13150 3.648207E+07 6040.03875
26 13200 3.549434E+07 5957.712236
27 13250 3.452146E+07 5875.496153
28 13300 3.356598E+07 5793.615159
29 13350 3.263059E+07 5712.318869
30 13400 3.171169E+07 5631.313607
31 13450 3.080984E+07 5550.661274
32 13500 2.992572E+07 5470.440919
33 13550 2.905686E+07 5390.441869
34 13600 2.820575E+07 5310.908839
35 13650 2.737116E+07 5231.745008
36 13700 2.655560E+07 5153.212589
37 13750 2.575232E+07 5074.674515
38 13800 2.496715E+07 4996.713422
39 13850 2.419569E+07 4918.911404
40 13900 2.344232E+07 4841.727268
41 13950 2.270363E+07 4764.832291
42 14000 2.198215E+07 4688.512852
43 14050 2.127411E+07 4612.386446
44 14100 2.058196E+07 4536.734227
45 14150 1.990347E+07 4461.330615
46 14200 1.924117E+07 4386.475463
47 14250 1.859371E+07 4312.041926
48 14300 1.796066E+07 4238.001528
49 14350 1.734144E+07 4164.305627
50 14400 1.673491E+07 4090.832005
51 14450 1.614486E+07 4018.066921
52 14500 1.556582E+07 3945.354348
53 14550 1.500395E+07 3873.492826
54 14600 1.445357E+07 3801.785423
55 14650 1.391677E+07 3730.51812
56 14700 1.339411E+07 3659.796472
57 14750 1.288430E+07 3589.470303
58 14800 1.238646E+07 3519.440284
59 14850 1.190164E+07 3449.875909
60 14900 1.143011E+07 3380.844281
61 14950 1.097078E+07 3312.217027
62 15000 1.052425E+07 3244.109423
63 15050 1.008924E+07 3176.356172
64 15100 9.665787E+06 3108.984892
65 15150 9.254249E+06 3042.079724
66 15200 8.854339E+06 2975.624154
67 15250 8.467155E+06 2909.837666
68 15300 8.090963E+06 2844.46187
69 15350 7.725603E+06 2779.496931
70 15400 7.370687E+06 2714.900844
71 15450 7.028022E+06 2651.041609
72 15500 6.694518E+06 2587.376647
73 15550 6.372090E+06 2524.299879
74 15600 6.058846E+06 2461.472259
75 15650 5.758606E+06 2399.709617
76 15700 5.466336E+06 2338.019685
77 15750 5.183979E+06 2276.835393
78 15800 4.912587E+06 2216.435542
79 15850 4.648231E+06 2155.975548
80 15900 4.396058E+06 2096.677784
81 15950 4.151727E+06 2037.578662
82 16000 3.916397E+06 1978.98901
83 16100 3.473288E+06 1863.676016
84 16200 3.065010E+06 1750.717128
85 16300 2.688767E+06 1639.746111
86 16400 2.344119E+06 1531.051707
87 16500 2.029421E+06 1424.577365
88 16600 1.743956E+06 1320.589413
89 16700 1.487062E+06 1219.45145
90 16800 1.255541E+06 1120.509421
91 16900 1.049216E+06 1024.312329
92 17000 8.724297E+05 934.0394267
93 17100 7.157295E+05 846.0079518
94 17200 5.750288E+05 758.3065238
95 17300 4.560588E+05 675.3212528
96 17400 3.553991E+05 596.1536111
97 17500 2.697442E+05 519.3690855
98 17600 2.005270E+05 447.8024159
99 17700 1.434300E+05 378.7215839
100 17800 9.860455E+04 314.0136092
101 17900 6.354514E+04 252.0816166
102 18000 3.898907E+04 197.456499
103 18100 2.149273E+04 146.6039915
104 18200 1.010559E+04 100.5265405
105 18300 4.910901E+03 70.07781835
106 18400 2.252190E+03 47.4572434
107 18500 1.860929E+03 43.13848425
108 18600 1.760000E+03 41.95235393

View File

@@ -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",