Refactor visualization

Replace usage of Stream:toList because of glitches in scripting
This commit is contained in:
Alexander Nozik 2022-06-07 12:44:30 +03:00
parent b911790238
commit ef670f8418
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
39 changed files with 1118 additions and 2401 deletions

1
.gitignore vendored
View File

@ -5,5 +5,6 @@ out/
.gradle .gradle
build/ build/
/notebooks/.ipynb_checkpoints /notebooks/.ipynb_checkpoints
/kotlin-js-store/
!gradle-wrapper.jar !gradle-wrapper.jar

View File

@ -1,24 +1,25 @@
plugins { plugins {
id("ru.mipt.npm.gradle.project") id("space.kscience.gradle.project")
} }
allprojects { allprojects {
repositories { repositories {
mavenLocal() mavenLocal()
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
} }
group = "ru.inr.mass" group = "ru.inr.mass"
version = "0.1.3" version = "0.1.3"
} }
val dataforgeVersion by extra("0.5.2") val dataforgeVersion by extra("0.6.0-dev-15")
val tablesVersion: String by extra("0.1.5") val tablesVersion: String by extra("0.2.0-dev-3")
val kmathVersion by extra("0.3.0") val kmathVersion by extra("0.3.1-dev-6")
val plotlyVersion: String by extra("0.5.0") val visionForgeVersion: String by rootProject.extra("0.3.0-dev-4")
ksciencePublish{ ksciencePublish{
github("numass")
space("https://maven.pkg.jetbrains.space/mipt-npm/p/numass/maven") space("https://maven.pkg.jetbrains.space/mipt-npm/p/numass/maven")
} }

View File

@ -12,4 +12,4 @@ org.gradle.configureondemand=true
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G
toolsVersion=0.11.2-kotlin-1.6.10 toolsVersion=0.13.3-kotlin-1.7.20

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
"source": [ "source": [
"@file:Repository(\"https://repo.kotlin.link\")\n", "@file:Repository(\"https://repo.kotlin.link\")\n",
"@file:Repository(\"*mavenLocal\")\n", "@file:Repository(\"*mavenLocal\")\n",
"@file:DependsOn(\"ru.inr.mass:numass-workspace:0.1.1\")" "@file:DependsOn(\"ru.inr.mass:numass-workspace:0.1.3\")"
] ]
}, },
{ {

View File

@ -1,6 +1,5 @@
plugins { plugins {
kotlin("multiplatform") id("space.kscience.gradle.mpp")
id("ru.mipt.npm.gradle.common")
`maven-publish` `maven-publish`
} }
@ -22,8 +21,8 @@ kotlin.sourceSets {
} }
} }
kscience{ //kscience{
useAtomic() // useAtomic()
} //}

View File

@ -23,10 +23,6 @@ import ru.inr.mass.data.api.NumassPoint.Companion.HV_KEY
import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.*
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import space.kscience.dataforge.values.ListValue
import space.kscience.dataforge.values.Value
import space.kscience.dataforge.values.ValueType
import space.kscience.dataforge.values.int
import space.kscience.tables.ColumnHeader import space.kscience.tables.ColumnHeader
import space.kscience.tables.MetaRow import space.kscience.tables.MetaRow
import space.kscience.tables.RowTable import space.kscience.tables.RowTable

View File

