Compare commits

..

2 Commits

Author SHA1 Message Date
af2539eed2 BM@N and fixes 2023-09-30 20:13:08 +03:00
4b91e5d62b BM@N and fixes 2023-09-30 20:01:29 +03:00
10 changed files with 14899 additions and 33 deletions

View File

@ -0,0 +1,53 @@
package ru.mipt.npm.root
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import space.kscience.visionforge.solid.Float32Vector3D
@Serializable
public data class FairTrackParam(
val fX: Double,
val fY: Double,
val fZ: Double,
val fTx: Double,
val fTy: Double,
val fQp: Double,
)
public fun FairTrackParam.toVector(): Float32Vector3D = Float32Vector3D(fX,fY,fZ)
@Serializable
public data class CbmStsTrack(
val fParamFirst: FairTrackParam,
val fParamLast: FairTrackParam,
)
@Serializable
public data class BmnGlobalTrack(
val fParamFirst: FairTrackParam,
val fParamLast: FairTrackParam,
)
public class BmnEventContainer(
public val cbmTracks: List<CbmStsTrack>,
public val bmnGlobalTracks: List<BmnGlobalTrack>,
)
public object BMN {
public val json: Json = Json {
ignoreUnknownKeys = true
classDiscriminator = "_typename"
}
public fun readEventJson(string: String): BmnEventContainer {
val jsonArray = json.parseToJsonElement(string) as JsonArray
val cbmTracks: List<CbmStsTrack> =
json.decodeFromJsonElement(ListSerializer(CbmStsTrack.serializer()), jsonArray[0])
val bmnGlobalTracks: List<BmnGlobalTrack> =
json.decodeFromJsonElement(ListSerializer(BmnGlobalTrack.serializer()), jsonArray[1])
return BmnEventContainer(cbmTracks, bmnGlobalTracks)
}
}

View File

@ -113,8 +113,8 @@ private fun SolidGroup.addShape(
val fScale by shape.meta.doubleArray() val fScale by shape.meta.doubleArray()
extruded(name = name) { extruded(name = name) {
(0 until fNvert).forEach { index -> shape {
shape { (0 until fNvert).forEach { index ->
point(fX[index], fY[index]) point(fX[index], fY[index])
} }
} }
@ -181,10 +181,9 @@ private fun SolidGroup.addShape(
name = name, name = name,
) { ) {
z = (fZ[1] + fZ[0]) / 2 z = (fZ[1] + fZ[0]) / 2
}.apply(block) }.apply(block)
} else { } else {
TODO() TODO("Polycone is not implemented")
} }
} }

View File

