Muon monitor full-stack

This commit is contained in:
Alexander Nozik 2019-12-30 17:14:42 +03:00
parent f88c184a61
commit dac794b8ca
13 changed files with 124 additions and 36 deletions

View File

@ -4,7 +4,7 @@ val dataforgeVersion by extra("0.1.5-dev-6")
plugins { plugins {
val kotlinVersion = "1.3.61" val kotlinVersion = "1.3.61"
val toolsVersion = "0.3.1" val toolsVersion = "0.3.2"
kotlin("jvm") version kotlinVersion apply false kotlin("jvm") version kotlinVersion apply false
id("kotlin-dce-js") version kotlinVersion apply false id("kotlin-dce-js") version kotlinVersion apply false

View File

@ -26,8 +26,12 @@ kotlin {
dependencies { dependencies {
api("no.tornado:tornadofx:1.7.19") api("no.tornado:tornadofx:1.7.19")
//api("no.tornado:tornadofx-controlsfx:0.1.1") //api("no.tornado:tornadofx-controlsfx:0.1.1")
api("de.jensd:fontawesomefx-fontawesome:4.7.0-11") api("de.jensd:fontawesomefx-fontawesome:4.7.0-11"){
api("de.jensd:fontawesomefx-commons:11.0") exclude(group = "org.openjfx")
}
api("de.jensd:fontawesomefx-commons:11.0"){
exclude(group = "org.openjfx")
}
} }
} }
jsMain{ jsMain{

View File

@ -33,7 +33,7 @@ class GDMLTransformer(val root: GDML) {
var volumeAction: (GDMLGroup) -> Action = { Action.CACHE } var volumeAction: (GDMLGroup) -> Action = { Action.CACHE }
var solidConfiguration: VisualObject3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { parent, solid -> var solidConfiguration: VisualObject3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { parent, _ ->
lUnit = LUnit.CM lUnit = LUnit.CM
if (parent.physVolumes.isNotEmpty()) { if (parent.physVolumes.isNotEmpty()) {
useStyle("opaque") { useStyle("opaque") {

View File

@ -6,9 +6,7 @@ import hep.dataforge.meta.get
import hep.dataforge.meta.string import hep.dataforge.meta.string
import hep.dataforge.output.Renderer import hep.dataforge.output.Renderer
import hep.dataforge.vis.common.Colors import hep.dataforge.vis.common.Colors
import hep.dataforge.vis.spatial.Point3D
import hep.dataforge.vis.spatial.VisualObject3D import hep.dataforge.vis.spatial.VisualObject3D
import hep.dataforge.vis.spatial.specifications.AxesSpec
import hep.dataforge.vis.spatial.specifications.CameraSpec import hep.dataforge.vis.spatial.specifications.CameraSpec
import hep.dataforge.vis.spatial.specifications.CanvasSpec import hep.dataforge.vis.spatial.specifications.CanvasSpec
import hep.dataforge.vis.spatial.specifications.ControlsSpec import hep.dataforge.vis.spatial.specifications.ControlsSpec
@ -71,7 +69,7 @@ class ThreeCanvas(val three: ThreePlugin, val spec: CanvasSpec) : Renderer<Visua
} }
addControls(renderer.domElement, spec.controls ?: ControlsSpec.empty()) addControls(renderer.domElement, spec.controls)
fun animate() { fun animate() {
window.requestAnimationFrame { window.requestAnimationFrame {

View File

@ -15,10 +15,6 @@ val ktor_version = "1.3.0-rc"
kotlin { kotlin {
jvm {
withJava()
}
js { js {
browser { browser {
webpackTask { webpackTask {
@ -27,23 +23,38 @@ kotlin {
} }
} }
val installJS = tasks.getByName<Copy>("installJsDist")
jvm {
withJava()
compilations.findByName("main").apply {
tasks.getByName<ProcessResources>("jvmProcessResources") {
dependsOn(installJS)
afterEvaluate {
from(installJS.destinationDir)
}
}
}
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
implementation(project(":dataforge-vis-spatial")) implementation(project(":dataforge-vis-spatial"))
} }
} }
jvmMain{ jvmMain {
dependencies { dependencies {
implementation("org.apache.commons:commons-math3:3.6.1") implementation("org.apache.commons:commons-math3:3.6.1")
implementation("io.ktor:ktor-server-cio:$ktor_version") implementation("io.ktor:ktor-server-cio:$ktor_version")
implementation("io.ktor:ktor-serialization:$ktor_version")
} }
} }
} }
} }
application { application {
mainClassName = "ru.mipt.npm.muon.monitor.MMDemoAppKt" mainClassName = "ru.mipt.npm.muon.monitor.server/MMServerKt"
} }
configure<JavaFXOptions> { configure<JavaFXOptions> {

View File

@ -67,7 +67,7 @@ class Model {
tracks.removeAll() tracks.removeAll()
} }
fun showEvent(event: Event) { fun displayEvent(event: Event) {
events.add(event) events.add(event)
event.hits.forEach { event.hits.forEach {
highlight(it) highlight(it)
@ -76,4 +76,8 @@ class Model {
tracks.polyline(*it.toTypedArray()) tracks.polyline(*it.toTypedArray())
} }
} }
companion object {
fun buildGeometry() = Model().root
}
} }

View File

@ -132,18 +132,20 @@ object Monitor {
* Build map for the whole monitor * Build map for the whole monitor
*/ */
val detectors: Collection<SC16> by lazy { val detectors: Collection<SC16> by lazy {
readMonitorConfig().lineSequence().mapNotNull { line -> readMonitorConfig()
if (line.startsWith(" ")) { .lineSequence()
val split = line.trim().split("\\s+".toRegex()); .mapNotNull { line ->
val detectorName = split[1]; if (line.startsWith(" ")) {
val x = split[4].toDouble() - 500; val split = line.trim().split("\\s+".toRegex());
val y = split[5].toDouble() - 500; val detectorName = split[1];
val z = split[6].toDouble() - 180; val x = split[4].toDouble() - 500;
SC16(detectorName, Point3D(x, y, z)) val y = split[5].toDouble() - 500;
} else { val z = split[6].toDouble() - 180;
null SC16(detectorName, Point3D(x, y, z))
} } else {
}.toList() null
}
}.toList()
} }
val pixels: Collection<SC1> get() = detectors.flatMap { it.pixels } val pixels: Collection<SC1> get() = detectors.flatMap { it.pixels }

View File

@ -1,7 +1,7 @@
package ru.mipt.npm.muon.monitor package ru.mipt.npm.muon.monitor
actual fun readResource(path: String): String { actual fun readResource(path: String): String {
return ClassLoader.getSystemClassLoader().getResourceAsStream(path)?.readAllBytes()?.contentToString() return ClassLoader.getSystemClassLoader().getResourceAsStream(path)?.readAllBytes()?.decodeToString()
?: error("Resource '$path' not found") ?: error("Resource '$path' not found")
} }

View File

@ -0,0 +1,51 @@
package ru.mipt.npm.muon.monitor.server
import hep.dataforge.vis.spatial.Visual3DPlugin
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.application.install
import io.ktor.features.CallLogging
import io.ktor.features.ContentNegotiation
import io.ktor.features.DefaultHeaders
import io.ktor.http.content.resources
import io.ktor.http.content.static
import io.ktor.response.respond
import io.ktor.routing.Routing
import io.ktor.routing.get
import io.ktor.serialization.serialization
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.simulateOne
import java.io.File
fun Application.module() {
val currentDir = File(".").absoluteFile
environment.log.info("Current directory: $currentDir")
val generator = UniformTrackGenerator(JDKRandomGenerator(223))
install(DefaultHeaders)
install(CallLogging)
install(ContentNegotiation){
serialization(json = Visual3DPlugin.json)
}
install(Routing) {
get("/next") {
call.respond(generator.simulateOne())
}
get("/geometry"){
call.respond(Model.buildGeometry())
}
static("/") {
resources()
}
}
}
fun main() {
embeddedServer(CIO, 8080,host = "localhost", module = Application::module).start(wait = true)
}

View File

@ -9,6 +9,7 @@ import ru.mipt.npm.muon.monitor.Monitor.LOWER_LAYER_Z
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE
import ru.mipt.npm.muon.monitor.Monitor.UPPER_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.UPPER_LAYER_Z
import ru.mipt.npm.muon.monitor.SC1 import ru.mipt.npm.muon.monitor.SC1
import kotlin.random.Random
/** /**
* Auxiliary cache for [SC1] planes * Auxiliary cache for [SC1] planes
@ -108,7 +109,7 @@ internal class SC1Aux(val sc: SC1, var efficiency: Double = 1.0) {
} }
private fun eff(): Boolean { private fun eff(): Boolean {
return efficiency == 1.0 || rnd.nextDouble() < efficiency; return efficiency == 1.0 || Random.nextDouble() < efficiency;
} }
} }

View File

@ -3,8 +3,6 @@ package ru.mipt.npm.muon.monitor.sim
import org.apache.commons.math3.geometry.euclidean.threed.Line import org.apache.commons.math3.geometry.euclidean.threed.Line
import org.apache.commons.math3.geometry.euclidean.threed.Plane import org.apache.commons.math3.geometry.euclidean.threed.Plane
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D import org.apache.commons.math3.geometry.euclidean.threed.Vector3D
import org.apache.commons.math3.random.JDKRandomGenerator
import org.apache.commons.math3.random.RandomGenerator
import ru.mipt.npm.muon.monitor.Event import ru.mipt.npm.muon.monitor.Event
import ru.mipt.npm.muon.monitor.Monitor import ru.mipt.npm.muon.monitor.Monitor
import ru.mipt.npm.muon.monitor.SC1 import ru.mipt.npm.muon.monitor.SC1
@ -15,8 +13,6 @@ import java.util.*
// minimal track length in detector // minimal track length in detector
val MINIMAL_TRACK_LENGTH = 10.0 val MINIMAL_TRACK_LENGTH = 10.0
var rnd: RandomGenerator = JDKRandomGenerator(223)
private val layerCache = HashMap<Double, Plane>() private val layerCache = HashMap<Double, Plane>()
@ -36,7 +32,7 @@ fun readEffs(): Map<String, Double> {
detectorName = trimmed.split(Regex("\\s+"))[2] detectorName = trimmed.split(Regex("\\s+"))[2]
} else if (trimmed.startsWith("pixel")) { } else if (trimmed.startsWith("pixel")) {
index = 0 index = 0
} else if (!trimmed.isEmpty()) { } else if (trimmed.isNotEmpty()) {
val eff = trimmed.split(Regex("\\s+"))[1].toDouble() val eff = trimmed.split(Regex("\\s+"))[1].toDouble()
effMap.put("SC${detectorName}_${index}", eff) effMap.put("SC${detectorName}_${index}", eff)
index++ index++

View File

@ -1,6 +1,7 @@
package ru.mipt.npm.muon.monitor.sim package ru.mipt.npm.muon.monitor.sim
import org.apache.commons.math3.geometry.euclidean.threed.Line 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.Event
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE
@ -8,19 +9,20 @@ import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE
/** /**
* Simulate single track and returns corresponding event * Simulate single track and returns corresponding event
*/ */
fun simulateOne(trackGenerator: TrackGenerator = UniformTrackGenerator()): Event { fun TrackGenerator.simulateOne(): Event {
val track = trackGenerator.generate() val track = generate()
return buildEventByTrack(track) return buildEventByTrack(track)
} }
interface TrackGenerator { interface TrackGenerator {
val rnd: RandomGenerator
fun generate(): Line fun generate(): Line
} }
/** /**
* A uniform generator with track bases distributed in square in central plane, uniform phi and cos theta * A uniform generator with track bases distributed in square in central plane, uniform phi and cos theta
*/ */
class UniformTrackGenerator(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 { TrackGenerator {
override fun generate(): Line { override fun generate(): Line {
val x = (1 - rnd.nextDouble() * 2.0) * maxX val x = (1 - rnd.nextDouble() * 2.0) * maxX
@ -32,6 +34,7 @@ class UniformTrackGenerator(val maxX: Double = 4 * PIXEL_XY_SIZE, val maxY: Doub
} }
class FixedAngleGenerator( class FixedAngleGenerator(
override val rnd: RandomGenerator,
val phi: Double, val theta: Double, val phi: Double, val theta: Double,
val maxX: Double = 4 * PIXEL_XY_SIZE, val maxX: Double = 4 * PIXEL_XY_SIZE,
val maxY: Double = 4 * PIXEL_XY_SIZE val maxY: Double = 4 * PIXEL_XY_SIZE
@ -47,6 +50,7 @@ class FixedAngleGenerator(
* Generating surface distribution using accept-reject method * Generating surface distribution using accept-reject method
*/ */
class Cos2TrackGenerator( class Cos2TrackGenerator(
override val rnd: RandomGenerator,
val power: Double = 2.0, val power: Double = 2.0,
val maxX: Double = 4 * PIXEL_XY_SIZE, val maxX: Double = 4 * PIXEL_XY_SIZE,
val maxY: Double = 4 * PIXEL_XY_SIZE val maxY: Double = 4 * PIXEL_XY_SIZE

View File

@ -0,0 +1,17 @@
package ru.mipt.npm.muon.monitor
import org.junit.Test
import kotlin.test.assertTrue
class GeometryTest {
@Test
fun testLoadGeometry(){
assertTrue { readMonitorConfig().isNotBlank() }
}
@Test
fun testLoadModel(){
assertTrue { Monitor.pixels.isNotEmpty() }
}
}