From d36542ac5bc7dff9cecd02f1522413268318f4cd Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 31 Dec 2019 16:06:38 +0300 Subject: [PATCH] RC 0.1.0 --- .../vis/common/AbstractVisualGroup.kt | 19 +++--- .../vis/spatial/three/ThreeCanvas.kt | 3 +- .../vis/spatial/three/ThreeLabelFactory.kt | 1 - .../vis/spatial/three/ThreeLineFactory.kt | 12 ++-- .../vis/spatial/three/ThreeMaterials.kt | 15 ++--- .../vis/spatial/three/ThreePlugin.kt | 66 ++++++++++++++++--- .../hep/dataforge/vis/spatial/three/three.kt | 15 ++--- demo/muon-monitor/build.gradle.kts | 17 +++-- .../kotlin/ru/mipt/npm/muon/monitor/Event.kt | 10 +-- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 6 +- .../ru/mipt/npm/muon/monitor/Monitor.kt | 12 ++-- .../ru/mipt/npm/muon/monitor/MMDemoApp.kt | 64 ++++++++++-------- demo/muon-monitor/src/jsMain/web/index.html | 17 ++--- .../mipt/npm/muon/monitor/server/MMServer.kt | 24 +++++-- .../ru/mipt/npm/muon/monitor/sim/line.kt | 4 +- .../ru/mipt/npm/muon/monitor/sim/monitor.kt | 13 ++-- .../mipt/npm/muon/monitor/sim/simulation.kt | 20 ++++-- 17 files changed, 196 insertions(+), 122 deletions(-) diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt index 21edc5e8..3b93e602 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt @@ -1,10 +1,7 @@ package hep.dataforge.vis.common import hep.dataforge.meta.MetaItem -import hep.dataforge.names.Name -import hep.dataforge.names.NameToken -import hep.dataforge.names.asName -import hep.dataforge.names.isEmpty +import hep.dataforge.names.* import kotlinx.serialization.Transient @@ -75,7 +72,7 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup protected abstract fun createGroup(name: Name): MutableVisualGroup /** - * Add named or unnamed child to the group. If key is [null] the child is considered unnamed. Both key and value are not + * Add named or unnamed child to the group. If key is null the child is considered unnamed. Both key and value are not * allowed to be null in the same time. If name is present and [child] is null, the appropriate element is removed. */ override fun set(name: Name, child: VisualObject?) { @@ -102,9 +99,13 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup structureChangeListeners.forEach { it.callback(name, child) } } - operator fun set(key: String, child: VisualObject?) = if (key.isBlank()) { - child?.let { addStatic(child) } - } else { - set(key.asName(), child) + operator fun set(key: String, child: VisualObject?): Unit { + if (key.isBlank()) { + if(child!= null) { + addStatic(child) + } + } else { + set(key.toName(), child) + } } } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeCanvas.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeCanvas.kt index 5e52bf0b..47695be4 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeCanvas.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeCanvas.kt @@ -92,7 +92,8 @@ class ThreeCanvas(val three: ThreePlugin, val spec: CanvasSpec) : Renderer { val context = canvas.getContext("2d") as CanvasRenderingContext2D context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" context.fillStyle = obj.color ?: "black" - //context.textAlign = CanvasTextAlign.CENTER context.textBaseline = CanvasTextBaseline.MIDDLE val metrics = context.measureText(obj.text) //canvas.width = metrics.width.toInt() diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeLineFactory.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeLineFactory.kt index f2fba9ec..d2e8d52e 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeLineFactory.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeLineFactory.kt @@ -2,9 +2,11 @@ package hep.dataforge.vis.spatial.three import hep.dataforge.meta.node import hep.dataforge.vis.spatial.PolyLine -import hep.dataforge.vis.spatial.layer +import hep.dataforge.vis.spatial.color +import hep.dataforge.vis.spatial.three.ThreeMaterials.DEFAULT_LINE_COLOR import info.laht.threekt.core.Geometry import info.laht.threekt.core.Object3D +import info.laht.threekt.math.Color import info.laht.threekt.objects.LineSegments import kotlin.reflect.KClass @@ -18,11 +20,13 @@ object ThreeLineFactory : ThreeFactory { val material = ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.EDGES_MATERIAL_KEY).node) + + material.linewidth = obj.thickness.toDouble() + material.color = obj.color?.let { Color(it) }?: DEFAULT_LINE_COLOR + return LineSegments(geometry, material).apply { - updatePosition(obj) - layers.enable(obj.layer) - + //layers.enable(obj.layer) //add listener to object properties obj.onPropertyChange(this) { propertyName, _, _ -> updateProperty(obj, propertyName) diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeMaterials.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeMaterials.kt index b712e9be..aa09b2d3 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeMaterials.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeMaterials.kt @@ -6,7 +6,6 @@ import hep.dataforge.vis.common.Colors import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.spatial.Material3D import info.laht.threekt.materials.LineBasicMaterial -import info.laht.threekt.materials.Material import info.laht.threekt.materials.MeshBasicMaterial import info.laht.threekt.materials.MeshPhongMaterial import info.laht.threekt.math.Color @@ -25,7 +24,7 @@ object ThreeMaterials { // private val materialCache = HashMap() - private val lineMaterialCache = HashMap() + private val lineMaterialCache = HashMap() // fun buildMaterial(meta: Meta): Material = @@ -37,11 +36,11 @@ object ThreeMaterials { // //side = 2 // } - fun getLineMaterial(meta: Meta?): Material = lineMaterialCache.getOrPut(meta) { + fun getLineMaterial(meta: Meta?): LineBasicMaterial = lineMaterialCache.getOrPut(meta) { LineBasicMaterial().apply { - color = meta["color"]?.color() ?: DEFAULT_LINE_COLOR - opacity = meta["opacity"].double ?: 1.0 - transparent = meta["transparent"].boolean ?: (opacity < 1.0) + color = meta[Material3D.COLOR_KEY]?.color() ?: DEFAULT_LINE_COLOR + opacity = meta[Material3D.OPACITY_KEY].double ?: 1.0 + transparent = opacity < 1.0 linewidth = meta["thickness"].double ?: 1.0 } } @@ -98,7 +97,7 @@ fun Mesh.updateMaterial(obj: VisualObject) { color = meta[Material3D.COLOR_KEY]?.color() ?: ThreeMaterials.DEFAULT_COLOR specular = meta[Material3D.SPECULAR_COLOR]!!.color() opacity = meta[Material3D.OPACITY_KEY]?.double ?: 1.0 - transparent = opacity <= 0.0 + transparent = opacity < 1.0 wireframe = meta[Material3D.WIREFRAME_KEY].boolean ?: false needsUpdate = true } @@ -106,7 +105,7 @@ fun Mesh.updateMaterial(obj: VisualObject) { MeshBasicMaterial().apply { color = meta[Material3D.COLOR_KEY]?.color() ?: ThreeMaterials.DEFAULT_COLOR opacity = meta[Material3D.OPACITY_KEY]?.double ?: 1.0 - transparent = opacity <= 0.0 + transparent = opacity < 1.0 wireframe = meta[Material3D.WIREFRAME_KEY].boolean ?: false needsUpdate = true } diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt index 15a19515..037a34f2 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt @@ -2,10 +2,7 @@ package hep.dataforge.vis.spatial.three import hep.dataforge.context.* import hep.dataforge.meta.Meta -import hep.dataforge.names.Name -import hep.dataforge.names.asName -import hep.dataforge.names.isEmpty -import hep.dataforge.names.startsWith +import hep.dataforge.names.* import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.spatial.* import info.laht.threekt.core.Object3D @@ -43,14 +40,13 @@ class ThreePlugin : AbstractPlugin() { is Proxy -> proxyFactory(obj) is VisualGroup3D -> { val group = ThreeGroup() - obj.children.forEach { (name, child) -> + obj.children.forEach { (token, child) -> if (child is VisualObject3D && child.ignore != true) { try { val object3D = buildObject3D(child) - object3D.name = name.toString() - group.add(object3D) + group[token] = object3D } catch (ex: Throwable) { - logger.error(ex) { "Failed to render $name" } + logger.error(ex) { "Failed to render $child" } } } } @@ -71,6 +67,31 @@ class ThreePlugin : AbstractPlugin() { visible = obj.visible ?: true } } + + obj.onChildrenChange(this) { name, child -> + if (name.isEmpty()) { + logger.error { "Children change with empty namr on $group" } + return@onChildrenChange + } + + val parentName = name.cutLast() + val childName = name.last()!! + + //removing old object + findChild(name)?.let { oldChild -> + oldChild.parent?.remove(oldChild) + } + + //adding new object + if (child != null && child is VisualObject3D) { + try { + val object3D = buildObject3D(child) + set(name, object3D) + } catch (ex: Throwable) { + logger.error(ex) { "Failed to render $child" } + } + } + } } } is Composite -> compositeFactory(obj) @@ -93,7 +114,34 @@ class ThreePlugin : AbstractPlugin() { } } -fun Object3D.findChild(name: Name): Object3D? { +internal operator fun Object3D.set(token: NameToken, object3D: Object3D) { + object3D.name = token.toString() + add(object3D) +} + +internal fun Object3D.getOrCreateGroup(name: Name): Object3D { + return when { + name.isEmpty() -> this + name.length == 1 -> { + val token = name.first()!! + children.find { it.name == token.toString() } ?: info.laht.threekt.objects.Group().also { group -> + group.name = token.toString() + this.add(group) + } + } + else -> getOrCreateGroup(name.first()!!.asName()).getOrCreateGroup(name.cutFirst()) + } +} + +internal operator fun Object3D.set(name: Name, obj: Object3D) { + when (name.length) { + 0 -> error("Can't set object with an empty name") + 1 -> set(name.first()!!, obj) + else -> getOrCreateGroup(name.cutLast())[name.last()!!] = obj + } +} + +internal fun Object3D.findChild(name: Name): Object3D? { return when { name.isEmpty() -> this name.length == 1 -> this.children.find { it.name == name.first()!!.toString() } diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/three.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/three.kt index 318989ca..9f3a7985 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/three.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/three.kt @@ -5,7 +5,10 @@ import hep.dataforge.meta.float import hep.dataforge.meta.get import hep.dataforge.meta.node import hep.dataforge.vis.spatial.* -import info.laht.threekt.core.* +import info.laht.threekt.core.BufferGeometry +import info.laht.threekt.core.DirectGeometry +import info.laht.threekt.core.Face3 +import info.laht.threekt.core.Geometry import info.laht.threekt.external.controls.OrbitControls import info.laht.threekt.materials.Material import info.laht.threekt.math.Euler @@ -14,16 +17,6 @@ import info.laht.threekt.objects.Mesh import info.laht.threekt.textures.Texture import kotlin.math.PI -/** - * Utility methods for three.kt. - * TODO move to three project - */ - -@Suppress("FunctionName") -fun Group(children: Collection) = info.laht.threekt.objects.Group().apply { - children.forEach { this.add(it) } -} - val VisualObject3D.euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name) val MetaItem<*>.vector get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f) diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index c976977c..48b34d0b 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -1,9 +1,8 @@ -import org.openjfx.gradle.JavaFXOptions import scientifik.useSerialization plugins { id("scientifik.mpp") - id("org.openjfx.javafxplugin") + //id("org.openjfx.javafxplugin") id("application") } @@ -50,6 +49,14 @@ kotlin { implementation("io.ktor:ktor-serialization:$ktor_version") } } + jsMain{ + dependencies{ + implementation("io.ktor:ktor-client-js:$ktor_version") + implementation("io.ktor:ktor-client-serialization-js:$ktor_version") + implementation(npm("text-encoding")) + implementation(npm("abort-controller")) + } + } } } @@ -57,6 +64,6 @@ application { mainClassName = "ru.mipt.npm.muon.monitor.server/MMServerKt" } -configure { - modules("javafx.controls") -} \ No newline at end of file +//configure { +// modules("javafx.controls") +//} \ No newline at end of file diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt index 1992442d..5eddd7a4 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt @@ -12,9 +12,9 @@ typealias Track = List * */ @Serializable -data class Event(val track: Track?, val hits: Collection) { - /** - * The unique identity for given set of hits. One identity could correspond to different tracks - */ - val id get() = hits.sorted().joinToString(separator = ", ", prefix = "[", postfix = "]"); +data class Event(val id: Int, val track: Track?, val hits: Collection) { +// /** +// * The unique identity for given set of hits. One identity could correspond to different tracks +// */ +// val id get() = hits.sorted().joinToString(separator = ", ", prefix = "[", postfix = "]") } \ No newline at end of file diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 6a9619b8..e2d6afb0 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -60,7 +60,7 @@ class Model { map[pixel]?.color("blue") } - private fun reset() { + fun reset() { map.values.forEach { it.setProperty(Material3D.MATERIAL_COLOR_KEY, null) } @@ -73,7 +73,9 @@ class Model { highlight(it) } event.track?.let { - tracks.polyline(*it.toTypedArray()) + tracks.polyline(*it.toTypedArray(), name = "track[${event.id}]"){ + thickness = 4 + } } } diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt index 89cfe0a9..161854a8 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt @@ -125,8 +125,8 @@ object Monitor { const val PIXEL_XY_SPACING = 123.2 const val PIXEL_Z_SIZE = 30.0 const val CENTRAL_LAYER_Z = 0.0 - const val UPPER_LAYER_Z = 166.0 - const val LOWER_LAYER_Z = -180.0 + const val UPPER_LAYER_Z = -166.0 + const val LOWER_LAYER_Z = 180.0 /** * Build map for the whole monitor @@ -136,11 +136,11 @@ object Monitor { .lineSequence() .mapNotNull { line -> if (line.startsWith(" ")) { - val split = line.trim().split("\\s+".toRegex()); + val split = line.trim().split("\\s+".toRegex()) val detectorName = split[1]; - val x = split[4].toDouble() - 500; - val y = split[5].toDouble() - 500; - val z = split[6].toDouble() - 180; + val x = split[4].toDouble() - 500 + val y = split[5].toDouble() - 500 + val z = 180 - split[6].toDouble() SC16(detectorName, Point3D(x, y, z)) } else { null diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 6f5f8c31..a9fac312 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -6,53 +6,41 @@ import hep.dataforge.js.startApplication import hep.dataforge.meta.buildMeta import hep.dataforge.meta.withBottom import hep.dataforge.names.NameToken +import hep.dataforge.vis.js.editor.card import hep.dataforge.vis.js.editor.objectTree import hep.dataforge.vis.js.editor.propertyEditor import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_WIREFRAME_KEY +import hep.dataforge.vis.spatial.Visual3DPlugin import hep.dataforge.vis.spatial.VisualObject3D import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY import hep.dataforge.vis.spatial.three.ThreePlugin import hep.dataforge.vis.spatial.three.output import hep.dataforge.vis.spatial.three.threeSettings import hep.dataforge.vis.spatial.visible +import io.ktor.client.HttpClient +import io.ktor.client.features.json.JsonFeature +import io.ktor.client.features.json.serializer.KotlinxSerializer +import io.ktor.client.request.get +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.html.js.button +import kotlinx.html.js.onClickFunction import org.w3c.dom.HTMLElement import kotlin.browser.document import kotlin.dom.clear -import kotlin.math.PI private class GDMLDemoApp : Application { -// /** -// * Handle mouse drag according to https://www.html5rocks.com/en/tutorials/file/dndfiles/ -// */ -// private fun handleDragOver(event: DragEvent) { -// event.stopPropagation() -// event.preventDefault() -// event.dataTransfer?.dropEffect = "copy" -// } -// -// /** -// * Load data from text file -// */ -// private fun loadData(event: DragEvent, block: (name: String, data: String) -> Unit) { -// event.stopPropagation() -// event.preventDefault() -// -// val file = (event.dataTransfer?.files as FileList)[0] -// ?: throw RuntimeException("Failed to load file") -// -// FileReader().apply { -// onload = { -// val string = result as String -// block(file.name, string) -// } -// readAsText(file) -// } -// } private val model = Model() + private val connection = HttpClient{ + install(JsonFeature) { + serializer = KotlinxSerializer(Visual3DPlugin.json) + } + } + override fun start(state: Map) { val context = Global.context("demo") {} @@ -75,7 +63,25 @@ private class GDMLDemoApp : Application { output.camera.layers.set(0) output.camera.position.z = -2000.0 output.camera.position.y = 500.0 - settingsElement.threeSettings(output) + settingsElement.threeSettings(output){ + card("Events") { + button { + +"Next" + onClickFunction = { + GlobalScope.launch { + val event = connection.get("http://localhost:8080/event") + model.displayEvent(event) + } + } + } + button { + +"Clear" + onClickFunction = { + model.reset() + } + } + } + } //tree.visualObjectTree(visual, editor::propertyEditor) treeElement.objectTree(NameToken("World"), visual) { editorElement.propertyEditor(it) { item -> diff --git a/demo/muon-monitor/src/jsMain/web/index.html b/demo/muon-monitor/src/jsMain/web/index.html index 3f8315fa..e4bb83a9 100644 --- a/demo/muon-monitor/src/jsMain/web/index.html +++ b/demo/muon-monitor/src/jsMain/web/index.html @@ -11,24 +11,19 @@ - +

Muon monitor demo

-
+
+
+
+
-
-
+
diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/server/MMServer.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/server/MMServer.kt index 16fe88b0..1518aa35 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/server/MMServer.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/server/MMServer.kt @@ -5,6 +5,7 @@ import hep.dataforge.vis.spatial.Visual3DPlugin import io.ktor.application.Application import io.ktor.application.call import io.ktor.application.install +import io.ktor.application.log import io.ktor.features.CallLogging import io.ktor.features.ContentNegotiation import io.ktor.features.DefaultHeaders @@ -18,34 +19,43 @@ import io.ktor.server.cio.CIO import io.ktor.server.engine.embeddedServer import org.apache.commons.math3.random.JDKRandomGenerator import ru.mipt.npm.muon.monitor.Model -import ru.mipt.npm.muon.monitor.sim.UniformTrackGenerator +import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator import ru.mipt.npm.muon.monitor.sim.simulateOne +import java.awt.Desktop import java.io.File +import java.net.URI +private val generator = Cos2TrackGenerator(JDKRandomGenerator(223)) fun Application.module() { val currentDir = File(".").absoluteFile environment.log.info("Current directory: $currentDir") - val generator = UniformTrackGenerator(JDKRandomGenerator(223)) + install(DefaultHeaders) install(CallLogging) - install(ContentNegotiation){ + install(ContentNegotiation) { serialization(json = Visual3DPlugin.json) } install(Routing) { - get("/next") { - call.respond(generator.simulateOne()) + get("/event") { + val event = generator.simulateOne() + call.respond(event) } - get("/geometry"){ + get("/geometry") { call.respond(Model.buildGeometry()) } static("/") { resources() } } + try { + Desktop.getDesktop().browse(URI("http://localhost:8080/index.html")) + } catch (ex: Exception) { + log.error("Failed to launch browser", ex) + } } fun main() { - embeddedServer(CIO, 8080,host = "localhost", module = Application::module).start(wait = true) + embeddedServer(CIO, 8080, host = "localhost", module = Application::module).start(wait = true) } \ No newline at end of file diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt index db673b97..488140de 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt @@ -54,8 +54,8 @@ fun Vector3D.toPoint() = Point3D(x, y, z) fun Line.toPoints(): List { val basePoint = basePlane.intersection(this) - val bottom = basePoint.subtract(300.0, direction) - val top = basePoint.add(300.0, direction) + val bottom = basePoint.subtract(2000.0, direction) + val top = basePoint.add(2000.0, direction) return listOf(bottom.toPoint(), top.toPoint()) } diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt index 7a4f5581..01ff5d3b 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt @@ -11,13 +11,14 @@ import java.util.* // minimal track length in detector -val MINIMAL_TRACK_LENGTH = 10.0 +internal const val MINIMAL_TRACK_LENGTH = 10.0 private val layerCache = HashMap() -fun findLayer(z: Double): Plane = layerCache.getOrPut(z){ - Plane(Vector3D(0.0, 0.0, z), Vector3D(0.0, 0.0, 1.0), +fun findLayer(z: Double): Plane = layerCache.getOrPut(z) { + Plane( + Vector3D(0.0, 0.0, z), Vector3D(0.0, 0.0, 1.0), Monitor.GEOMETRY_TOLERANCE ) } @@ -34,7 +35,7 @@ fun readEffs(): Map { index = 0 } else if (trimmed.isNotEmpty()) { val eff = trimmed.split(Regex("\\s+"))[1].toDouble() - effMap.put("SC${detectorName}_${index}", eff) + effMap["SC${detectorName}_${index}"] = eff index++ } } @@ -42,8 +43,8 @@ fun readEffs(): Map { } -fun buildEventByTrack(track: Line, hitResolver: (Line) -> Collection = defaultHitResolver): Event { - return Event(track.toPoints(), hitResolver(track).map { it.name }) +fun buildEventByTrack(index: Int, track: Line, hitResolver: (Line) -> Collection = defaultHitResolver): Event { + return Event(index, track.toPoints(), hitResolver(track).map { it.name }) } val defaultHitResolver: (Line) -> Collection = { track: Line -> diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/simulation.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/simulation.kt index 86a9152a..6019a94a 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/simulation.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/simulation.kt @@ -4,14 +4,18 @@ import org.apache.commons.math3.geometry.euclidean.threed.Line import org.apache.commons.math3.random.RandomGenerator import ru.mipt.npm.muon.monitor.Event import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE +import kotlin.math.acos +import kotlin.math.pow +import kotlin.math.sin +private var counter = 0 /** * Simulate single track and returns corresponding event */ fun TrackGenerator.simulateOne(): Event { val track = generate() - return buildEventByTrack(track) + return buildEventByTrack(counter++, track) } interface TrackGenerator { @@ -22,13 +26,17 @@ interface TrackGenerator { /** * A uniform generator with track bases distributed in square in central plane, uniform phi and cos theta */ -class UniformTrackGenerator(override val rnd: RandomGenerator, val maxX: Double = 4 * PIXEL_XY_SIZE, val maxY: Double = 4 * PIXEL_XY_SIZE) : +class UniformTrackGenerator( + override val rnd: RandomGenerator, + val maxX: Double = 4 * PIXEL_XY_SIZE, + val maxY: Double = 4 * PIXEL_XY_SIZE +) : TrackGenerator { override fun generate(): Line { val x = (1 - rnd.nextDouble() * 2.0) * maxX val y = (1 - rnd.nextDouble() * 2.0) * maxY val phi = (1 - rnd.nextDouble() * 2.0) * Math.PI - val theta = Math.PI / 2 - Math.acos(rnd.nextDouble()) + val theta = Math.PI / 2 - acos(rnd.nextDouble()) return makeTrack(x, y, theta, phi) } } @@ -63,10 +71,10 @@ class Cos2TrackGenerator( for (i in 0..500) { - val thetaCandidate = Math.acos(rnd.nextDouble()) + val thetaCandidate = acos(rnd.nextDouble()) val u = rnd.nextDouble() - val sin = Math.sin(thetaCandidate) - if (u < Math.pow(sin, power) / sin) { + val sin = sin(thetaCandidate) + if (u < sin.pow(power) / sin) { return makeTrack(x, y, thetaCandidate, phi) } }