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 {
val kotlinVersion = "1.3.61"
val toolsVersion = "0.3.1"
val toolsVersion = "0.3.2"
kotlin("jvm") version kotlinVersion apply false
id("kotlin-dce-js") version kotlinVersion apply false

View File

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

View File

@ -33,7 +33,7 @@ class GDMLTransformer(val root: GDML) {
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
if (parent.physVolumes.isNotEmpty()) {
useStyle("opaque") {

View File

@ -6,9 +6,7 @@ import hep.dataforge.meta.get
import hep.dataforge.meta.string
import hep.dataforge.output.Renderer
import hep.dataforge.vis.common.Colors
import hep.dataforge.vis.spatial.Point3D
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.CanvasSpec
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() {
window.requestAnimationFrame {

View File

@ -15,10 +15,6 @@ val ktor_version = "1.3.0-rc"
kotlin {
jvm {
withJava()
}
js {
browser {
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 {
commonMain {
dependencies {
implementation(project(":dataforge-vis-spatial"))
}
}
jvmMain{
jvmMain {
dependencies {
implementation("org.apache.commons:commons-math3:3.6.1")
implementation("io.ktor:ktor-server-cio:$ktor_version")
implementation("io.ktor:ktor-serialization:$ktor_version")
}
}
}
}
application {
mainClassName = "ru.mipt.npm.muon.monitor.MMDemoAppKt"
mainClassName = "ru.mipt.npm.muon.monitor.server/MMServerKt"
}
configure<JavaFXOptions> {

View File

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

View File

@ -132,18 +132,20 @@ object Monitor {
* Build map for the whole monitor
*/
val detectors: Collection<SC16> by lazy {
readMonitorConfig().lineSequence().mapNotNull { line ->
if (line.startsWith(" ")) {
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;
SC16(detectorName, Point3D(x, y, z))
} else {
null
}
}.toList()
readMonitorConfig()
.lineSequence()
.mapNotNull { line ->
if (line.startsWith(" ")) {
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;
SC16(detectorName, Point3D(x, y, z))
} else {
null
}
}.toList()
}
val pixels: Collection<SC1> get() = detectors.flatMap { it.pixels }

View File

@ -1,7 +1,7 @@
package ru.mipt.npm.muon.monitor
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")
}

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.UPPER_LAYER_Z
import ru.mipt.npm.muon.monitor.SC1
import kotlin.random.Random
/**
* Auxiliary cache for [SC1] planes
@ -108,7 +109,7 @@ internal class SC1Aux(val sc: SC1, var efficiency: Double = 1.0) {
}
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.Plane
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.Monitor
import ru.mipt.npm.muon.monitor.SC1
@ -15,8 +13,6 @@ import java.util.*
// minimal track length in detector
val MINIMAL_TRACK_LENGTH = 10.0
var rnd: RandomGenerator = JDKRandomGenerator(223)
private val layerCache = HashMap<Double, Plane>()
@ -36,7 +32,7 @@ fun readEffs(): Map<String, Double> {
detectorName = trimmed.split(Regex("\\s+"))[2]
} else if (trimmed.startsWith("pixel")) {
index = 0
} else if (!trimmed.isEmpty()) {
} else if (trimmed.isNotEmpty()) {
val eff = trimmed.split(Regex("\\s+"))[1].toDouble()
effMap.put("SC${detectorName}_${index}", eff)
index++

View File

@ -1,6 +1,7 @@
package ru.mipt.npm.muon.monitor.sim
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
@ -8,19 +9,20 @@ import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE
/**
* Simulate single track and returns corresponding event
*/
fun simulateOne(trackGenerator: TrackGenerator = UniformTrackGenerator()): Event {
val track = trackGenerator.generate()
fun TrackGenerator.simulateOne(): Event {
val track = generate()
return buildEventByTrack(track)
}
interface TrackGenerator {
val rnd: RandomGenerator
fun generate(): Line
}
/**
* 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 {
override fun generate(): Line {
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(
override val rnd: RandomGenerator,
val phi: Double, val theta: Double,
val maxX: 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
*/
class Cos2TrackGenerator(
override val rnd: RandomGenerator,
val power: Double = 2.0,
val maxX: 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() }
}
}