RC 0.1.0
This commit is contained in:
parent
dac794b8ca
commit
d36542ac5b
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -92,7 +92,8 @@ class ThreeCanvas(val three: ThreePlugin, val spec: CanvasSpec) : Renderer<Visua
|
||||
|
||||
override fun render(obj: VisualObject3D, meta: Meta) {
|
||||
content = obj
|
||||
scene.add(three.buildObject3D(obj))
|
||||
val object3D = three.buildObject3D(obj)
|
||||
scene.add(object3D)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ object ThreeLabelFactory : ThreeFactory<Label3D> {
|
||||
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()
|
||||
|
@ -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<PolyLine> {
|
||||
|
||||
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)
|
||||
|
@ -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<Meta, Material>()
|
||||
private val lineMaterialCache = HashMap<Meta?, Material>()
|
||||
private val lineMaterialCache = HashMap<Meta?, LineBasicMaterial>()
|
||||
|
||||
|
||||
// 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
|
||||
}
|
||||
|
@ -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() }
|
||||
|
@ -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<Object3D>) = 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)
|
||||
|
@ -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<JavaFXOptions> {
|
||||
modules("javafx.controls")
|
||||
}
|
||||
//configure<JavaFXOptions> {
|
||||
// modules("javafx.controls")
|
||||
//}
|
@ -12,9 +12,9 @@ typealias Track = List<Point3D>
|
||||
*
|
||||
*/
|
||||
@Serializable
|
||||
data class Event(val track: Track?, val hits: Collection<String>) {
|
||||
/**
|
||||
* 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<String>) {
|
||||
// /**
|
||||
// * The unique identity for given set of hits. One identity could correspond to different tracks
|
||||
// */
|
||||
// val id get() = hits.sorted().joinToString(separator = ", ", prefix = "[", postfix = "]")
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<String, Any>) {
|
||||
|
||||
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<Event>("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 ->
|
||||
|
@ -11,24 +11,19 @@
|
||||
<script type="text/javascript" src="main.bundle.js"></script>
|
||||
</head>
|
||||
<body class="testApp">
|
||||
<!--
|
||||
<div class="container" id="drop_zone" data-toggle="tooltip" data-placement="right"
|
||||
title="Для загрузки данных в текстовом формате, надо перетащить файл сюда">
|
||||
Загрузить данные
|
||||
<br/>
|
||||
(перетащить файл сюда)
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<h1>Muon monitor demo</h1>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-3" id="tree"></div>
|
||||
<div class="col-lg-3">
|
||||
<div class="row" id ="settings"></div>
|
||||
<div class="row" id ="tree"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="row" id="settings"></div>
|
||||
<div class="row" id="canvas"></div>
|
||||
<div class="container" id = "canvas"></div>
|
||||
</div>
|
||||
<div class="col-lg-3" id="editor"></div>
|
||||
</div>
|
||||
|
@ -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)
|
||||
}
|
@ -54,8 +54,8 @@ fun Vector3D.toPoint() = Point3D(x, y, z)
|
||||
|
||||
fun Line.toPoints(): List<Point3D> {
|
||||
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())
|
||||
}
|
||||
|
||||
|
@ -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<Double, Plane>()
|
||||
|
||||
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<String, Double> {
|
||||
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<String, Double> {
|
||||
}
|
||||
|
||||
|
||||
fun buildEventByTrack(track: Line, hitResolver: (Line) -> Collection<SC1> = defaultHitResolver): Event {
|
||||
return Event(track.toPoints(), hitResolver(track).map { it.name })
|
||||
fun buildEventByTrack(index: Int, track: Line, hitResolver: (Line) -> Collection<SC1> = defaultHitResolver): Event {
|
||||
return Event(index, track.toPoints(), hitResolver(track).map { it.name })
|
||||
}
|
||||
|
||||
val defaultHitResolver: (Line) -> Collection<SC1> = { track: Line ->
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user