@ -31,7 +31,9 @@ import kotlin.math.*
* An analyzer which uses time information from events * An analyzer which uses time information from events
* Created by darksnake on 11.07.2017. * Created by darksnake on 11.07.2017.
*/ */
public open class TimeAnalyzer(override val extractor: NumassEventExtractor) : NumassAnalyzer() { public open class TimeAnalyzer(
override val extractor: NumassEventExtractor = NumassEventExtractor.EVENTS_ONLY,
) : NumassAnalyzer() {
override suspend fun analyzeInternal( override suspend fun analyzeInternal(
block: NumassBlock, block: NumassBlock,
@ -76,7 +78,7 @@ public open class TimeAnalyzer(override val extractor: NumassEventExtractor) : N
filter { pair -> pair.second >= t0 }.collect { pair -> filter { pair -> pair.second >= t0 }.collect { pair ->
totalN++ totalN++
//TODO add progress listener here //TODO add progress listener here
totalT+= pair.second totalT += pair.second
} }
if (totalN == 0L) { if (totalN == 0L) {
@ -114,10 +116,12 @@ public open class TimeAnalyzer(override val extractor: NumassEventExtractor) : N
sumOf { it.countRate } / size, sumOf { it.countRate } / size,
sumOf { it.countRateError.pow(2.0) } / size / size sumOf { it.countRateError.pow(2.0) } / size / size
) )
AveragingMethod.WEIGHTED -> Pair( AveragingMethod.WEIGHTED -> Pair(
sumOf { it.countRate * it.length } / totalTime, sumOf { it.countRate * it.length } / totalTime,
sumOf { (it.countRateError * it.length / totalTime).pow(2.0) } sumOf { (it.countRateError * it.length / totalTime).pow(2.0) }
) )
AveragingMethod.GEOMETRIC -> { AveragingMethod.GEOMETRIC -> {
val mean = exp(sumOf { ln(it.countRate) } / size) val mean = exp(sumOf { ln(it.countRate) } / size)
val variance = (mean / size).pow(2.0) * sumOf { val variance = (mean / size).pow(2.0) * sumOf {

View File

@ -1,6 +1,5 @@
plugins { plugins {
kotlin("multiplatform") id("space.kscience.gradle.mpp")
id("ru.mipt.npm.gradle.common")
`maven-publish` `maven-publish`
} }
@ -12,7 +11,7 @@ kotlin.sourceSets {
dependencies { dependencies {
api("space.kscience:dataforge-context:$dataforgeVersion") api("space.kscience:dataforge-context:$dataforgeVersion")
api("space.kscience:dataforge-data:$dataforgeVersion") api("space.kscience:dataforge-data:$dataforgeVersion")
api("org.jetbrains.kotlinx:kotlinx-datetime:${ru.mipt.npm.gradle.KScienceVersions.dateTimeVersion}") api("org.jetbrains.kotlinx:kotlinx-datetime:${space.kscience.gradle.KScienceVersions.dateTimeVersion}")
} }
} }
jvmMain{ jvmMain{

View File

@ -1,7 +1,6 @@
plugins { plugins {
kotlin("jvm") id("space.kscience.gradle.jvm")
id("ru.mipt.npm.gradle.common") id("com.squareup.wire") version "4.4.1"
id("com.squareup.wire") version "4.2.0"
`maven-publish` `maven-publish`
} }
@ -12,6 +11,13 @@ dependencies {
api("space.kscience:dataforge-io:$dataforgeVersion") api("space.kscience:dataforge-io:$dataforgeVersion")
} }
wire{ wire {
kotlin{} kotlin {
out = "src/gen/kotlin"
}
}
sourceSets.main {
kotlin.srcDir("src/gen/kotlin")
} }

View File

@ -0,0 +1,659 @@
// Code generated by Wire protocol buffer compiler, do not edit.
// Source: ru.inr.mass.data.proto.Point in numass-proto.proto
package ru.inr.mass.`data`.proto
import com.squareup.wire.*
import com.squareup.wire.Syntax.PROTO_3
import com.squareup.wire.internal.immutableCopyOf
import com.squareup.wire.internal.redactElements
import okio.ByteString
public class Point(
channels: List<Channel> = emptyList(),
unknownFields: ByteString = ByteString.EMPTY,
) : Message<Point, Nothing>(ADAPTER, unknownFields) {
/**
* Array of measuring channels
*/
@field:WireField(
tag = 1,
adapter = "ru.inr.mass.data.proto.Point${'$'}Channel#ADAPTER",
label = WireField.Label.REPEATED,
)
public val channels: List<Channel> = immutableCopyOf("channels", channels)
@Deprecated(
message = "Shouldn't be used in Kotlin",
level = DeprecationLevel.HIDDEN,
)
public 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")
public override fun equals(other: Any?): Boolean {
if (other === this) return true
if (other !is Point) return false
if (unknownFields != other.unknownFields) return false
if (channels != other.channels) return false
return true
}
public override fun hashCode(): Int {
var result = super.hashCode
if (result == 0) {
result = unknownFields.hashCode()
result = result * 37 + channels.hashCode()
super.hashCode = result
}
return result
}
public override fun toString(): String {
val result = mutableListOf<String>()
if (channels.isNotEmpty()) result += """channels=$channels"""
return result.joinToString(prefix = "Point{", separator = ", ", postfix = "}")
}
public fun copy(channels: List<Channel> = this.channels, unknownFields: ByteString =
this.unknownFields): Point = Point(channels, unknownFields)
public companion object {
@JvmField
public val ADAPTER: ProtoAdapter<Point> = object : ProtoAdapter<Point>(
FieldEncoding.LENGTH_DELIMITED,
Point::class,
"type.googleapis.com/ru.inr.mass.data.proto.Point",
PROTO_3,
null,
"numass-proto.proto"
) {
public override fun encodedSize(`value`: Point): Int {
var size = value.unknownFields.size
size += Channel.ADAPTER.asRepeated().encodedSizeWithTag(1, value.channels)
return size
}
public override fun encode(writer: ProtoWriter, `value`: Point): Unit {
Channel.ADAPTER.asRepeated().encodeWithTag(writer, 1, value.channels)
writer.writeBytes(value.unknownFields)
}
public override fun encode(writer: ReverseProtoWriter, `value`: Point): Unit {
writer.writeBytes(value.unknownFields)
Channel.ADAPTER.asRepeated().encodeWithTag(writer, 1, value.channels)
}
public override fun decode(reader: ProtoReader): Point {
val channels = mutableListOf<Channel>()
val unknownFields = reader.forEachTag { tag ->
when (tag) {
1 -> channels.add(Channel.ADAPTER.decode(reader))
else -> reader.readUnknownField(tag)
}
}
return Point(
channels = channels,
unknownFields = unknownFields
)
}
public override fun redact(`value`: Point): Point = value.copy(
channels = value.channels.redactElements(Channel.ADAPTER),
unknownFields = ByteString.EMPTY
)
}
private const val serialVersionUID: Long = 0L
}
/**
* A single channel for multichannel detector readout
*/
public class Channel(
/**
* The number of measuring channel
*/
@field:WireField(
tag = 1,
adapter = "com.squareup.wire.ProtoAdapter#UINT64",
label = WireField.Label.OMIT_IDENTITY,
)
public val id: Long = 0L,
blocks: List<Block> = emptyList(),
unknownFields: ByteString = ByteString.EMPTY,
) : Message<Channel, Nothing>(ADAPTER, unknownFields) {
/**
* Blocks
*/
@field:WireField(
tag = 2,
adapter = "ru.inr.mass.data.proto.Point${'$'}Channel${'$'}Block#ADAPTER",
label = WireField.Label.REPEATED,
)
public val blocks: List<Block> = immutableCopyOf("blocks", blocks)
@Deprecated(
message = "Shouldn't be used in Kotlin",
level = DeprecationLevel.HIDDEN,
)
public 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")
public override fun equals(other: Any?): Boolean {
if (other === this) return true
if (other !is Channel) return false
if (unknownFields != other.unknownFields) return false
if (id != other.id) return false
if (blocks != other.blocks) return false
return true
}
public override fun hashCode(): Int {
var result = super.hashCode
if (result == 0) {
result = unknownFields.hashCode()
result = result * 37 + id.hashCode()
result = result * 37 + blocks.hashCode()
super.hashCode = result
}
return result
}
public override fun toString(): String {
val result = mutableListOf<String>()
result += """id=$id"""
if (blocks.isNotEmpty()) result += """blocks=$blocks"""
return result.joinToString(prefix = "Channel{", separator = ", ", postfix = "}")
}
public fun copy(
id: Long = this.id,
blocks: List<Block> = this.blocks,
unknownFields: ByteString = this.unknownFields,
): Channel = Channel(id, blocks, unknownFields)
public companion object {
@JvmField
public val ADAPTER: ProtoAdapter<Channel> = object : ProtoAdapter<Channel>(
FieldEncoding.LENGTH_DELIMITED,
Channel::class,
"type.googleapis.com/ru.inr.mass.data.proto.Point.Channel",
PROTO_3,
null,
"numass-proto.proto"
) {
public override fun encodedSize(`value`: Channel): Int {
var size = value.unknownFields.size
if (value.id != 0L) size += ProtoAdapter.UINT64.encodedSizeWithTag(1, value.id)
size += Block.ADAPTER.asRepeated().encodedSizeWithTag(2, value.blocks)
return size
}
public override fun encode(writer: ProtoWriter, `value`: Channel): Unit {
if (value.id != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.id)
Block.ADAPTER.asRepeated().encodeWithTag(writer, 2, value.blocks)
writer.writeBytes(value.unknownFields)
}
public override fun encode(writer: ReverseProtoWriter, `value`: Channel): Unit {
writer.writeBytes(value.unknownFields)
Block.ADAPTER.asRepeated().encodeWithTag(writer, 2, value.blocks)
if (value.id != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.id)
}
public override fun decode(reader: ProtoReader): Channel {
var id: Long = 0L
val blocks = mutableListOf<Block>()
val unknownFields = reader.forEachTag { tag ->
when (tag) {
1 -> id = ProtoAdapter.UINT64.decode(reader)
2 -> blocks.add(Block.ADAPTER.decode(reader))
else -> reader.readUnknownField(tag)
}
}
return Channel(
id = id,
blocks = blocks,
unknownFields = unknownFields
)
}
public override fun redact(`value`: Channel): Channel = value.copy(
blocks = value.blocks.redactElements(Block.ADAPTER),
unknownFields = ByteString.EMPTY
)
}
private const val serialVersionUID: Long = 0L
}
/**
* A continuous measurement block
*/
public class Block(
/**
* Block start in epoch nanos
*/
@field:WireField(
tag = 1,
adapter = "com.squareup.wire.ProtoAdapter#UINT64",
label = WireField.Label.OMIT_IDENTITY,
)
public val time: Long = 0L,
frames: List<Frame> = emptyList(),
/**
* Events array
*/
@field:WireField(
tag = 3,
adapter = "ru.inr.mass.data.proto.Point${'$'}Channel${'$'}Block${'$'}Events#ADAPTER",
label = WireField.Label.OMIT_IDENTITY,
)
public val events: Events? = null,
/**
* block size in nanos. If missing, take from meta.
*/
@field:WireField(
tag = 4,
adapter = "com.squareup.wire.ProtoAdapter#UINT64",
label = WireField.Label.OMIT_IDENTITY,
)
public val length: Long = 0L,
/**
* tick size in nanos. Obsolete, to be removed
*/
@field:WireField(
tag = 5,
adapter = "com.squareup.wire.ProtoAdapter#UINT64",
label = WireField.Label.OMIT_IDENTITY,
jsonName = "binSize",
)
public val bin_size: Long = 0L,
unknownFields: ByteString = ByteString.EMPTY,
) : Message<Block, Nothing>(ADAPTER, unknownFields) {
/**
* Frames array
*/
@field:WireField(
tag = 2,
adapter = "ru.inr.mass.data.proto.Point${'$'}Channel${'$'}Block${'$'}Frame#ADAPTER",
label = WireField.Label.REPEATED,
)
public val frames: List<Frame> = immutableCopyOf("frames", frames)
@Deprecated(
message = "Shouldn't be used in Kotlin",
level = DeprecationLevel.HIDDEN,
)
public 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")
public override fun equals(other: Any?): Boolean {
if (other === this) return true
if (other !is Block) return false
if (unknownFields != other.unknownFields) return false
if (time != other.time) return false
if (frames != other.frames) return false
if (events != other.events) return false
if (length != other.length) return false
if (bin_size != other.bin_size) return false
return true
}
public override fun hashCode(): Int {
var result = super.hashCode
if (result == 0) {
result = unknownFields.hashCode()
result = result * 37 + time.hashCode()
result = result * 37 + frames.hashCode()
result = result * 37 + (events?.hashCode() ?: 0)
result = result * 37 + length.hashCode()
result = result * 37 + bin_size.hashCode()
super.hashCode = result
}
return result
}
public override fun toString(): String {
val result = mutableListOf<String>()
result += """time=$time"""
if (frames.isNotEmpty()) result += """frames=$frames"""
if (events != null) result += """events=$events"""
result += """length=$length"""
result += """bin_size=$bin_size"""
return result.joinToString(prefix = "Block{", separator = ", ", postfix = "}")
}
public fun copy(
time: Long = this.time,
frames: List<Frame> = this.frames,
events: Events? = this.events,
length: Long = this.length,
bin_size: Long = this.bin_size,
unknownFields: ByteString = this.unknownFields,
): Block = Block(time, frames, events, length, bin_size, unknownFields)
public companion object {
@JvmField
public val ADAPTER: ProtoAdapter<Block> = object : ProtoAdapter<Block>(
FieldEncoding.LENGTH_DELIMITED,
Block::class,
"type.googleapis.com/ru.inr.mass.data.proto.Point.Channel.Block",
PROTO_3,
null,
"numass-proto.proto"
) {
public override fun encodedSize(`value`: Block): Int {
var size = value.unknownFields.size
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)
return size
}
public override fun encode(writer: ProtoWriter, `value`: Block): Unit {
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)
writer.writeBytes(value.unknownFields)
}
public override fun encode(writer: ReverseProtoWriter, `value`: Block): Unit {
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)
Frame.ADAPTER.asRepeated().encodeWithTag(writer, 2, value.frames)
if (value.time != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
}
public override fun decode(reader: ProtoReader): Block {
var time: Long = 0L
val frames = mutableListOf<Frame>()
var events: Events? = null
var length: Long = 0L
var bin_size: Long = 0L
val unknownFields = reader.forEachTag { tag ->
when (tag) {
1 -> time = ProtoAdapter.UINT64.decode(reader)
2 -> frames.add(Frame.ADAPTER.decode(reader))
3 -> events = Events.ADAPTER.decode(reader)
4 -> length = ProtoAdapter.UINT64.decode(reader)
5 -> bin_size = ProtoAdapter.UINT64.decode(reader)
else -> reader.readUnknownField(tag)
}
}
return Block(
time = time,
frames = frames,
events = events,
length = length,
bin_size = bin_size,
unknownFields = unknownFields
)
}
public override fun redact(`value`: Block): Block = value.copy(
frames = value.frames.redactElements(Frame.ADAPTER),
events = value.events?.let(Events.ADAPTER::redact),
unknownFields = ByteString.EMPTY
)
}
private const val serialVersionUID: Long = 0L
}
/**
* Raw data frame
*/
public class Frame(
/**
* Time in nanos from the beginning of the block
*/
@field:WireField(
tag = 1,
adapter = "com.squareup.wire.ProtoAdapter#UINT64",
label = WireField.Label.OMIT_IDENTITY,
)
public val time: Long = 0L,
/**
* Frame data as an array of int16 measured in arbitrary channels
*/
@field:WireField(
tag = 2,
adapter = "com.squareup.wire.ProtoAdapter#BYTES",
label = WireField.Label.OMIT_IDENTITY,
declaredName = "data",
)
public val data_: ByteString = ByteString.EMPTY,
unknownFields: ByteString = ByteString.EMPTY,
) : Message<Frame, Nothing>(ADAPTER, unknownFields) {
@Deprecated(
message = "Shouldn't be used in Kotlin",
level = DeprecationLevel.HIDDEN,
)
public 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")
public override fun equals(other: Any?): Boolean {
if (other === this) return true
if (other !is Frame) return false
if (unknownFields != other.unknownFields) return false
if (time != other.time) return false
if (data_ != other.data_) return false
return true
}
public override fun hashCode(): Int {
var result = super.hashCode
if (result == 0) {
result = unknownFields.hashCode()
result = result * 37 + time.hashCode()
result = result * 37 + data_.hashCode()
super.hashCode = result
}
return result
}
public override fun toString(): String {
val result = mutableListOf<String>()
result += """time=$time"""
result += """data_=$data_"""
return result.joinToString(prefix = "Frame{", separator = ", ", postfix = "}")
}
public fun copy(
time: Long = this.time,
data_: ByteString = this.data_,
unknownFields: ByteString = this.unknownFields,
): Frame = Frame(time, data_, unknownFields)
public companion object {
@JvmField
public val ADAPTER: ProtoAdapter<Frame> = object : ProtoAdapter<Frame>(
FieldEncoding.LENGTH_DELIMITED,
Frame::class,
"type.googleapis.com/ru.inr.mass.data.proto.Point.Channel.Block.Frame",
PROTO_3,
null,
"numass-proto.proto"
) {
public 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_)
return size
}
public override fun encode(writer: ProtoWriter, `value`: Frame): Unit {
if (value.time != 0L) ProtoAdapter.UINT64.encodeWithTag(writer, 1, value.time)
if (value.data_ != ByteString.EMPTY) ProtoAdapter.BYTES.encodeWithTag(writer, 2,
value.data_)
writer.writeBytes(value.unknownFields)
}
public override fun encode(writer: ReverseProtoWriter, `value`: Frame): Unit {
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)
}
public override fun decode(reader: ProtoReader): Frame {
var time: Long = 0L
var data_: ByteString = ByteString.EMPTY
val unknownFields = reader.forEachTag { tag ->
when (tag) {
1 -> time = ProtoAdapter.UINT64.decode(reader)
2 -> data_ = ProtoAdapter.BYTES.decode(reader)
else -> reader.readUnknownField(tag)
}
}
return Frame(
time = time,
data_ = data_,
unknownFields = unknownFields
)
}
public override fun redact(`value`: Frame): Frame = value.copy(
unknownFields = ByteString.EMPTY
)
}
private const val serialVersionUID: Long = 0L
}
}
/**
* Event block obtained directly from device of from frame analysis
* In order to save space, times and amplitudes are in separate arrays.
* Amplitude and time with the same index correspond to the same event
*/
public class Events(
times: List<Long> = emptyList(),
amplitudes: List<Long> = emptyList(),
unknownFields: ByteString = ByteString.EMPTY,
) : Message<Events, Nothing>(ADAPTER, unknownFields) {
/**
* Array of time in nanos from the beginning of the block
*/
@field:WireField(
tag = 1,
adapter = "com.squareup.wire.ProtoAdapter#UINT64",
label = WireField.Label.PACKED,
)
public val times: List<Long> = immutableCopyOf("times", times)
/**
* Array of amplitudes of events in channels
*/
@field:WireField(
tag = 2,
adapter = "com.squareup.wire.ProtoAdapter#UINT64",
label = WireField.Label.PACKED,
)
public val amplitudes: List<Long> = immutableCopyOf("amplitudes", amplitudes)
@Deprecated(
message = "Shouldn't be used in Kotlin",
level = DeprecationLevel.HIDDEN,
)
public 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")
public override fun equals(other: Any?): Boolean {
if (other === this) return true
if (other !is Events) return false
if (unknownFields != other.unknownFields) return false
if (times != other.times) return false
if (amplitudes != other.amplitudes) return false
return true
}
public override fun hashCode(): Int {
var result = super.hashCode
if (result == 0) {
result = unknownFields.hashCode()
result = result * 37 + times.hashCode()
result = result * 37 + amplitudes.hashCode()
super.hashCode = result
}
return result
}
public override fun toString(): String {
val result = mutableListOf<String>()
if (times.isNotEmpty()) result += """times=$times"""
if (amplitudes.isNotEmpty()) result += """amplitudes=$amplitudes"""
return result.joinToString(prefix = "Events{", separator = ", ", postfix = "}")
}
public fun copy(
times: List<Long> = this.times,
amplitudes: List<Long> = this.amplitudes,
unknownFields: ByteString = this.unknownFields,
): Events = Events(times, amplitudes, unknownFields)
public companion object {
@JvmField
public val ADAPTER: ProtoAdapter<Events> = object : ProtoAdapter<Events>(
FieldEncoding.LENGTH_DELIMITED,
Events::class,
"type.googleapis.com/ru.inr.mass.data.proto.Point.Channel.Block.Events",
PROTO_3,
null,
"numass-proto.proto"
) {
public override fun encodedSize(`value`: Events): Int {
var size = value.unknownFields.size
size += ProtoAdapter.UINT64.asPacked().encodedSizeWithTag(1, value.times)
size += ProtoAdapter.UINT64.asPacked().encodedSizeWithTag(2, value.amplitudes)
return size
}
public override fun encode(writer: ProtoWriter, `value`: Events): Unit {
ProtoAdapter.UINT64.asPacked().encodeWithTag(writer, 1, value.times)
ProtoAdapter.UINT64.asPacked().encodeWithTag(writer, 2, value.amplitudes)
writer.writeBytes(value.unknownFields)
}
public override fun encode(writer: ReverseProtoWriter, `value`: Events): Unit {
writer.writeBytes(value.unknownFields)
ProtoAdapter.UINT64.asPacked().encodeWithTag(writer, 2, value.amplitudes)
ProtoAdapter.UINT64.asPacked().encodeWithTag(writer, 1, value.times)
}
public override fun decode(reader: ProtoReader): Events {
val times = mutableListOf<Long>()
val amplitudes = mutableListOf<Long>()
val unknownFields = reader.forEachTag { tag ->
when (tag) {
1 -> times.add(ProtoAdapter.UINT64.decode(reader))
2 -> amplitudes.add(ProtoAdapter.UINT64.decode(reader))
else -> reader.readUnknownField(tag)
}
}
return Events(
times = times,
amplitudes = amplitudes,
unknownFields = unknownFields
)
}
public override fun redact(`value`: Events): Events = value.copy(
unknownFields = ByteString.EMPTY
)
}
private const val serialVersionUID: Long = 0L
}
}
}
}
}

View File

@ -4,10 +4,7 @@ import ru.inr.mass.data.api.NumassPoint
import ru.inr.mass.data.api.NumassSet import ru.inr.mass.data.api.NumassSet
import ru.inr.mass.data.api.NumassSet.Companion.NUMASS_HV_TARGET import ru.inr.mass.data.api.NumassSet.Companion.NUMASS_HV_TARGET
import ru.inr.mass.data.api.readEnvelope import ru.inr.mass.data.api.readEnvelope
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.*
import space.kscience.dataforge.context.error
import space.kscience.dataforge.context.logger
import space.kscience.dataforge.context.warn
import space.kscience.dataforge.io.io import space.kscience.dataforge.io.io
import space.kscience.dataforge.io.readEnvelopeFile import space.kscience.dataforge.io.readEnvelopeFile
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
@ -16,14 +13,16 @@ import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.util.stream.Collectors
import kotlin.io.path.* import kotlin.io.path.*
import kotlin.streams.toList
@OptIn(ExperimentalPathApi::class)
public class NumassDirectorySet internal constructor( public class NumassDirectorySet internal constructor(
public val context: Context, public val numassProto: NumassProtoPlugin,
public val path: Path, public val path: Path,
) : NumassSet { ) : NumassSet, ContextAware {
override val context: Context
get() = numassProto.context
@OptIn(DFExperimental::class) @OptIn(DFExperimental::class)
override val meta: Meta override val meta: Meta
@ -43,12 +42,12 @@ public class NumassDirectorySet internal constructor(
it.fileName.name.startsWith("p") it.fileName.name.startsWith("p")
}.map { pointPath -> }.map { pointPath ->
try { try {
context.readNumassPointFile(pointPath) numassProto.readNumassPointFile(pointPath)
} catch (e: Exception) { } catch (e: Exception) {
context.logger.error(e) { "Error reading Numass point file $pointPath" } context.logger.error(e) { "Error reading Numass point file $pointPath" }
null null
} }
}.toList().filterNotNull() }.collect(Collectors.toList()).filterNotNull()
@OptIn(DFExperimental::class) @OptIn(DFExperimental::class)
@ -73,20 +72,3 @@ public class NumassDirectorySet internal constructor(
public companion object public companion object
} }
@OptIn(DFExperimental::class)
public fun Context.readNumassPointFile(path: Path): NumassPoint? {
val envelope = io.readEnvelopeFile(path)
return ProtoNumassPoint.fromEnvelope(envelope)
}
public fun Context.readNumassPointFile(path: String): NumassPoint? = readNumassPointFile(Path.of(path))
@OptIn(ExperimentalPathApi::class)
public fun Context.readNumassDirectory(path: Path): NumassDirectorySet {
if (!path.exists()) error("Path $path does not exist")
if (!path.isDirectory()) error("The path $path is not a directory")
return NumassDirectorySet(this, path)
}
public fun Context.readNumassDirectory(path: String): NumassDirectorySet = readNumassDirectory(Path.of(path))

View File

@ -1,28 +1,77 @@
package ru.inr.mass.data.proto package ru.inr.mass.data.proto
import kotlinx.coroutines.launch
import ru.inr.mass.data.api.NumassPoint
import space.kscience.dataforge.context.AbstractPlugin import space.kscience.dataforge.context.AbstractPlugin
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.data.DataSource
import space.kscience.dataforge.data.DataTree
import space.kscience.dataforge.data.static
import space.kscience.dataforge.io.EnvelopeFormatFactory import space.kscience.dataforge.io.EnvelopeFormatFactory
import space.kscience.dataforge.io.IOPlugin import space.kscience.dataforge.io.IOPlugin
import space.kscience.dataforge.io.readEnvelopeFile
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.NameToken
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.exists
import kotlin.io.path.isDirectory
import kotlin.io.path.relativeTo
import kotlin.reflect.KClass import kotlin.reflect.KClass
public class NumassProtoPlugin : AbstractPlugin() { public class NumassProtoPlugin : AbstractPlugin() {
public val io: IOPlugin by require(IOPlugin) public val io: IOPlugin by require(IOPlugin)
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
override fun content(target: String): Map<Name, Any> = if(target == EnvelopeFormatFactory.ENVELOPE_FORMAT_TYPE){ override fun content(target: String): Map<Name, Any> = if (target == EnvelopeFormatFactory.ENVELOPE_FORMAT_TYPE) {
mapOf(TaggedNumassEnvelopeFormat.name to TaggedNumassEnvelopeFormat) mapOf(TaggedNumassEnvelopeFormat.name to TaggedNumassEnvelopeFormat)
} else{ } else {
super.content(target) super.content(target)
} }
public companion object : PluginFactory<NumassProtoPlugin> { public companion object : PluginFactory<NumassProtoPlugin> {
override fun invoke(meta: Meta, context: Context): NumassProtoPlugin = NumassProtoPlugin() override fun build(context: Context, meta: Meta): NumassProtoPlugin = NumassProtoPlugin()
override val tag: PluginTag = PluginTag("numass-proto", group = "ru.inr.mass") override val tag: PluginTag = PluginTag("numass-proto", group = "ru.inr.mass")
override val type: KClass<out NumassProtoPlugin> = NumassProtoPlugin::class override val type: KClass<out NumassProtoPlugin> = NumassProtoPlugin::class
} }
} }
@OptIn(DFExperimental::class)
public fun NumassProtoPlugin.readNumassPointFile(path: Path): NumassPoint? {
val envelope = io.readEnvelopeFile(path)
return ProtoNumassPoint.fromEnvelope(envelope)
}
public fun NumassProtoPlugin.readNumassPointFile(path: String): NumassPoint? = readNumassPointFile(Path.of(path))
public fun NumassProtoPlugin.readNumassDirectory(path: Path): NumassDirectorySet {
if (!path.exists()) error("Path $path does not exist")
if (!path.isDirectory()) error("The path $path is not a directory")
return NumassDirectorySet(this, path)
}
public fun NumassProtoPlugin.readNumassDirectory(path: String): NumassDirectorySet = readNumassDirectory(Path.of(path))
public suspend fun NumassProtoPlugin.readRepository(path: Path): DataTree<NumassDirectorySet> = DataSource {
Files.walk(path).filter {
it.isDirectory() && it.resolve("meta").exists()
}.forEach { childPath ->
val name = Name(childPath.relativeTo(path).map { segment ->
NameToken(segment.fileName.toString())
})
val value = readNumassDirectory(childPath)
launch {
static(name, value, value.meta)
}
}
//TODO add file watcher
}
public suspend fun NumassProtoPlugin.readRepository(path: String): DataTree<NumassDirectorySet> = readRepository(Path.of(path))
public fun NumassProtoPlugin.readPoint(path: String): NumassPoint = readNumassPointFile(path)
?: error("Can't read numass point at $path")

View File

@ -31,9 +31,6 @@ import ru.inr.mass.data.api.NumassFrame
import ru.inr.mass.data.api.NumassPoint import ru.inr.mass.data.api.NumassPoint
import space.kscience.dataforge.io.Envelope import space.kscience.dataforge.io.Envelope
import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.*
import space.kscience.dataforge.values.ValueType
import space.kscience.dataforge.values.long
import space.kscience.dataforge.values.string
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.InputStream import java.io.InputStream
@ -87,9 +84,10 @@ internal class ProtoNumassPoint(
override val startTime: Instant override val startTime: Instant
get() { get() {
val startTimeValue = meta["start_time"]?.value val startTimeValue = meta["start_time"]?.value
return when{ return when {
startTimeValue == null -> Instant.DISTANT_PAST startTimeValue == null -> Instant.DISTANT_PAST
startTimeValue.type == ValueType.STRING -> LocalDateTime.parse(startTimeValue.string).toInstant(TimeZone.UTC) startTimeValue.type == ValueType.STRING -> LocalDateTime.parse(startTimeValue.string)
.toInstant(TimeZone.UTC)
//TODO fix time zones!!! //TODO fix time zones!!!
startTimeValue.type == ValueType.NUMBER -> Instant.fromEpochMilliseconds(startTimeValue.long) startTimeValue.type == ValueType.NUMBER -> Instant.fromEpochMilliseconds(startTimeValue.long)
else -> error("Can't decode start time") else -> error("Can't decode start time")
@ -116,7 +114,7 @@ internal class ProtoNumassPoint(
override fun toString(): String = "ProtoNumassPoint(index = ${index}, hv = $voltage)" override fun toString(): String = "ProtoNumassPoint(index = ${index}, hv = $voltage)"
public companion object { companion object {
/** /**
* Get valid data stream utilizing compression if it is present * Get valid data stream utilizing compression if it is present
@ -142,6 +140,7 @@ internal class ProtoNumassPoint(
inflater.end() inflater.end()
ByteArrayInputStream(unzippeddata).use(block) ByteArrayInputStream(unzippeddata).use(block)
} }
else -> { else -> {
data?.read { data?.read {
block(asInputStream()) block(asInputStream())
@ -149,7 +148,7 @@ internal class ProtoNumassPoint(
} }
} }
public fun fromEnvelope(envelope: Envelope): ProtoNumassPoint? { fun fromEnvelope(envelope: Envelope): ProtoNumassPoint? {
if (envelope.data == null) return null if (envelope.data == null) return null
return ProtoNumassPoint(envelope.meta) { return ProtoNumassPoint(envelope.meta) {
envelope.useData { envelope.useData {
@ -180,6 +179,7 @@ public class ProtoNumassBlock(
block.length > 0 -> block.length.nanoseconds block.length > 0 -> block.length.nanoseconds
parent?.meta?.get("acquisition_time") != null -> parent?.meta?.get("acquisition_time") != null ->
(parent.meta["acquisition_time"].double ?: (0.0 * 1000)).milliseconds (parent.meta["acquisition_time"].double ?: (0.0 * 1000)).milliseconds
else -> { else -> {
LoggerFactory.getLogger(javaClass) LoggerFactory.getLogger(javaClass)
.error("No length information on block. Trying to infer from first and last events") .error("No length information on block. Trying to infer from first and last events")
@ -221,7 +221,8 @@ public class ProtoNumassBlock(
} else { } else {
ShortArray(shortBuffer.limit()) { shortBuffer.get(it) } ShortArray(shortBuffer.limit()) { shortBuffer.get(it) }
} }
FrameType.TQDC2021 -> ShortArray(shortBuffer.limit()){
FrameType.TQDC2021 -> ShortArray(shortBuffer.limit()) {
(shortBuffer.get(it).toUShort().toInt() - Short.MAX_VALUE).toShort() (shortBuffer.get(it).toUShort().toInt() - Short.MAX_VALUE).toShort()
} }
} }

View File

@ -18,18 +18,19 @@ package ru.inr.mass.data.proto
import io.ktor.utils.io.core.* import io.ktor.utils.io.core.*
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.invoke
import space.kscience.dataforge.io.* import space.kscience.dataforge.io.*
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.string import space.kscience.dataforge.meta.string
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.parseAsName
import java.util.* import java.util.*
public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeFormat { public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeFormat {
private fun Tag.toBinary() = Binary(24) { private fun Tag.toBinary() = Binary {
writeRawString(START_SEQUENCE) writeRawString(START_SEQUENCE)
writeRawString("DFNU") writeRawString("DFNU")
writeShort(metaFormatKey) writeShort(metaFormatKey)
@ -70,7 +71,7 @@ public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeForm
val metaFormat = io.resolveMetaFormat(tag.metaFormatKey) val metaFormat = io.resolveMetaFormat(tag.metaFormatKey)
?: error("Meta format with key ${tag.metaFormatKey} not found") ?: error("Meta format with key ${tag.metaFormatKey} not found")
val meta: Meta = metaFormat.readObject(input.readBinary(tag.metaSize.toInt())) val meta: Meta = metaFormat.readObjectFrom(input.readBinary(tag.metaSize.toInt()))
val data = input.readBinary(tag.dataSize.toInt()) val data = input.readBinary(tag.dataSize.toInt())
@ -87,10 +88,10 @@ public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeForm
?: error("Meta format with key ${tag.metaFormatKey} not found") ?: error("Meta format with key ${tag.metaFormatKey} not found")
} }
val meta: Meta = metaFormat.readObject(input.readBinary(tag.metaSize.toInt())) val meta: Meta = metaFormat.readObjectFrom(input.readBinary(tag.metaSize.toInt()))
return PartialEnvelope(meta, 30u + tag.metaSize, tag.dataSize) return PartialEnvelope(meta, 30 + tag.metaSize.toInt(), tag.dataSize)
} }
private data class Tag( private data class Tag(
@ -99,17 +100,17 @@ public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeForm
val dataSize: ULong, val dataSize: ULong,
) )
override fun toMeta(): Meta = Meta { // override fun toMeta(): Meta = Meta {
IOFormat.NAME_KEY put name.toString() // NAME_KEY put name.toString()
} // }
public companion object : EnvelopeFormatFactory { public companion object : EnvelopeFormatFactory {
private const val START_SEQUENCE = "#!" private const val START_SEQUENCE = "#!"
private const val END_SEQUENCE = "!#\r\n" private const val END_SEQUENCE = "!#\r\n"
override val name: Name = super.name + "numass" override val name: Name = "envelope.numass".parseAsName()
override fun invoke(meta: Meta, context: Context): EnvelopeFormat { override fun build(context: Context, meta: Meta): EnvelopeFormat {
val io = context.io val io = context.io
val metaFormatName = meta["name"].string?.let { Name.parse(it) } ?: JsonMetaFormat.name val metaFormatName = meta["name"].string?.let { Name.parse(it) } ?: JsonMetaFormat.name

View File

@ -6,9 +6,10 @@ import ru.inr.mass.data.api.NumassSet
import ru.inr.mass.data.api.ParentBlock import ru.inr.mass.data.api.ParentBlock
import ru.inr.mass.data.api.channels import ru.inr.mass.data.api.channels
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.fetch
import space.kscience.dataforge.meta.ListValue
import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.string import space.kscience.dataforge.meta.string
import space.kscience.dataforge.values.ListValue
import java.nio.file.Path import java.nio.file.Path
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -16,11 +17,12 @@ class TestNumassDirectory {
val context = Context("numass-test") { val context = Context("numass-test") {
plugin(NumassProtoPlugin) plugin(NumassProtoPlugin)
} }
val numassProto = context.fetch(NumassProtoPlugin)
@Test @Test
fun testDanteRead() { fun testDanteRead() {
val dataPath = Path.of("src/test/resources", "testData/dante") val dataPath = Path.of("src/test/resources", "testData/dante")
val testSet = context.readNumassDirectory(dataPath) val testSet = numassProto.readNumassDirectory(dataPath)
assertEquals("2018-04-13T22:01:46", testSet.meta["end_time"].string) assertEquals("2018-04-13T22:01:46", testSet.meta["end_time"].string)
assertEquals(ListValue.EMPTY, testSet.meta["comments"]?.value) assertEquals(ListValue.EMPTY, testSet.meta["comments"]?.value)
assertEquals(31, testSet.points.size) assertEquals(31, testSet.points.size)
@ -32,12 +34,12 @@ class TestNumassDirectory {
@Test @Test
fun testTQDCRead() = runBlocking { fun testTQDCRead() = runBlocking {
val pointPath = Path.of("src/test/resources", "testData/tqdc") val pointPath = Path.of("src/test/resources", "testData/tqdc")
val set: NumassSet = context.readNumassDirectory(pointPath) val set: NumassSet = numassProto.readNumassDirectory(pointPath)
val point = set.first { it.voltage == 18200.0 } val point = set.first { it.voltage == 18200.0 }
point.channels.forEach { (channel, block) -> point.channels.forEach { (channel, block) ->
println("$channel: $block") println("$channel: $block")
if(block is ParentBlock){ if (block is ParentBlock) {
block.blocks.toList().forEach{ block.blocks.toList().forEach {
println("\t${it.channel}:${it.eventsCount}") println("\t${it.channel}:${it.eventsCount}")
} }
} }

View File

@ -1,13 +1,14 @@
plugins { plugins {
kotlin("multiplatform") id("space.kscience.gradle.mpp")
id("ru.mipt.npm.gradle.common")
`maven-publish` `maven-publish`
} }
val visionForgeVersion = "0.2.0-dev-24" val visionForgeVersion: String by rootProject.extra
val production: Boolean by rootProject.extra(false)
kotlin { kotlin {
js{ js(IR) {
browser { browser {
webpackTask { webpackTask {
this.outputFileName = "js/numass-web.js" this.outputFileName = "js/numass-web.js"
@ -16,17 +17,6 @@ kotlin {
binaries.executable() binaries.executable()
} }
afterEvaluate {
val jsBrowserDistribution by tasks.getting
tasks.getByName<ProcessResources>("jvmProcessResources") {
dependsOn(jsBrowserDistribution)
afterEvaluate {
from(jsBrowserDistribution)
}
}
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
@ -44,8 +34,26 @@ kotlin {
} }
} }
kscience{ afterEvaluate {
val distributionTask = if (production) {
tasks.getByName("jsBrowserDistribution")
} else {
tasks.getByName("jsBrowserDevelopmentExecutableDistribution")
}
tasks.getByName<ProcessResources>("jvmProcessResources") {
dependsOn(distributionTask)
from(distributionTask)
include("**/*.js")
if (production) {
include("**/*.map")
}
}
}
kscience {
useSerialization { useSerialization {
json() json()
} }
withContextReceivers()
} }

View File

@ -8,28 +8,22 @@ import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionBase
import space.kscience.visionforge.VisionGroupBase
import space.kscience.visionforge.VisionPlugin import space.kscience.visionforge.VisionPlugin
import space.kscience.visionforge.plotly.PlotlyPlugin
import kotlin.reflect.KClass import kotlin.reflect.KClass
public class NumassCommonPlugin(meta: Meta) : VisionPlugin(meta) { public class NumassCommonPlugin(meta: Meta = Meta.EMPTY) : VisionPlugin(meta) {
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
public val plotlyPlugin: PlotlyPlugin by require(PlotlyPlugin)
override val visionSerializersModule: SerializersModule get() = numassSerializersModule override val visionSerializersModule: SerializersModule get() = numassSerializersModule
public companion object : PluginFactory<NumassCommonPlugin> { public companion object : PluginFactory<NumassCommonPlugin> {
override val tag: PluginTag = PluginTag("numass.common", "ru.inr.mass") override val tag: PluginTag = PluginTag("numass.common", "ru.inr.mass")
override val type: KClass<NumassCommonPlugin> = NumassCommonPlugin::class override val type: KClass<NumassCommonPlugin> = NumassCommonPlugin::class
override fun invoke(meta: Meta, context: Context): NumassCommonPlugin = NumassCommonPlugin()
private val numassSerializersModule = SerializersModule { override fun build(context: Context, meta: Meta): NumassCommonPlugin = NumassCommonPlugin()
internal val numassSerializersModule = SerializersModule {
polymorphic(Vision::class) { polymorphic(Vision::class) {
subclass(VisionBase.serializer())
subclass(VisionGroupBase.serializer())
subclass(VisionOfNumassHv.serializer()) subclass(VisionOfNumassHv.serializer())
subclass(VisionOfNumassPoint.serializer()) subclass(VisionOfNumassPoint.serializer())
subclass(VisionOfNumassHv.serializer()) subclass(VisionOfNumassHv.serializer())

View File

@ -1,24 +1,23 @@
package ru.inr.mass.data.server package ru.inr.mass.data.server
import kotlinx.coroutines.flow.collect
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import ru.inr.mass.data.api.NumassBlock import ru.inr.mass.data.api.NumassBlock
import ru.inr.mass.data.api.NumassPoint import ru.inr.mass.data.api.NumassPoint
import ru.inr.mass.data.api.NumassSet import ru.inr.mass.data.api.NumassSet
import ru.inr.mass.data.api.NumassSet.Companion.NUMASS_HV_TARGET import ru.inr.mass.data.api.NumassSet.Companion.NUMASS_HV_TARGET
import ru.inr.mass.data.api.channels
import ru.inr.mass.data.proto.HVData import ru.inr.mass.data.proto.HVData
import ru.inr.mass.data.proto.HVEntry import ru.inr.mass.data.proto.HVEntry
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.NameToken
import space.kscience.dataforge.provider.top import space.kscience.dataforge.provider.top
import space.kscience.visionforge.VisionBase import space.kscience.visionforge.AbstractVision
import space.kscience.visionforge.VisionGroupBase
public typealias SimpleAmplitudeSpectrum = Map<UShort, UInt> public typealias SimpleAmplitudeSpectrum = Map<Short, UInt>
private suspend fun NumassBlock.simpleAmplitudeSpectrum(): SimpleAmplitudeSpectrum { internal suspend fun NumassBlock.simpleAmplitudeSpectrum(): SimpleAmplitudeSpectrum {
val res = mutableMapOf<UShort, UInt>() val res = mutableMapOf<Short, UInt>()
events.collect { events.collect {
res[it.amplitude] = (res[it.amplitude] ?: 0U) + 1U res[it.amplitude] = (res[it.amplitude] ?: 0U) + 1U
} }
@ -31,26 +30,26 @@ public class VisionOfNumassPoint(
public val index: Int, public val index: Int,
public val voltage: Double, public val voltage: Double,
public val spectra: Map<String, SimpleAmplitudeSpectrum>, public val spectra: Map<String, SimpleAmplitudeSpectrum>,
) : VisionBase() ) : AbstractVision()
public suspend fun NumassPoint.toVision(): VisionOfNumassPoint = VisionOfNumassPoint( public suspend fun NumassPoint.toVision(): VisionOfNumassPoint = VisionOfNumassPoint(
meta, meta,
index, index,
voltage, voltage,
getChannels().entries.associate { (k, v) -> channels.entries.associate { (k, v) ->
k.toString() to v.simpleAmplitudeSpectrum() k.toString() to v.simpleAmplitudeSpectrum()
} }
) )
@Serializable @Serializable
public class VisionOfNumassHv(public val hv: HVData) : VisionBase(), Iterable<HVEntry> { public class VisionOfNumassHv(public val hv: HVData) : AbstractVision(), Iterable<HVEntry> {
override fun iterator(): Iterator<HVEntry> = hv.iterator() override fun iterator(): Iterator<HVEntry> = hv.iterator()
} }
private val VisionOfNumassPoint.token: NameToken get() = NameToken("point", index.toString()) private val VisionOfNumassPoint.token: NameToken get() = NameToken("point", index.toString())
@Serializable @Serializable
public class VisionOfNumassSet(public val points: List<VisionOfNumassPoint>) : VisionBase() { public class VisionOfNumassSet(public val points: List<VisionOfNumassPoint>) : AbstractVision() {
// init { // init {
// points.forEach { // points.forEach {
// //childrenInternal[it.token] = it // //childrenInternal[it.token] = it

View File

@ -8,17 +8,22 @@ import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import space.kscience.plotly.models.LineShape import space.kscience.plotly.models.LineShape
import space.kscience.plotly.models.ScatterMode import space.kscience.plotly.models.ScatterMode
import space.kscience.plotly.plot import space.kscience.plotly.plotElement
import space.kscience.plotly.scatter import space.kscience.plotly.scatter
import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.ElementVisionRenderer
import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionClient
import space.kscience.visionforge.plotly.PlotlyPlugin
import kotlin.reflect.KClass import kotlin.reflect.KClass
public class NumassJsPlugin : AbstractPlugin(), ElementVisionRenderer { public class NumassJsPlugin : AbstractPlugin(), ElementVisionRenderer {
public val client: VisionClient by require(VisionClient)
public val numassCommon: NumassCommonPlugin by require(NumassCommonPlugin) public val numassCommon: NumassCommonPlugin by require(NumassCommonPlugin)
private val plotly = numassCommon.plotlyPlugin public val plotly: PlotlyPlugin by require(PlotlyPlugin)
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
@ -27,6 +32,11 @@ public class NumassJsPlugin : AbstractPlugin(), ElementVisionRenderer {
else -> ElementVisionRenderer.ZERO_RATING else -> ElementVisionRenderer.ZERO_RATING
} }
override fun content(target: String): Map<Name, Any> = when (target) {
ElementVisionRenderer.TYPE -> mapOf("numass".asName() to this)
else -> super.content(target)
}
override fun render(element: Element, vision: Vision, meta: Meta) { override fun render(element: Element, vision: Vision, meta: Meta) {
when (vision) { when (vision) {
is VisionOfNumassHv -> element.append { is VisionOfNumassHv -> element.append {
@ -47,22 +57,25 @@ public class NumassJsPlugin : AbstractPlugin(), ElementVisionRenderer {
} }
} }
} }
is VisionOfNumassPoint -> element.append { is VisionOfNumassPoint -> element.append {
h1{ +"Point"} h1 { +"Point" }
plot { plotElement {
vision.spectra.forEach { (channel, spectrum) -> vision.spectra.forEach { (channel, spectrum) ->
val pairs = spectrum.entries.sortedBy { it.key }
scatter { scatter {
name = channel name = channel
mode = ScatterMode.lines mode = ScatterMode.lines
line { line {
shape = LineShape.hv shape = LineShape.hv
} }
x.numbers = spectrum.keys.map { it.toInt() } x.numbers = pairs.map { it.key.toInt() }
y.numbers = spectrum.values.map { it.toInt() } y.numbers = pairs.map { it.value.toInt() }
} }
} }
} }
} }
is VisionOfNumassSet -> {} is VisionOfNumassSet -> {}
} }
} }
@ -71,6 +84,8 @@ public class NumassJsPlugin : AbstractPlugin(), ElementVisionRenderer {
public companion object : PluginFactory<NumassJsPlugin> { public companion object : PluginFactory<NumassJsPlugin> {
override val tag: PluginTag = PluginTag("numass.js", "ru.inr.mass") override val tag: PluginTag = PluginTag("numass.js", "ru.inr.mass")
override val type: KClass<NumassJsPlugin> = NumassJsPlugin::class override val type: KClass<NumassJsPlugin> = NumassJsPlugin::class
override fun invoke(meta: Meta, context: Context): NumassJsPlugin = NumassJsPlugin()
override fun build(context: Context, meta: Meta): NumassJsPlugin = NumassJsPlugin()
} }
} }

View File

@ -1,53 +0,0 @@
package ru.inr.mass.data.server
import kotlinx.coroutines.runBlocking
import kotlinx.html.div
import kotlinx.html.h1
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.visionforge.three.server.close
import space.kscience.visionforge.three.server.serve
import space.kscience.visionforge.three.server.show
import space.kscience.visionforge.visionManager
import java.nio.file.Path
public fun main() {
val context = Context("Numass") {
plugin(NumassProtoPlugin)
plugin(NumassCommonPlugin)
}
val pointPath = Path.of("C:\\Users\\altavir\\Desktop\\p20211122173034(20s).dat")
val point: NumassPoint = context.readNumassPointFile(pointPath)!!
val visionOfNumass = runBlocking {
point.toVision()
}
val server = context.visionManager.serve {
//use client library
useNumassWeb()
//use css
//useCss("css/styles.css")
page {
div("flex-column") {
h1 { +"Satellite detector demo" }
//vision(visionOfNumass)
}
}
}
server.show()
println("Enter 'exit' to close server")
while (readLine() != "exit") {
//
}
server.close()
}

View File

@ -0,0 +1,50 @@
package ru.inr.mass.data.server
import kotlinx.html.div
import kotlinx.html.h1
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.visionforge.html.VisionPage
import space.kscience.visionforge.server.close
import space.kscience.visionforge.server.openInBrowser
import space.kscience.visionforge.server.serve
import space.kscience.visionforge.visionManager
import java.nio.file.Path
public suspend fun main() {
val context = Context("Numass") {
plugin(NumassProtoPlugin)
plugin(NumassCommonPlugin)
}
val numassProto = context.fetch(NumassProtoPlugin)
val pointPath = Path.of("D:\\Work\\Numass\\data\\test\\set_7\\p120(30s)(HV1=13300)")
val point: NumassPoint = numassProto.readNumassPointFile(pointPath)!!
val visionOfNumass = point.toVision()
val server = context.visionManager.serve {
header("numass", VisionPage.scriptHeader("js/numass-web.js"))
page {
div("flex-column") {
h1 { +"Visionforge file demo" }
vision { visionOfNumass }
}
}
}
server.openInBrowser()
println("Enter 'exit' to close server")
while (readLine() != "exit") {
//
}
server.close()
}

View File

@ -4,29 +4,26 @@ import space.kscience.dataforge.context.Context
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import space.kscience.visionforge.html.HtmlVisionFragment import space.kscience.visionforge.html.HtmlVisionFragment
import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.html.ResourceLocation
import space.kscience.visionforge.html.page import space.kscience.visionforge.html.VisionPage
import space.kscience.visionforge.html.scriptHeader import space.kscience.visionforge.html.importScriptHeader
import space.kscience.visionforge.makeFile import space.kscience.visionforge.makeFile
import space.kscience.visionforge.three.server.VisionServer
import space.kscience.visionforge.three.server.useScript
import java.awt.Desktop import java.awt.Desktop
import java.nio.file.Path import java.nio.file.Path
public fun VisionServer.useNumassWeb(): Unit {
useScript("js/numass-web.js")
}
@DFExperimental @DFExperimental
public fun Context.makeNumassWebFile( public fun Context.makeNumassWebFile(
content: HtmlVisionFragment,
path: Path? = null, path: Path? = null,
title: String = "VisionForge Numass page", title: String = "VisionForge Numass page",
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM, resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
show: Boolean = true, show: Boolean = true,
content: HtmlVisionFragment,
): Unit { ): Unit {
val actualPath = page(title, content = content).makeFile(path) { actualPath -> val actualPath = VisionPage(this, content = content).makeFile(path) { actualPath: Path ->
mapOf("numassWeb" to scriptHeader("js/numass-web.js", resourceLocation, actualPath)) mapOf(
"title" to VisionPage.title(title),
"numassWeb" to VisionPage.importScriptHeader("js/numass-web.js", resourceLocation, actualPath)
)
} }
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
} }

View File

@ -0,0 +1,28 @@
package ru.inr.mass.data.server
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 java.nio.file.Path
@Suppress("OPT_IN_USAGE")
public suspend fun main() {
val context = Context("Numass") {
plugin(NumassProtoPlugin)
plugin(NumassCommonPlugin)
}
val numassProto = context.fetch(NumassProtoPlugin)
val pointPath = Path.of("D:\\Work\\Numass\\data\\test\\set_7\\p120(30s)(HV1=13300)")
val point: NumassPoint = numassProto.readNumassPointFile(pointPath)!!
val visionOfNumass: VisionOfNumassPoint = point.toVision()
context.makeNumassWebFile {
vision { visionOfNumass }
}
}

View File

@ -1,5 +1,5 @@
plugins { plugins {
id("ru.mipt.npm.gradle.jvm") id("space.kscience.gradle.jvm")
} }
val dataforgeVersion: String by rootProject.extra val dataforgeVersion: String by rootProject.extra

View File

@ -1,5 +1,5 @@
plugins { plugins {
id("ru.mipt.npm.gradle.mpp") id("space.kscience.gradle.mpp")
`maven-publish` `maven-publish`
} }

View File

@ -1,6 +1,6 @@
plugins { plugins {
id("ru.mipt.npm.gradle.jvm") id("space.kscience.gradle.jvm")
id("com.github.johnrengelman.shadow") version "7.1.1" id("com.github.johnrengelman.shadow") version "7.1.2"
`maven-publish` `maven-publish`
} }
@ -9,7 +9,7 @@ kotlin {
} }
val dataforgeVersion: String by rootProject.extra val dataforgeVersion: String by rootProject.extra
val plotlyVersion: String by rootProject.extra("0.5.0") val visionForgeVersion: String by rootProject.extra
val kmathVersion: String by rootProject.extra val kmathVersion: String by rootProject.extra
val tablesVersion: String by rootProject.extra val tablesVersion: String by rootProject.extra
@ -18,9 +18,10 @@ dependencies {
implementation(projects.numassModel) implementation(projects.numassModel)
implementation(projects.numassAnalysis) implementation(projects.numassAnalysis)
implementation("space.kscience:dataforge-workspace:$dataforgeVersion") implementation("space.kscience:dataforge-workspace:$dataforgeVersion")
implementation("space.kscience:plotlykt-jupyter:$plotlyVersion")
implementation("space.kscience:kmath-jupyter:$kmathVersion") implementation("space.kscience:kmath-jupyter:$kmathVersion")
implementation("space.kscience:tables-kt:$tablesVersion") implementation("space.kscience:tables-kt:$tablesVersion")
implementation("space.kscience:visionforge-plotly:$visionForgeVersion")
} }
kscience{ kscience{

View File

@ -5,6 +5,7 @@ import kotlinx.coroutines.runBlocking
import kotlinx.html.* import kotlinx.html.*
import kotlinx.html.stream.createHTML import kotlinx.html.stream.createHTML
import org.jetbrains.kotlinx.jupyter.api.HTML import org.jetbrains.kotlinx.jupyter.api.HTML
import org.jetbrains.kotlinx.jupyter.api.declare
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
import ru.inr.mass.data.api.NumassBlock import ru.inr.mass.data.api.NumassBlock
import ru.inr.mass.data.api.NumassFrame import ru.inr.mass.data.api.NumassFrame
@ -23,7 +24,8 @@ import space.kscience.plotly.toPage
internal class NumassJupyter : JupyterIntegration() { internal class NumassJupyter : JupyterIntegration() {
override fun Builder.onLoaded() { override fun Builder.onLoaded() {
repositories( repositories(
"https://repo.kotlin.link" "https://repo.kotlin.link",
"https://maven.pkg.jetbrains.space/spc/p/sci/dev"
) )
import( import(
@ -39,6 +41,9 @@ internal class NumassJupyter : JupyterIntegration() {
import<Numass>() import<Numass>()
onLoaded {
declare("Numass" to Numass, "workspace" to Numass.workspace)
}
render<NumassBlock> { render<NumassBlock> {
HTML(Plotly.plotNumassBlock(it).toPage().render()) HTML(Plotly.plotNumassBlock(it).toPage().render())
@ -60,7 +65,7 @@ internal class NumassJupyter : JupyterIntegration() {
} }
render<DataTree<NumassDirectorySet>> { tree -> render<DataTree<NumassDirectorySet>> { tree ->
HTML(createHTML().div { numassTree(tree)}) HTML(createHTML().div { numassTree(tree) })
} }
} }
} }
@ -68,7 +73,7 @@ internal class NumassJupyter : JupyterIntegration() {
private fun FlowContent.numassTree(tree: DataTree<NumassDirectorySet>) { private fun FlowContent.numassTree(tree: DataTree<NumassDirectorySet>) {
ul { ul {
runBlocking { runBlocking {
tree.items().forEach { (token, treeItem) -> tree.items.forEach { (token, treeItem) ->
li { li {
p { +token.toString() } p { +token.toString() }
when (treeItem) { when (treeItem) {

View File

@ -5,13 +5,13 @@ import ru.inr.mass.workspace.Numass.readRepository
import ru.inr.mass.workspace.plotNumassSet import ru.inr.mass.workspace.plotNumassSet
import space.kscience.dataforge.data.DataTree import space.kscience.dataforge.data.DataTree
import space.kscience.dataforge.data.await import space.kscience.dataforge.data.await
import space.kscience.dataforge.data.getData import space.kscience.dataforge.data.get
import space.kscience.plotly.Plotly import space.kscience.plotly.Plotly
import space.kscience.plotly.makeFile import space.kscience.plotly.makeFile
suspend fun main() { suspend fun main() {
val repo: DataTree<NumassDirectorySet> = readRepository("D:\\Work\\Numass\\data\\2018_04") val repo: DataTree<NumassDirectorySet> = readRepository("D:\\Work\\Numass\\data\\2018_04")
val testSet = repo.getData("Adiabacity_19.set_3")?.await() ?: error("Not found") val testSet = repo["Adiabacity_19.set_3"]?.await() ?: error("Not found")
Plotly.plotNumassSet(testSet).makeFile() Plotly.plotNumassSet(testSet).makeFile()
} }

View File

@ -85,7 +85,7 @@ suspend fun main() {
val hv = 16900.0 val hv = 16900.0
//select point number 2 (U = 16900 V) from each directory //select point number 2 (U = 16900 V) from each directory
val points: Map<NameToken, NumassPoint?> = repo.items().mapValues { val points: Map<NameToken, NumassPoint?> = repo.items.mapValues {
val directory = it.value.data?.await() val directory = it.value.data?.await()
val point = directory?.points?.find { point -> point.voltage == hv } val point = directory?.points?.find { point -> point.voltage == hv }
point point

View File

@ -1,20 +1,22 @@
package ru.inr.mass.scripts package ru.inr.mass.scripts
import kotlinx.coroutines.flow.collect
import ru.inr.mass.data.proto.NumassDirectorySet import ru.inr.mass.data.proto.NumassDirectorySet
import ru.inr.mass.workspace.Numass.readRepository import ru.inr.mass.workspace.Numass.readRepository
import space.kscience.dataforge.data.DataSource
import space.kscience.dataforge.data.DataTree import space.kscience.dataforge.data.DataTree
import space.kscience.dataforge.data.filter import space.kscience.dataforge.data.filter
import space.kscience.dataforge.data.forEach
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.string import space.kscience.dataforge.meta.string
suspend fun main() { suspend fun main() {
val repo: DataTree<NumassDirectorySet> = readRepository("D:\\Work\\Numass\\data\\2018_04") val repo: DataTree<NumassDirectorySet> = readRepository("D:\\Work\\Numass\\data\\2018_04")
val filtered = repo.filter { _, data -> val filtered: DataSource<NumassDirectorySet> = repo.filter { _, meta: Meta ->
val operator by data.meta.string() val operator by meta.string()
operator?.startsWith("Vas") ?: false operator?.startsWith("Vas") ?: false
} }
filtered.flowData().collect { filtered.forEach{
println(it) println(it)
} }
} }

View File

@ -3,54 +3,41 @@ package ru.inr.mass.workspace
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import ru.inr.mass.data.api.NumassBlock import ru.inr.mass.data.api.NumassBlock
import ru.inr.mass.data.api.NumassPoint import ru.inr.mass.data.api.NumassPoint
import ru.inr.mass.data.api.NumassSet import ru.inr.mass.data.proto.*
import ru.inr.mass.data.proto.NumassDirectorySet import space.kscience.dataforge.context.fetch
import ru.inr.mass.data.proto.readNumassDirectory import space.kscience.dataforge.data.DataTree
import ru.inr.mass.data.proto.readNumassPointFile import space.kscience.dataforge.workspace.Workspace
import space.kscience.dataforge.data.*
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.NameToken
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.exists
import kotlin.io.path.isDirectory
import kotlin.io.path.relativeTo
import kotlin.streams.toList
object Numass { object Numass {
fun readDirectory(path: String): NumassDirectorySet = NUMASS.context.readNumassDirectory(path) val workspace = Workspace {
context {
@OptIn(ExperimentalPathApi::class) plugin(NumassWorkspacePlugin)
fun readRepository(path: Path): DataTree<NumassDirectorySet> = runBlocking {
ActiveDataTree {
@Suppress("BlockingMethodInNonBlockingContext")
withContext(Dispatchers.IO) {
Files.walk(path).filter {
it.isDirectory() && it.resolve("meta").exists()
}.toList().forEach { childPath ->
val name = Name(childPath.relativeTo(path).map { segment ->
NameToken(segment.fileName.toString())
})
val value = NUMASS.context.readNumassDirectory(childPath)
static(name, value, value.meta)
}
}
//TODO add file watcher
} }
} }
fun readRepository(path: String): DataTree<NumassDirectorySet> = readRepository(Path.of(path)) val context get() = workspace.context
fun readPoint(path: String): NumassPoint = NUMASS.context.readNumassPointFile(path) val numassProto by lazy { context.fetch(NumassProtoPlugin) }
?: error("Can't read numass point at $path")
} 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) }
operator fun DataSet<NumassSet>.get(name: String): NumassSet? = runBlocking {
getData(Name.parse(name))?.await()
} }
fun NumassBlock.listFrames() = runBlocking { frames.toList() } fun NumassBlock.listFrames() = runBlocking { frames.toList() }

View File

@ -1,118 +0,0 @@
package ru.inr.mass.workspace
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.meta.Meta
import space.kscience.dataforge.values.Value
import space.kscience.dataforge.workspace.TaskReference
import space.kscience.dataforge.workspace.WorkspacePlugin
import space.kscience.dataforge.workspace.task
import space.kscience.tables.Table
import kotlin.reflect.KClass
class NumassPlugin : WorkspacePlugin() {
override val tag: PluginTag get() = Companion.tag
val numassProtoPlugin by require(NumassProtoPlugin)
// val select 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.select<NumassSet> { _, meta ->
// when (forward) {
// true -> meta["iteration_info.reverse"]?.boolean?.not() ?: false
// false -> meta["iteration_info.reverse"]?.boolean ?: false
// else -> true
// }
// }
//
// emit(Name.EMPTY, filtered)
// }
//
// val analyze by task<Table<Value>>(
// MetaDescriptor {
// info = "Count the number of events for each voltage and produce a table with the results"
// }
// ) {
// pipeFrom(select) { set, name, meta ->
// val res = SmartAnalyzer.analyzeSet(set, 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 {
// descriptor {
// value("showPlot", types = listOf(ValueType.BOOLEAN), info = "Show plot after complete")
// value("monitorPoint", types = listOf(ValueType.NUMBER), info = "The voltage for monitor point")
// }
// 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))
// }
// }
// join<NumassSet, Table> { data ->
// val monitorVoltage = meta.getDouble("monitorPoint", 16000.0);
// val analyzer = SmartAnalyzer()
// val analyzerMeta = meta.getMetaOrEmpty("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.getBoolean("showPlot", 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)
//
// return@join res;
// }
}
companion object : PluginFactory<NumassPlugin> {
override val tag: PluginTag = PluginTag("numass", "ru.mipt.npm")
override val type: KClass<out NumassPlugin> = NumassPlugin::class
override fun invoke(meta: Meta, context: Context): NumassPlugin = NumassPlugin()
}
}

View File

@ -0,0 +1,134 @@
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
import kotlin.reflect.KClass
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 val type: KClass<out NumassWorkspacePlugin> = NumassWorkspacePlugin::class
override fun build(context: Context, meta: Meta): NumassWorkspacePlugin = NumassWorkspacePlugin()
}
}

View File

@ -10,8 +10,8 @@ import ru.inr.mass.data.analysis.timeHistogram
import ru.inr.mass.data.api.* import ru.inr.mass.data.api.*
import ru.inr.mass.data.proto.HVData import ru.inr.mass.data.proto.HVData
import ru.inr.mass.data.proto.NumassDirectorySet import ru.inr.mass.data.proto.NumassDirectorySet
import space.kscience.dataforge.values.asValue import space.kscience.dataforge.meta.asValue
import space.kscience.dataforge.values.double import space.kscience.dataforge.meta.double
import space.kscience.kmath.domains.center import space.kscience.kmath.domains.center
import space.kscience.kmath.histogram.Histogram1D import space.kscience.kmath.histogram.Histogram1D
import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.misc.UnstableKMathAPI

View File

@ -1,10 +0,0 @@
package ru.inr.mass.workspace
import ru.inr.mass.data.proto.NumassProtoPlugin
import space.kscience.dataforge.workspace.Workspace
val NUMASS = Workspace {
context{
plugin(NumassProtoPlugin)
}
}

View File

@ -15,10 +15,10 @@ pluginManagement {
} }
plugins { plugins {
id("ru.mipt.npm.gradle.project") version toolsVersion id("space.kscience.gradle.project") version toolsVersion
id("ru.mipt.npm.gradle.mpp") version toolsVersion id("space.kscience.gradle.mpp") version toolsVersion
id("ru.mipt.npm.gradle.jvm") version toolsVersion id("space.kscience.gradle.jvm") version toolsVersion
id("ru.mipt.npm.gradle.js") version toolsVersion id("space.kscience.gradle.js") version toolsVersion
} }
} }
@ -34,7 +34,7 @@ dependencyResolutionManagement {
versionCatalogs { versionCatalogs {
create("npmlibs") { create("npmlibs") {
from("ru.mipt.npm:version-catalog:$toolsVersion") from("space.kscience:version-catalog:$toolsVersion")
} }
} }
} }
@ -43,7 +43,7 @@ include(
":numass-data-model", ":numass-data-model",
":numass-analysis", ":numass-analysis",
":numass-data-proto", ":numass-data-proto",
//":numass-data-server", ":numass-data-server",
":numass-workspace", ":numass-workspace",
":numass-model", ":numass-model",
//":numass-detector-client" //":numass-detector-client"