A lot of minor fixes. Moving some code to kotlin

This commit is contained in:
Alexander Nozik 2017-12-20 19:26:03 +03:00
parent c6b928face
commit 01b3da3a91
9 changed files with 214 additions and 147 deletions

View File

@ -21,9 +21,9 @@ allprojects{
} }
dependencies{ dependencies{
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:1.2.10"
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.10" compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.10"
compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: '1.2.10' compile "org.jetbrains.kotlin:kotlin-reflect:1.2.10"
testCompile group: 'junit', name: 'junit', version: '4.+'
} }

View File

@ -7,7 +7,7 @@ import hep.dataforge.grind.GrindShell
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import inr.numass.NumassPlugin import inr.numass.NumassPlugin
import inr.numass.actions.TimeAnalyzerAction import inr.numass.actions.TimeAnalyzerAction
import inr.numass.data.SimpleChainGenerator import inr.numass.data.GeneratorKt
import inr.numass.data.api.SimpleNumassPoint import inr.numass.data.api.SimpleNumassPoint
import org.apache.commons.math3.random.JDKRandomGenerator import org.apache.commons.math3.random.JDKRandomGenerator
@ -32,8 +32,8 @@ new GrindShell(ctx).eval {
def blocks = (1..num).collect { def blocks = (1..num).collect {
def generator = new SimpleChainGenerator(cr, new JDKRandomGenerator(), { 1000 }) def chain = GeneratorKt.buildSimpleEventChain(cr, new JDKRandomGenerator(),{10000})
generator.generateBlock(Instant.now().plusNanos(it * length), length) { prev, next -> next.timeOffset - prev.timeOffset > dt * 1000 } GeneratorKt.generateBlock(Instant.now().plusNanos(it * length), length, chain)
} }
def point = new SimpleNumassPoint(10000, blocks) def point = new SimpleNumassPoint(10000, blocks)

View File

@ -281,6 +281,6 @@ class NumassPlugin : BasicPlugin() {
fun displayJFreeChart(title: String, width: Double = 800.0, height: Double = 600.0, meta: Meta = Meta.empty()): JFreeChartFrame { fun displayJFreeChart(title: String, width: Double = 800.0, height: Double = 600.0, meta: Meta = Meta.empty()): JFreeChartFrame {
val frame = JFreeChartFrame(meta) val frame = JFreeChartFrame(meta)
frame.configureValue("title", title) frame.configureValue("title", title)
FXPlugin().apply { startGlobal() }.display (PlotContainer(frame)) FXPlugin().apply { startGlobal() }.display(PlotContainer(frame), width, height)
return frame return frame
} }

View File

@ -1,114 +0,0 @@
package inr.numass.data
import inr.numass.data.api.NumassBlock
import inr.numass.data.api.NumassEvent
import inr.numass.data.api.SimpleBlock
import org.apache.commons.math3.random.JDKRandomGenerator
import org.apache.commons.math3.random.RandomGenerator
import java.time.Duration
import java.time.Instant
import java.util.*
import kotlin.collections.ArrayList
interface ChainGenerator {
fun next(event: NumassEvent?): NumassEvent
fun generateBlock(start: Instant, length: Long, filter: (NumassEvent, NumassEvent) -> Boolean = { _, _ -> true }): NumassBlock {
val events = ArrayList<NumassEvent>()
var event = next(null)
events.add(event)
while (event.timeOffset < length) {
val nextEvent = next(event)
if (filter(event, nextEvent)) {
event = nextEvent
if (event.timeOffset < length) {
events.add(event)
}
}
}
return SimpleBlock(start, Duration.ofNanos(length), events)
}
}
private fun RandomGenerator.nextExp(mean: Double): Double {
return -mean * Math.log(1 - nextDouble())
}
private fun RandomGenerator.nextDeltaTime(cr: Double): Long {
return (nextExp(1.0 / cr) * 1e9).toLong()
}
class SimpleChainGenerator(
val cr: Double,
private val rnd: RandomGenerator = JDKRandomGenerator(),
private val amp: RandomGenerator.(NumassEvent?, Long) -> Short = { _, _ -> ((nextDouble() + 2.0) * 100).toShort() }
) : ChainGenerator {
override fun next(event: NumassEvent?): NumassEvent {
return if (event == null) {
NumassEvent(rnd.amp(null, 0), Instant.EPOCH, 0)
} else {
val deltaT = rnd.nextDeltaTime(cr)
NumassEvent(rnd.amp(event, deltaT), event.blockTime, event.timeOffset + deltaT)
}
}
}
class BunchGenerator(
private val cr: Double,
private val bunchRate: Double,
private val bunchLength: RandomGenerator.() -> Long,
private val rnd: RandomGenerator = JDKRandomGenerator(),
private val amp: RandomGenerator.(NumassEvent?, Long) -> Short = { _, _ -> ((nextDouble() + 2.0) * 100).toShort() }
) : ChainGenerator {
private val internalGenerator = SimpleChainGenerator(cr, rnd, amp)
var bunchStart: Long = 0
var bunchEnd: Long = 0
override fun next(event: NumassEvent?): NumassEvent {
if (event?.timeOffset ?: 0 >= bunchEnd) {
bunchStart = bunchEnd + rnd.nextExp(bunchRate).toLong()
bunchEnd = bunchStart + rnd.bunchLength()
return NumassEvent(rnd.amp(null, 0), Instant.EPOCH, bunchStart)
} else {
return internalGenerator.next(event)
}
}
override fun generateBlock(start: Instant, length: Long, filter: (NumassEvent, NumassEvent) -> Boolean): NumassBlock {
bunchStart = 0
bunchEnd = 0
return super.generateBlock(start, length, filter)
}
}
class MergingGenerator(private vararg val generators: ChainGenerator) : ChainGenerator {
private val waiting: TreeSet<Pair<ChainGenerator, NumassEvent>> = TreeSet(Comparator.comparing<Pair<ChainGenerator, NumassEvent>, Long> { it.second.timeOffset })
init {
generators.forEach { generator ->
waiting.add(Pair(generator, generator.next(null)))
}
}
override fun next(event: NumassEvent?): NumassEvent {
val pair = waiting.first()
waiting.remove(pair)
waiting.add(Pair(pair.first, pair.first.next(pair.second)))
return pair.second
}
override fun generateBlock(start: Instant, length: Long, filter: (NumassEvent, NumassEvent) -> Boolean): NumassBlock {
generators.forEach { generator ->
waiting.add(Pair(generator, generator.next(null)))
}
return super.generateBlock(start, length, filter)
}
}

View File

@ -0,0 +1,186 @@
package inr.numass.data
import hep.dataforge.maths.chain.Chain
import hep.dataforge.maths.chain.MarkovChain
import hep.dataforge.maths.chain.StatefulChain
import inr.numass.data.api.NumassBlock
import inr.numass.data.api.NumassEvent
import inr.numass.data.api.SimpleBlock
import org.apache.commons.math3.random.JDKRandomGenerator
import org.apache.commons.math3.random.RandomGenerator
import java.time.Duration
import java.time.Instant
private fun RandomGenerator.nextExp(mean: Double): Double {
return -mean * Math.log(1 - nextDouble())
}
private fun RandomGenerator.nextDeltaTime(cr: Double): Long {
return (nextExp(1.0 / cr) * 1e9).toLong()
}
fun generateBlock(start: Instant, length: Long, chain: Chain<NumassEvent>): NumassBlock {
val events = chain.asSequence().takeWhile { it.timeOffset < length }.toList()
return SimpleBlock(start, Duration.ofNanos(length), events)
}
internal val defaultGenerator = JDKRandomGenerator()
internal val defaultAmplitudeGenerator: RandomGenerator.(NumassEvent?, Long) -> Short = { _, _ -> ((nextDouble() + 2.0) * 100).toShort() }
fun buildSimpleEventChain(
cr: Double,
rnd: RandomGenerator = defaultGenerator,
amp: RandomGenerator.(NumassEvent?, Long) -> Short = defaultAmplitudeGenerator): Chain<NumassEvent> {
return MarkovChain(NumassEvent(rnd.amp(null, 0), Instant.now(), 0)) { event ->
val deltaT = rnd.nextDeltaTime(cr)
NumassEvent(rnd.amp(event, deltaT), event.blockTime, event.timeOffset + deltaT)
}
}
private data class BunchState(var bunchStart: Long = 0, var bunchEnd: Long = 0)
/**
* The chain of bunched events
* @param cr count rate of events inside bunch
* @param bunchRate number of bunches per second
* @param bunchLength the length of bunch
*/
fun buildBunchChain(
cr: Double,
bunchRate: Double,
bunchLength: Double,
rnd: RandomGenerator = defaultGenerator,
amp: RandomGenerator.(NumassEvent?, Long) -> Short = defaultAmplitudeGenerator
): Chain<NumassEvent> {
return StatefulChain(
BunchState(0, 0),
NumassEvent(rnd.amp(null, 0), Instant.now(), 0)) { event ->
if (event.timeOffset >= bunchEnd) {
bunchStart = bunchEnd + (rnd.nextDeltaTime(bunchRate)).toLong()
bunchEnd = bunchStart + (bunchLength*1e9).toLong()
NumassEvent(rnd.amp(null, 0), Instant.EPOCH, bunchStart)
} else {
val deltaT = rnd.nextDeltaTime(cr)
NumassEvent(rnd.amp(event, deltaT), event.blockTime, event.timeOffset + deltaT)
}
}
}
private class MergingState(private val chains: List<Chain<NumassEvent>>) {
suspend fun poll(): NumassEvent {
val next = chains.minBy { it.value.timeOffset } ?: chains.first()
val res = next.value
next.next()
return res
}
}
fun mergeEventChains(vararg chains: Chain<NumassEvent>): Chain<NumassEvent> {
return StatefulChain(MergingState(listOf(*chains)),NumassEvent(0, Instant.now(), 0)){
poll()
}
}
//
//
///**
// * @param S - intermediate state of generator
// */
//abstract class ChainGenerator<S> {
//
// protected abstract fun next(event: NumassEvent?, state: S = buildState()): NumassEvent
//
// fun buildSequence(): Sequence<NumassEvent> {
// val state = buildState()
// return generateSequence(seed = null) { event: NumassEvent? ->
// next(event, state)
// }
// }
//
// protected abstract fun buildState(): S
//
// fun generateBlock(start: Instant, length: Long): NumassBlock {
// val events = buildSequence().takeWhile { it.timeOffset < length }.toList()
// return SimpleBlock(start, Duration.ofNanos(length), events)
// }
//}
//
//
//class SimpleChainGenerator(
// val cr: Double,
// private val rnd: RandomGenerator = JDKRandomGenerator(),
// private val amp: RandomGenerator.(NumassEvent?, Long) -> Short = { _, _ -> ((nextDouble() + 2.0) * 100).toShort() }
//) : ChainGenerator<Unit>() {
//
// override fun buildState() {
// return Unit
// }
//
// override fun next(event: NumassEvent?, state: Unit): NumassEvent {
// return if (event == null) {
// NumassEvent(rnd.amp(null, 0), Instant.EPOCH, 0)
// } else {
// val deltaT = rnd.nextDeltaTime(cr)
// NumassEvent(rnd.amp(event, deltaT), event.blockTime, event.timeOffset + deltaT)
// }
// }
//
// fun next(event: NumassEvent?): NumassEvent {
// return next(event, Unit)
// }
//}
//
//class BunchGenerator(
// private val cr: Double,
// private val bunchRate: Double,
// private val bunchLength: RandomGenerator.() -> Long,
// private val rnd: RandomGenerator = JDKRandomGenerator(),
// private val amp: RandomGenerator.(NumassEvent?, Long) -> Short = { _, _ -> ((nextDouble() + 2.0) * 100).toShort() }
//) : ChainGenerator<BunchGenerator.BunchState>() {
//
// private val internalGenerator = SimpleChainGenerator(cr, rnd, amp)
//
// class BunchState(var bunchStart: Long = 0, var bunchEnd: Long = 0)
//
// override fun next(event: NumassEvent?, state: BunchState): NumassEvent {
// if (event?.timeOffset ?: 0 >= state.bunchEnd) {
// state.bunchStart = state.bunchEnd + (rnd.nextExp(bunchRate) * 1e9).toLong()
// state.bunchEnd = state.bunchStart + rnd.bunchLength()
// return NumassEvent(rnd.amp(null, 0), Instant.EPOCH, state.bunchStart)
// } else {
// return internalGenerator.next(event)
// }
// }
//
// override fun buildState(): BunchState {
// return BunchState(0, 0)
// }
//}
//
//
//class MergingGenerator(private vararg val generators: ChainGenerator<*>) : ChainGenerator<MergingGenerator.MergingState>() {
//
// inner class MergingState {
// val queue: PriorityQueue<Pair<Sequence<NumassEvent>, NumassEvent>> =
// PriorityQueue(Comparator.comparing<Pair<Sequence<NumassEvent>, NumassEvent>, Long> { it.second.timeOffset })
//
// init {
// generators.forEach { generator ->
// val sequence = generator.buildSequence()
// queue.add(Pair(sequence, sequence.iterator().next()))
// }
// }
// }
//
// override fun next(event: NumassEvent?, state: MergingState): NumassEvent {
// val pair = state.queue.poll()
// state.queue.add(Pair(pair.first, pair.first.iterator().next()))
// return pair.second
// }
//
// override fun buildState(): MergingState {
// return MergingState()
// }
//}
//

View File

@ -1,33 +1,27 @@
package inr.numass.scripts package inr.numass.scripts
import hep.dataforge.fx.plots.PlotManager
import hep.dataforge.kodex.buildContext
import hep.dataforge.kodex.buildMeta import hep.dataforge.kodex.buildMeta
import inr.numass.NumassPlugin
import inr.numass.data.BunchGenerator
import inr.numass.data.MergingGenerator
import inr.numass.data.SimpleChainGenerator
import inr.numass.data.analyzers.NumassAnalyzer import inr.numass.data.analyzers.NumassAnalyzer
import inr.numass.data.analyzers.SmartAnalyzer import inr.numass.data.analyzers.SmartAnalyzer
import inr.numass.data.api.SimpleNumassPoint import inr.numass.data.api.SimpleNumassPoint
import inr.numass.data.buildBunchChain
import inr.numass.data.buildSimpleEventChain
import inr.numass.data.generateBlock
import inr.numass.data.mergeEventChains
import java.time.Instant import java.time.Instant
fun main(args: Array<String>) { fun main(args: Array<String>) {
val context = buildContext("NUMASS", NumassPlugin::class.java, PlotManager::class.java)
val cr = 10.0 val cr = 10.0
val length = 30e9.toLong() val length = 1e12.toLong()
val num = 50; val num = 20;
val dt = 6.5
val regularGenerator = SimpleChainGenerator(cr)
val bunchGenerator = BunchGenerator(40.0, 0.1, { 2e9.toLong() })
val generator = MergingGenerator(regularGenerator, bunchGenerator)
val blocks = (1..num).map { val blocks = (1..num).map {
generator.generateBlock(Instant.now().plusNanos(it * length), length) val regularChain = buildSimpleEventChain(cr)
val bunchChain = buildBunchChain(20.0, 0.01, 5.0)
val generator = mergeEventChains(regularChain, bunchChain)
generateBlock(Instant.now().plusNanos(it * length), length, generator)
} }
val point = SimpleNumassPoint(10000.0, blocks) val point = SimpleNumassPoint(10000.0, blocks)
@ -36,11 +30,11 @@ fun main(args: Array<String>) {
"t0.crFraction" to 0.1 "t0.crFraction" to 0.1
} }
println("actual count rate: ${point.events.count() / point.length.seconds}") println("actual count rate: ${point.events.count().toDouble() / point.length.seconds}")
val res = SmartAnalyzer().analyze(point, meta) val res = SmartAnalyzer().analyze(point, meta)
.getDouble(NumassAnalyzer.COUNT_RATE_KEY) .getDouble(NumassAnalyzer.COUNT_RATE_KEY)
println("estimated count rate: ${res}") println("estimated count rate: $res")
} }

View File

@ -3,6 +3,7 @@ package inr.numass.viewer
import hep.dataforge.fx.dfIcon import hep.dataforge.fx.dfIcon
import hep.dataforge.fx.plots.PlotContainer import hep.dataforge.fx.plots.PlotContainer
import hep.dataforge.fx.runGoal import hep.dataforge.fx.runGoal
import hep.dataforge.fx.ui
import hep.dataforge.goals.Goal import hep.dataforge.goals.Goal
import hep.dataforge.kodex.configure import hep.dataforge.kodex.configure
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
@ -13,6 +14,7 @@ import hep.dataforge.tables.Adapters
import hep.dataforge.tables.Table import hep.dataforge.tables.Table
import inr.numass.data.analyzers.NumassAnalyzer import inr.numass.data.analyzers.NumassAnalyzer
import inr.numass.data.analyzers.SimpleAnalyzer import inr.numass.data.analyzers.SimpleAnalyzer
import inr.numass.data.analyzers.spectrumWithBinning
import inr.numass.data.api.NumassPoint import inr.numass.data.api.NumassPoint
import javafx.beans.Observable import javafx.beans.Observable
import javafx.beans.binding.DoubleBinding import javafx.beans.binding.DoubleBinding
@ -131,7 +133,7 @@ class AmplitudeView(
DataPlot.plot( DataPlot.plot(
key, key,
Adapters.buildXYAdapter(NumassAnalyzer.CHANNEL_KEY, valueAxis), Adapters.buildXYAdapter(NumassAnalyzer.CHANNEL_KEY, valueAxis),
NumassAnalyzer.spectrumWithBinning(getSpectrum(point), binning) spectrumWithBinning(getSpectrum(point), binning)
).configure { ).configure {
"connectionType" to "step" "connectionType" to "step"
"thickness" to 2 "thickness" to 2
@ -140,7 +142,7 @@ class AmplitudeView(
"showErrors" to false "showErrors" to false
"JFreeChart.cache" to true "JFreeChart.cache" to true
} }
}.ui { plot -> } ui { plot ->
frame.add(plot) frame.add(plot)
progress.invalidate() progress.invalidate()
} }

View File

@ -13,6 +13,7 @@ import hep.dataforge.tables.Adapters
import hep.dataforge.tables.Table import hep.dataforge.tables.Table
import inr.numass.data.analyzers.NumassAnalyzer import inr.numass.data.analyzers.NumassAnalyzer
import inr.numass.data.analyzers.SimpleAnalyzer import inr.numass.data.analyzers.SimpleAnalyzer
import inr.numass.data.analyzers.countInWindow
import inr.numass.data.api.NumassPoint import inr.numass.data.api.NumassPoint
import inr.numass.data.api.NumassSet import inr.numass.data.api.NumassSet
import javafx.beans.property.SimpleIntegerProperty import javafx.beans.property.SimpleIntegerProperty
@ -172,7 +173,7 @@ class SpectrumView(
runGoal("spectrumData[$name]") { runGoal("spectrumData[$name]") {
set.points.map { point -> set.points.map { point ->
val count = NumassAnalyzer.countInWindow(getSpectrum(point), loChannel.toShort(), upChannel.toShort()); val count = countInWindow(getSpectrum(point), loChannel.toShort(), upChannel.toShort());
val seconds = point.length.toMillis() / 1000.0; val seconds = point.length.toMillis() / 1000.0;
runLater { runLater {
container.progress = progress.incrementAndGet().toDouble() / totalProgress container.progress = progress.incrementAndGet().toDouble() / totalProgress

View File

@ -12,7 +12,6 @@ import inr.numass.viewer.SpectrumView
import javafx.application.Application import javafx.application.Application
import javafx.scene.image.ImageView import javafx.scene.image.ImageView
import tornadofx.* import tornadofx.*
import java.io.File
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.stream.Collectors import java.util.stream.Collectors
@ -36,8 +35,7 @@ class ViewerComponentsTest : View(title = "Numass viewer test", icon = ImageView
button("Click me!") { button("Click me!") {
action { action {
runAsync { runAsync {
val rootDir = File("D:\\Work\\Numass\\data\\2017_05\\Fill_2") val set: NumassSet = NumassStorageFactory.buildLocal(global, "D:\\Work\\Numass\\data\\2017_05\\Fill_2", true, true)
val set: NumassSet = NumassStorageFactory.buildLocal(global, rootDir, true, true)
.provide("loader::set_2", NumassSet::class.java) .provide("loader::set_2", NumassSet::class.java)
.orElseThrow { RuntimeException("err") } .orElseThrow { RuntimeException("err") }
update(set); update(set);