@ -1,18 +1,17 @@
package space.kscience.visionforge.examples package space.kscience.visionforge.examples
import ru.mipt.npm.root.BMN
import ru.mipt.npm.root.DGeoManager import ru.mipt.npm.root.DGeoManager
import ru.mipt.npm.root.rootGeo import ru.mipt.npm.root.rootGeo
import ru.mipt.npm.root.serialization.TGeoManager import ru.mipt.npm.root.serialization.TGeoManager
import ru.mipt.npm.root.toVector
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.isLeaf import space.kscience.dataforge.meta.isLeaf
import space.kscience.dataforge.meta.string import space.kscience.dataforge.meta.string
import space.kscience.visionforge.Colors import space.kscience.visionforge.Colors
import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.html.ResourceLocation
import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.*
import space.kscience.visionforge.solid.ambientLight
import space.kscience.visionforge.solid.invoke
import space.kscience.visionforge.solid.solid
import java.util.zip.ZipInputStream import java.util.zip.ZipInputStream
import kotlin.io.path.Path import kotlin.io.path.Path
import kotlin.io.path.writeText import kotlin.io.path.writeText
@ -39,6 +38,8 @@ fun main() {
println(it) println(it)
} }
val events = BMN.readEventJson(TGeoManager::class.java.getResourceAsStream("/root/event_0.json")!!.bufferedReader().readText())
makeVisionFile(path = Path("data/output.html"), resourceLocation = ResourceLocation.EMBED) { makeVisionFile(path = Path("data/output.html"), resourceLocation = ResourceLocation.EMBED) {
vision("canvas") { vision("canvas") {
requirePlugin(Solids) requirePlugin(Solids)
@ -49,6 +50,30 @@ fun main() {
rootGeo(geo,"BM@N", ignoreRootColors = true).also { rootGeo(geo,"BM@N", ignoreRootColors = true).also {
Path("data/BM@N.vf.json").writeText(Solids.encodeToString(it)) Path("data/BM@N.vf.json").writeText(Solids.encodeToString(it))
} }
solidGroup("cbmStsTracks") {
events.cbmTracks.forEach { track ->
polyline(
track.fParamFirst.toVector(),
track.fParamLast.toVector()
) {
thickness = 2.0
color(Colors.blue)
}
}
}
solidGroup("bmnGlobalTracks") {
events.bmnGlobalTracks.forEach { track ->
polyline(
track.fParamFirst.toVector(),
track.fParamLast.toVector()
) {
thickness = 2.0
color(Colors.red)
}
}
}
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,215 @@
[
[{
"_typename" : "CbmStsTrack",
"fUniqueID" : 0,
"fBits" : 0,
"ststrk" : 2112745000,
"fStsHits" : [216, 221, 5, 50, 63, 82, 133],
"fMvdHits" : [],
"fPidHypo" : 211,
"fParamFirst" : {
"_typename" : "FairTrackParam",
"fUniqueID" : 0,
"fBits" : 0,
"fX" : -4.79052305221558,
"fY" : 8.83165168762207,
"fZ" : 36.5065002441406,
"fTx" : -0.11185921728611,
"fTy" : 0.228091076016426,
"fQp" : 0.893607378005981,
"fCovMatrix" : [1.68777798535302e-4, -9.69577522482723e-4, -1.07744517663377e-5, 1.2614247680176e-5, 2.87587154161884e-5, 0.0403835587203503, 5.90448107686825e-5, -5.16064348630607e-4, -2.05383723368868e-4, 2.20405854634009e-6, -8.30146461794357e-7, -5.49759215573431e-6, 1.16227884063846e-5, 3.6013934732182e-6, 1.46196922287345e-4]
},
"fParamLast" : {
"_typename" : "FairTrackParam",
"fUniqueID" : 0,
"fBits" : 0,
"fX" : 4.67626953125,
"fY" : 43.7959594726562,
"fZ" : 190.759826660156,
"fTx" : 0.240885242819786,
"fTy" : 0.230351597070694,
"fQp" : 0.896391570568085,
"fCovMatrix" : [0.00152156152762473, 0.00325645040720701, 4.73157851956785e-5, 4.51812447863631e-5, 1.32256536744535e-4, 0.0311740729957819, 1.29416745039634e-4, 3.94528120523319e-4, 3.28425812767819e-4, 3.75195077140233e-6, 1.75166894678114e-6, 9.62230569712119e-6, 9.89728778222343e-6, 4.38717188444571e-6, 1.46559861605056e-4]
},
"fFlag" : 0,
"fChi2" : 3.59655165672302,
"fNDF" : 9,
"fB" : 0,
"fnEv" : 0,
"fHitsArr" : {
"_typename" : "TClonesArray",
"name" : "CbmStsHits",
"arr" : []
}
}, {
"_typename" : "CbmStsTrack",
"fUniqueID" : 0,
"fBits" : 0,
"ststrk" : 0,
"fStsHits" : [79, 108, 136, 160],
"fMvdHits" : [],
"fPidHypo" : 211,
"fParamFirst" : {
"_typename" : "FairTrackParam",
"fUniqueID" : 0,
"fBits" : 0,
"fX" : 7.56474113464355,
"fY" : -6.31765508651733,
"fZ" : 123.474571228027,
"fTx" : 0.198165953159332,
"fTy" : -0.0599287338554859,
"fQp" : 0.826108694076538,
"fCovMatrix" : [0.00192060391418636, -0.00543995574116707, -7.47249359847046e-5, 9.40304598771036e-5, 4.32362634455785e-4, 0.0452092550694942, 2.69763870164752e-4, -7.19496863894165e-4, -0.00178805936593562, 5.47440777154407e-6, -4.97666542287334e-6, -3.32396593876183e-5, 1.67156704264926e-5, 3.69572808267549e-5, 3.62657097866759e-4]
},
"fParamLast" : {
"_typename" : "FairTrackParam",
"fUniqueID" : 0,
"fBits" : 0,
"fX" : 38.4175720214844,
"fY" : -12.5351896286011,
"fZ" : 222.266052246094,
"fTx" : 0.428264498710632,
"fTy" : -0.0652719661593437,
"fQp" : 0.827384233474731,
"fCovMatrix" : [0.00191446917597204, 0.00539331184700131, 7.50113686081022e-5, 9.10265880520456e-5, 4.29905543569475e-4, 0.0449054278433323, 2.68147414317355e-4, 7.0479983696714e-4, 0.00177141127642244, 5.60895068701939e-6, 4.76898094348144e-6, 3.39166836056393e-5, 1.61108710017288e-5, 3.51894050254487e-5, 3.57192009687424e-4]
},
"fFlag" : 0,
"fChi2" : 0.0889237225055695,
"fNDF" : 3,
"fB" : 0,
"fnEv" : 0,
"fHitsArr" : {
"_typename" : "TClonesArray",
"name" : "CbmStsHits",
"arr" : []
}
}]
,
[{
"_typename" : "BmnGlobalTrack",
"fUniqueID" : 0,
"fBits" : 0,
"fHits" : [],
"fParamFirst" : {
"_typename" : "FairTrackParam",
"fUniqueID" : 0,
"fBits" : 0,
"fX" : 0.514997541904449,
"fY" : 0.614071667194366,
"fZ" : 0.716018855571747,
"fTx" : -0.182437181472778,
"fTy" : 0.231170654296875,
"fQp" : 0.890645802021027,
"fCovMatrix" : [0.00640107085928321, -0.00549036636948586, -2.40077963098884e-4, 5.9050194977317e-5, 4.4034980237484e-4, 0.0939982086420059, 1.37060953420587e-4, -0.0010447750100866, -3.45796346664429e-4, 1.4494138667942e-5, -1.88720639471285e-6, -1.71545361808967e-5, 2.24065261136275e-5, 4.27886925535859e-6, 1.46344274980947e-4]
},
"fParamLast" : {
"_typename" : "FairTrackParam",
"fUniqueID" : 0,
"fBits" : 0,
"fX" : 4.67626953125,
"fY" : 43.7959594726562,
"fZ" : 190.759826660156,
"fTx" : 0.240885242819786,
"fTy" : 0.230351597070694,
"fQp" : 0.896391570568085,
"fCovMatrix" : [0.00152156152762473, 0.00325645040720701, 4.73157851956785e-5, 4.51812447863631e-5, 1.32256536744535e-4, 0.0311740729957819, 1.29416745039634e-4, 3.94528120523319e-4, 3.28425812767819e-4, 3.75195077140233e-6, 1.75166894678114e-6, 9.62230569712119e-6, 9.89728778222343e-6, 4.38717188444571e-6, 1.46559861605056e-4]
},
"fFlag" : -1,
"fChi2" : 3.596552,
"fNDF" : 9,
"fB" : 0,
"fLength" : 196.4224,
"fNhits" : 7,
"fUsing" : false,
"fGemTrack" : 0,
"fSsdTrack" : -1,
"fSilTrack" : -1,
"fTof1Hit" : -1,
"fTof2Hit" : -1,
"fDch1Track" : -1,
"fDch2Track" : -1,
"fDchTrack" : -1,
"fMwpc1Track" : -1,
"fMwpc2Track" : -1,
"fUpstreamTrack" : -1,
"fScWallCellId" : -1,
"fCscHit" : [-1, -1, -1, -1],
"fScWallSignal" : -1000,
"fBeta400" : -1000,
"fBeta700" : -1000,
"fdQdNUpper" : 0,
"fdQdNLower" : 0,
"fA" : -1,
"fZ" : 0,
"fPDG" : 0,
"fChi2InVertex" : 2.34478793822074e-310,
"fDCAInVertex" : 0.169359803199768,
"fPidTof400" : [],
"fPidTof700" : [],
"fIsPrimary" : true,
"fRefIndex" : 0
}, {
"_typename" : "BmnGlobalTrack",
"fUniqueID" : 0,
"fBits" : 0,
"fHits" : [],
"fParamFirst" : {
"_typename" : "FairTrackParam",
"fUniqueID" : 0,
"fBits" : 0,
"fX" : -1.30332088470459,
"fY" : 0.709633886814117,
"fZ" : 0.716018855571747,
"fTx" : -0.0394387505948544,
"fTy" : -0.0554707236588001,
"fQp" : 0.794627845287323,
"fCovMatrix" : [1.0362377166748, -0.242409482598305, -0.0120293609797955, 0.00132000644225627, 0.0113498065620661, 1.10034370422363, 0.0026963478885591, -0.0100266374647617, -0.00638964772224426, 1.71858730027452e-4, -1.46718830364989e-5, -1.39145020511933e-4, 1.31993641844019e-4, 3.72123940906022e-5, 3.64089268259704e-4]
},
"fParamLast" : {
"_typename" : "FairTrackParam",
"fUniqueID" : 0,
"fBits" : 0,
"fX" : 153.443832397461,
"fY" : -27.7408638000488,
"fZ" : 422.371002197266,
"fTx" : 0.623147189617157,
"fTy" : -0.0757252722978592,
"fQp" : 0.879441320896149,
"fCovMatrix" : [0.210621446371078, 0.00677151698619127, 0.00126052019186318, -1.89192069228739e-5, 0.00233594398014247, 0.117487587034702, 1.90632126759738e-5, 5.61361608561128e-4, 3.66047053830698e-4, 5.4321233619703e-5, -1.38209452416049e-6, 1.40239317261148e-5, 3.86252722819336e-5, -2.07852266953523e-7, 1.6525064711459e-4]
},
"fFlag" : -1,
"fChi2" : 28.54445,
"fNDF" : 3,
"fB" : 0,
"fLength" : 456.7299,
"fNhits" : 5,
"fUsing" : false,
"fGemTrack" : 1,
"fSsdTrack" : -1,
"fSilTrack" : -1,
"fTof1Hit" : 0,
"fTof2Hit" : -1,
"fDch1Track" : -1,
"fDch2Track" : -1,
"fDchTrack" : -1,
"fMwpc1Track" : -1,
"fMwpc2Track" : -1,
"fUpstreamTrack" : -1,
"fScWallCellId" : -1,
"fCscHit" : [-1, -1, -1, -1],
"fScWallSignal" : -1000,
"fBeta400" : 0.813491527513362,
"fBeta700" : -1000,
"fdQdNUpper" : 0,
"fdQdNLower" : 0,
"fA" : -1,
"fZ" : 0,
"fPDG" : 0,
"fChi2InVertex" : 2.34478793822074e-310,
"fDCAInVertex" : 1.82100653648376,
"fPidTof400" : [0.698706510566553, 0.0456706934329348, 0.070160747316434, 0.044178479600919, 0.0321317585690916, 0.0203602877603981, 0.0563498151154308, 0.0324417076382387],
"fPidTof700" : [],
"fIsPrimary" : true,
"fRefIndex" : 0
}]
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -34,20 +34,27 @@ public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
} }
} }
/**
* A layer for extruded shape
*/
@Serializable @Serializable
public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
/**
* An extruded shape with the same number of points on each layer.
*/
@Serializable @Serializable
@SerialName("solid.extrude") @SerialName("solid.extrude")
public class Extruded( public class Extruded(
public val shape: List<Float32Vector2D>, public val shape: Shape2D,
public val layers: List<Layer>, public val layers: List<Layer>,
) : SolidBase<Extruded>(), GeometrySolid { ) : SolidBase<Extruded>(), GeometrySolid {
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) { init {
val shape: Shape2D = shape require(shape.size > 2) { "Extruded shape requires more than 2 points per layer" }
}
if (shape.size < 3) error("Extruded shape requires more than 2 points per layer") override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
/** /**
* Expand the shape for specific layers * Expand the shape for specific layers
@ -90,31 +97,31 @@ public class Extruded(
geometryBuilder.cap(layers.last()) geometryBuilder.cap(layers.last())
} }
public class Builder(
public var shape: List<Float32Vector2D> = emptyList(),
public var layers: MutableList<Layer> = ArrayList(),
public val properties: MutableMeta = MutableMeta(),
) {
public fun shape(block: Shape2DBuilder.() -> Unit) {
this.shape = Shape2DBuilder().apply(block).build()
}
public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) {
layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat()))
}
internal fun build(): Extruded = Extruded(shape, layers).apply {
this.properties.setProperty(Name.EMPTY, this@Builder.properties)
}
}
public companion object { public companion object {
public const val TYPE: String = "solid.extruded" public const val TYPE: String = "solid.extruded"
} }
} }
public class ExtrudeBuilder(
public var shape: List<Float32Vector2D> = emptyList(),
public var layers: MutableList<Layer> = ArrayList(),
public val properties: MutableMeta = MutableMeta(),
) {
public fun shape(block: Shape2DBuilder.() -> Unit) {
this.shape = Shape2DBuilder().apply(block).build()
}
public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) {
layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat()))
}
internal fun build(): Extruded = Extruded(shape, layers).apply {
this.properties.setProperty(Name.EMPTY, this@ExtrudeBuilder.properties)
}
}
@VisionBuilder @VisionBuilder
public fun MutableVisionContainer<Solid>.extruded( public fun MutableVisionContainer<Solid>.extruded(
name: String? = null, name: String? = null,
action: ExtrudeBuilder.() -> Unit = {}, action: Extruded.Builder.() -> Unit = {},
): Extruded = ExtrudeBuilder().apply(action).build().also { setChild(name, it) } ): Extruded = Extruded.Builder().apply(action).build().also { setChild(name, it) }

View File

@ -15,7 +15,6 @@ import kotlin.math.sqrt
@Serializable(Float32Euclidean2DSpace.VectorSerializer::class) @Serializable(Float32Euclidean2DSpace.VectorSerializer::class)
public interface Float32Vector2D: Vector2D<Float> public interface Float32Vector2D: Vector2D<Float>
public object Float32Euclidean2DSpace : public object Float32Euclidean2DSpace :
GeometrySpace<Float32Vector2D>, GeometrySpace<Float32Vector2D>,
ScaleOperations<Float32Vector2D> { ScaleOperations<Float32Vector2D> {

View File

@ -0,0 +1,136 @@
package space.kscience.visionforge.solid
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import space.kscience.kmath.geometry.component1
import space.kscience.kmath.geometry.component2
import space.kscience.kmath.structures.Float32
private inline fun <T> Iterable<T>.sumOf(selector: (T) -> Float32): Float32 {
var sum = 0f
for (element in this) {
sum += selector(element)
}
return sum
}
/**
* A layered solid with a hole inside
*/
@Serializable
@SerialName("solid.surface")
public class LayersSurface(
public val layers: List<Layer>,
) : SolidBase<Extruded>(), GeometrySolid {
@Serializable
public data class Layer(val z: Float32, val outer: Shape2D, val inner: Shape2D?) {
init {
require(outer.size >= 3) { "Extruded shape requires more than 2 points per layer" }
require(inner == null || inner.size == outer.size) { "Outer shape size is ${outer.size}, but inner is ${inner?.size}" }
}
public fun outerPoints(): List<Float32Vector3D> = outer.map { (x, y) -> Float32Vector3D(x, y, z) }
public fun innerPoints(): List<Float32Vector3D>? = inner?.map { (x, y) -> Float32Vector3D(x, y, z) }
public val center: Float32Vector3D by lazy {
Float32Vector3D(
outer.sumOf { it.x } / size,
outer.sumOf { it.y } / size,
z
)
}
val size: Int get() = outer.size
}
init {
require(layers.size > 1) { "Number of layers must be 2 or more" }
require(layers.all { it.size == layers.first().size }) { "All layers must have the same size" }
}
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
geometryBuilder.apply {
//outer and inner
for (i in 0 until layers.size - 1) {
val bottom = layers[i]
val top = layers[i+1]
//creating shape in x-y plane with z = 0
val bottomOuterPoints = bottom.outerPoints()
val topOuterPoints = top.outerPoints()
for (it in 1 until bottomOuterPoints.size) {
//outer face
face4(
bottomOuterPoints[it - 1],
bottomOuterPoints[it],
topOuterPoints[it],
topOuterPoints[it - 1]
)
}
//outer face last segment
face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last())
val bottomInnerPoints = bottom.innerPoints() ?: bottom.outerPoints().map { bottom.center }
val topInnerPoints = top.innerPoints() ?: top.outerPoints().map { top.center }
for (it in 1 until bottomInnerPoints.size) {
//inner face
face4(
bottomInnerPoints[it],
bottomInnerPoints[it - 1],
topInnerPoints[it - 1],
topInnerPoints[it]
)
}
//inner face last segment
face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0])
}
val bottom = layers.first()
val top = layers.last()
val bottomOuterPoints = bottom.outerPoints()
val topOuterPoints = top.outerPoints()
val bottomInnerPoints = bottom.innerPoints() ?: bottom.outerPoints().map { bottom.center }
val topInnerPoints = top.innerPoints() ?: top.outerPoints().map { top.center }
(1 until bottom.size).forEach {
//bottom cup
face4(
bottomInnerPoints[it - 1],
bottomInnerPoints[it],
bottomOuterPoints[it],
bottomOuterPoints[it - 1]
)
//upper cup
face4(
topInnerPoints[it],
topInnerPoints[it - 1],
topOuterPoints[it - 1],
topOuterPoints[it]
)
face4(
bottomInnerPoints.last(),
bottomInnerPoints[0],
bottomOuterPoints[0],
bottomOuterPoints.last()
)
face4(topInnerPoints[0], topInnerPoints.last(), topOuterPoints.last(), topOuterPoints[0])
}
}
}
public companion object {
public const val TYPE: String = "solid.surface"
}
}