Use UShort for event amplitude
This commit is contained in:
parent
0ba8fea70f
commit
35a29e983e
@ -26,6 +26,7 @@ import hep.dataforge.workspace.tasks.TaskModel
|
|||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
@ -43,8 +44,8 @@ class WorkspaceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
fun testCaching() {
|
fun testCaching() {
|
||||||
counter.set(0)
|
|
||||||
wsp.context[CachePlugin::class.java]?.invalidate()
|
wsp.context[CachePlugin::class.java]?.invalidate()
|
||||||
val res1 = wsp.runTask("test2", Meta.empty())
|
val res1 = wsp.runTask("test2", Meta.empty())
|
||||||
val res2 = wsp.runTask("test2", Meta.empty())
|
val res2 = wsp.runTask("test2", Meta.empty())
|
||||||
@ -70,7 +71,6 @@ class WorkspaceTest {
|
|||||||
@BeforeClass
|
@BeforeClass
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun setup() {
|
fun setup() {
|
||||||
counter.set(0)
|
|
||||||
val context = Global.getContext("TEST").apply {
|
val context = Global.getContext("TEST").apply {
|
||||||
load(CachePlugin::class.java, MetaBuilder().setValue("fileCache.enabled", false))
|
load(CachePlugin::class.java, MetaBuilder().setValue("fileCache.enabled", false))
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import java.time.Duration
|
|||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
open class OrphanNumassEvent(val amplitude: Short, val timeOffset: Long) : Serializable, Comparable<OrphanNumassEvent> {
|
open class OrphanNumassEvent(val amplitude: UShort, val timeOffset: Long) : Serializable, Comparable<OrphanNumassEvent> {
|
||||||
operator fun component1() = amplitude
|
operator fun component1() = amplitude
|
||||||
operator fun component2() = timeOffset
|
operator fun component2() = timeOffset
|
||||||
|
|
||||||
@ -45,13 +45,13 @@ open class OrphanNumassEvent(val amplitude: Short, val timeOffset: Long) : Seria
|
|||||||
* @property owner an owner block for this event
|
* @property owner an owner block for this event
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class NumassEvent(amplitude: Short, timeOffset: Long, val owner: NumassBlock) : OrphanNumassEvent(amplitude, timeOffset), Serializable {
|
class NumassEvent(amplitude: UShort, timeOffset: Long, val owner: NumassBlock) : OrphanNumassEvent(amplitude, timeOffset), Serializable {
|
||||||
|
|
||||||
val channel: Int
|
val channel: Int
|
||||||
get() = owner.channel
|
get() = owner.channel
|
||||||
|
|
||||||
val time: Instant
|
val time: Instant
|
||||||
get() = owner.startTime.plusNanos(timeOffset)
|
get() = owner.startTime.plusNanos(timeOffset.toLong())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ class ProtoBlock(
|
|||||||
.error("The block is broken. Number of times is ${events.timesCount} and number of amplitudes is ${events.amplitudesCount}")
|
.error("The block is broken. Number of times is ${events.timesCount} and number of amplitudes is ${events.amplitudesCount}")
|
||||||
}
|
}
|
||||||
IntStream.range(0, events.timesCount)
|
IntStream.range(0, events.timesCount)
|
||||||
.mapToObj { i -> NumassEvent(events.getAmplitudes(i).toShort(), events.getTimes(i), this) }
|
.mapToObj { i -> NumassEvent(events.getAmplitudes(i).toUShort(), events.getTimes(i), this) }
|
||||||
} else {
|
} else {
|
||||||
Stream.empty()
|
Stream.empty()
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ class ChernovProcessor(
|
|||||||
|
|
||||||
val timeInTicks = (pos + buffer.position() - 1)
|
val timeInTicks = (pos + buffer.position() - 1)
|
||||||
|
|
||||||
val event = OrphanNumassEvent(amp.toInt().toShort(), (timeInTicks * tickSize).toLong())
|
val event = OrphanNumassEvent(amp.toInt().toUShort(), (timeInTicks * tickSize).toLong())
|
||||||
yield(event)
|
yield(event)
|
||||||
|
|
||||||
//subtracting event from buffer copy
|
//subtracting event from buffer copy
|
||||||
|
@ -90,13 +90,13 @@ object NumassDataUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun NumassBlock.transformChain(transform: (NumassEvent, NumassEvent) -> Pair<Short, Long>?): NumassBlock {
|
suspend fun NumassBlock.transformChain(transform: (NumassEvent, NumassEvent) -> OrphanNumassEvent?): NumassBlock {
|
||||||
return SimpleBlock.produce(this.startTime, this.length) {
|
return SimpleBlock.produce(this.startTime, this.length) {
|
||||||
this.events.asSequence()
|
this.events.asSequence()
|
||||||
.sortedBy { it.timeOffset }
|
.sortedBy { it.timeOffset }
|
||||||
.zipWithNext(transform)
|
.zipWithNext(transform)
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
.map { OrphanNumassEvent(it.first, it.second) }.asIterable()
|
.asIterable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,15 +98,15 @@ open class TimeAnalyzer(processor: SignalProcessor? = null) : AbstractAnalyzer(p
|
|||||||
.forEach { pair ->
|
.forEach { pair ->
|
||||||
totalN.incrementAndGet()
|
totalN.incrementAndGet()
|
||||||
//TODO add progress listener here
|
//TODO add progress listener here
|
||||||
totalT.addAndGet(pair.second)
|
totalT.addAndGet(pair.second.toLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalN.toInt() == 0) {
|
if (totalN.toInt() == 0) {
|
||||||
error("Zero number of intervals")
|
error("Zero number of intervals")
|
||||||
}
|
}
|
||||||
|
|
||||||
val countRate =
|
val countRate = 1e6 * totalN.get() / (totalT.get() / 1000 - t0.toLong() * totalN.get() / 1000)
|
||||||
1e6 * totalN.get() / (totalT.get() / 1000 - t0 * totalN.get() / 1000)//1e9 / (totalT.get() / totalN.get() - t0);
|
//1e9 / (totalT.get() / totalN.get() - t0);
|
||||||
val countRateError = countRate / sqrt(totalN.get().toDouble())
|
val countRateError = countRate / sqrt(totalN.get().toDouble())
|
||||||
val length = totalT.get() / 1e9
|
val length = totalT.get() / 1e9
|
||||||
val count = (length * countRate).toLong()
|
val count = (length * countRate).toLong()
|
||||||
@ -252,7 +252,7 @@ open class TimeAnalyzer(processor: SignalProcessor? = null) : AbstractAnalyzer(p
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
override fun getEvents(block: NumassBlock, meta: Meta): List<NumassEvent> {
|
override fun getEvents(block: NumassBlock, meta: Meta): List<NumassEvent> {
|
||||||
val t0 = getT0(block, meta).toLong()
|
val t0 = getT0(block, meta)
|
||||||
return getEventsWithDelay(block, meta)
|
return getEventsWithDelay(block, meta)
|
||||||
.filter { pair -> pair.second >= t0 }
|
.filter { pair -> pair.second >= t0 }
|
||||||
.map { it.first }.toList()
|
.map { it.first }.toList()
|
||||||
|
@ -182,8 +182,8 @@ constructor(override val name: String, private val path: Path, meta: Meta) : Num
|
|||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
private fun readEvent(channel: SeekableByteChannel, b: Int, timeDiv: Double): OrphanNumassEvent {
|
private fun readEvent(channel: SeekableByteChannel, b: Int, timeDiv: Double): OrphanNumassEvent {
|
||||||
val chanel: Short
|
val chanel: UShort
|
||||||
val time: Long
|
val time: ULong
|
||||||
|
|
||||||
val hb = b and 0x0f
|
val hb = b and 0x0f
|
||||||
val lab = b and 0xf0
|
val lab = b and 0xf0
|
||||||
@ -194,34 +194,34 @@ constructor(override val name: String, private val path: Path, meta: Meta) : Num
|
|||||||
time = readTime(channel)
|
time = readTime(channel)
|
||||||
}
|
}
|
||||||
0x20 -> {
|
0x20 -> {
|
||||||
chanel = 0
|
chanel = 0U
|
||||||
time = readTime(channel)
|
time = readTime(channel)
|
||||||
}
|
}
|
||||||
0x40 -> {
|
0x40 -> {
|
||||||
time = 0
|
time = 0U
|
||||||
chanel = readChanel(channel, hb)
|
chanel = readChanel(channel, hb)
|
||||||
}
|
}
|
||||||
0x80 -> {
|
0x80 -> {
|
||||||
time = 0
|
time = 0U
|
||||||
chanel = 0
|
chanel = 0U
|
||||||
}
|
}
|
||||||
else -> throw IOException("Event head expected")
|
else -> throw IOException("Event head expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
return OrphanNumassEvent(chanel, (time / timeDiv).toLong())
|
return OrphanNumassEvent(chanel, (time.toDouble() / timeDiv).toLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
private fun readChanel(channel: SeekableByteChannel, hb: Int): Short {
|
private fun readChanel(channel: SeekableByteChannel, hb: Int): UShort {
|
||||||
assert(hb < 127)
|
assert(hb < 127)
|
||||||
val buffer = readBlock(channel, 1)
|
val buffer = readBlock(channel, 1)
|
||||||
return (buffer.get() + 256 * hb).toShort()
|
return (buffer.get() + 256 * hb).toUShort()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
private fun readTime(channel: SeekableByteChannel): Long {
|
private fun readTime(channel: SeekableByteChannel): ULong {
|
||||||
val rx = readBlock(channel, 4)
|
val rx = readBlock(channel, 4)
|
||||||
return rx.long//rx[0] + 256 * rx[1] + 65536 * rx[2] + 256 * 65536 * rx[3];
|
return rx.long.toULong()//rx[0] + 256 * rx[1] + 65536 * rx[2] + 256 * 65536 * rx[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void skip(int length) throws IOException {
|
// private void skip(int length) throws IOException {
|
||||||
|
@ -87,7 +87,7 @@ class ClassicNumassPoint(private val envelope: Envelope) : NumassPoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun next(): NumassEvent {
|
override fun next(): NumassEvent {
|
||||||
val amp = java.lang.Short.toUnsignedInt(buffer.short).toShort()
|
val amp = buffer.short.toUShort()
|
||||||
val time = Integer.toUnsignedLong(buffer.int)
|
val time = Integer.toUnsignedLong(buffer.int)
|
||||||
val status = buffer.get() // status is ignored
|
val status = buffer.get() // status is ignored
|
||||||
return NumassEvent(amp, (time * timeCoef).toLong(), this@ClassicBlock)
|
return NumassEvent(amp, (time * timeCoef).toLong(), this@ClassicBlock)
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
package inr.numass.data
|
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
|
||||||
import hep.dataforge.grind.Grind
|
|
||||||
import hep.dataforge.maths.histogram.Histogram
|
|
||||||
import hep.dataforge.maths.histogram.UnivariateHistogram
|
|
||||||
import hep.dataforge.values.Values
|
|
||||||
import inr.numass.data.analyzers.TimeAnalyzer
|
|
||||||
import inr.numass.data.api.NumassBlock
|
|
||||||
|
|
||||||
import java.util.stream.LongStream
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by darksnake on 27-Jun-17.
|
|
||||||
*/
|
|
||||||
@CompileStatic
|
|
||||||
class PointAnalyzer {
|
|
||||||
|
|
||||||
static final TimeAnalyzer analyzer = new TimeAnalyzer();
|
|
||||||
|
|
||||||
static Histogram histogram(NumassBlock point, int loChannel = 0, int upChannel = 10000, double binSize = 0.5, int binNum = 500) {
|
|
||||||
return UnivariateHistogram.buildUniform(0d, binSize * binNum, binSize)
|
|
||||||
.fill(
|
|
||||||
kotlin.streams.jdk8.StreamsKt.asStream(analyzer.getEventsWithDelay(point, Grind.buildMeta("window.lo": loChannel, "window.up": upChannel))).mapToDouble {
|
|
||||||
it.second / 1000 as double
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
static Histogram histogram(LongStream stream, double binSize = 0.5, int binNum = 500) {
|
|
||||||
return UnivariateHistogram.buildUniform(0d, binSize * binNum, binSize).fill(stream.mapToDouble {
|
|
||||||
it / 1000 as double
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static Values analyze(Map values = Collections.emptyMap(), NumassBlock block, Closure metaClosure = null) {
|
|
||||||
return analyzer.analyze(block, Grind.buildMeta(values, metaClosure))
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// static class Result {
|
|
||||||
// double cr;
|
|
||||||
// double crErr;
|
|
||||||
// long num;
|
|
||||||
// double t0;
|
|
||||||
// int loChannel;
|
|
||||||
// int upChannel;
|
|
||||||
// }
|
|
||||||
}
|
|
@ -90,7 +90,7 @@ class NumassPlugin : BasicPlugin() {
|
|||||||
private fun loadMath(math: FunctionLibrary) {
|
private fun loadMath(math: FunctionLibrary) {
|
||||||
math.addBivariate("numass.trap.lowFields") { Ei, Ef -> 3.92e-5 * FastMath.exp(-(Ei - Ef) / 300.0) + 1.97e-4 - 6.818e-9 * Ei }
|
math.addBivariate("numass.trap.lowFields") { Ei, Ef -> 3.92e-5 * FastMath.exp(-(Ei - Ef) / 300.0) + 1.97e-4 - 6.818e-9 * Ei }
|
||||||
|
|
||||||
math.addBivariate("numass.trap.nominal") { Ei, Ef ->
|
math.addBivariate("numass.trap.nominal") { Ei, f ->
|
||||||
//return 1.64e-5 * FastMath.exp(-(Ei - Ef) / 300d) + 1.1e-4 - 4e-9 * Ei;
|
//return 1.64e-5 * FastMath.exp(-(Ei - Ef) / 300d) + 1.1e-4 - 4e-9 * Ei;
|
||||||
1.2e-4 - 4.5e-9 * Ei
|
1.2e-4 - 4.5e-9 * Ei
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ object TimeSpectrumAction : OneToOneAction<NumassPoint, Table>( "numass.timeSpec
|
|||||||
.fill(analyzer
|
.fill(analyzer
|
||||||
.getEventsWithDelay(input, inputMeta)
|
.getEventsWithDelay(input, inputMeta)
|
||||||
.asStream()
|
.asStream()
|
||||||
.mapToDouble { it.second / 1000.0 }
|
.mapToDouble { it.second.toDouble() / 1000.0 }
|
||||||
).asTable()
|
).asTable()
|
||||||
|
|
||||||
//.histogram(input, loChannel, upChannel, binSize, binNum).asTable();
|
//.histogram(input, loChannel, upChannel, binSize, binNum).asTable();
|
||||||
|
@ -24,7 +24,7 @@ private fun RandomGenerator.nextDeltaTime(cr: Double): Long {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun Sequence<OrphanNumassEvent>.generateBlock(start: Instant, length: Long): NumassBlock {
|
suspend fun Sequence<OrphanNumassEvent>.generateBlock(start: Instant, length: Long): NumassBlock {
|
||||||
return SimpleBlock.produce(start, Duration.ofNanos(length)) {
|
return SimpleBlock.produce(start, Duration.ofNanos(length.toLong())) {
|
||||||
takeWhile { it.timeOffset < length }.toList()
|
takeWhile { it.timeOffset < length }.toList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ private class MergingState(private val chains: List<Chain<OrphanNumassEvent>>) {
|
|||||||
* Merge event chains in ascending time order
|
* Merge event chains in ascending time order
|
||||||
*/
|
*/
|
||||||
fun List<Chain<OrphanNumassEvent>>.merge(): Chain<OrphanNumassEvent> {
|
fun List<Chain<OrphanNumassEvent>>.merge(): Chain<OrphanNumassEvent> {
|
||||||
return StatefulChain(MergingState(this), OrphanNumassEvent(0, 0)) {
|
return StatefulChain(MergingState(this), OrphanNumassEvent(0U, 0)) {
|
||||||
poll()
|
poll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,8 +64,8 @@ fun Chain<OrphanNumassEvent>.withDeadTime(deadTime: (OrphanNumassEvent) -> Long)
|
|||||||
|
|
||||||
object NumassGenerator {
|
object NumassGenerator {
|
||||||
|
|
||||||
val defaultAmplitudeGenerator: RandomGenerator.(OrphanNumassEvent?, Long) -> Short =
|
val defaultAmplitudeGenerator: RandomGenerator.(OrphanNumassEvent?, Long) -> UShort =
|
||||||
{ _, _ -> ((nextDouble() + 2.0) * 100).toInt().toShort() }
|
{ _, _ -> ((nextDouble() + 2.0) * 100).toInt().toUShort() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an event chain with fixed count rate
|
* Generate an event chain with fixed count rate
|
||||||
@ -77,7 +77,7 @@ object NumassGenerator {
|
|||||||
fun generateEvents(
|
fun generateEvents(
|
||||||
cr: Double,
|
cr: Double,
|
||||||
rnd: RandomGenerator = defaultGenerator,
|
rnd: RandomGenerator = defaultGenerator,
|
||||||
amp: RandomGenerator.(OrphanNumassEvent?, Long) -> Short = defaultAmplitudeGenerator): Chain<OrphanNumassEvent> {
|
amp: RandomGenerator.(OrphanNumassEvent?, Long) -> UShort = defaultAmplitudeGenerator): Chain<OrphanNumassEvent> {
|
||||||
return MarkovChain(OrphanNumassEvent(rnd.amp(null, 0), 0)) { event ->
|
return MarkovChain(OrphanNumassEvent(rnd.amp(null, 0), 0)) { event ->
|
||||||
val deltaT = rnd.nextDeltaTime(cr)
|
val deltaT = rnd.nextDeltaTime(cr)
|
||||||
OrphanNumassEvent(rnd.amp(event, deltaT), event.timeOffset + deltaT)
|
OrphanNumassEvent(rnd.amp(event, deltaT), event.timeOffset + deltaT)
|
||||||
@ -102,7 +102,7 @@ object NumassGenerator {
|
|||||||
bunchRate: Double,
|
bunchRate: Double,
|
||||||
bunchLength: Double,
|
bunchLength: Double,
|
||||||
rnd: RandomGenerator = defaultGenerator,
|
rnd: RandomGenerator = defaultGenerator,
|
||||||
amp: RandomGenerator.(OrphanNumassEvent?, Long) -> Short = defaultAmplitudeGenerator
|
amp: RandomGenerator.(OrphanNumassEvent?, Long) -> UShort = defaultAmplitudeGenerator
|
||||||
): Chain<OrphanNumassEvent> {
|
): Chain<OrphanNumassEvent> {
|
||||||
return StatefulChain(
|
return StatefulChain(
|
||||||
BunchState(0, 0),
|
BunchState(0, 0),
|
||||||
@ -134,6 +134,6 @@ object NumassGenerator {
|
|||||||
}
|
}
|
||||||
val distribution = EnumeratedRealDistribution(channels, values)
|
val distribution = EnumeratedRealDistribution(channels, values)
|
||||||
|
|
||||||
return generateEvents(cr, rnd) { _, _ -> distribution.sample().toInt().toShort() }
|
return generateEvents(cr, rnd) { _, _ -> distribution.sample().toInt().toUShort() }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,6 +32,7 @@ import java.time.Duration
|
|||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author [Alexander Nozik](mailto:altavir@gmail.com)
|
* @author [Alexander Nozik](mailto:altavir@gmail.com)
|
||||||
@ -43,6 +44,7 @@ class PileUpSimulator {
|
|||||||
private val pileup = ArrayList<OrphanNumassEvent>()
|
private val pileup = ArrayList<OrphanNumassEvent>()
|
||||||
private val registered = ArrayList<OrphanNumassEvent>()
|
private val registered = ArrayList<OrphanNumassEvent>()
|
||||||
private var generator: Chain<OrphanNumassEvent>
|
private var generator: Chain<OrphanNumassEvent>
|
||||||
|
|
||||||
//private double uSet = 0;
|
//private double uSet = 0;
|
||||||
private val doublePileup = AtomicInteger(0)
|
private val doublePileup = AtomicInteger(0)
|
||||||
|
|
||||||
@ -65,15 +67,15 @@ class PileUpSimulator {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
fun generated(): NumassBlock {
|
fun generated(): NumassBlock {
|
||||||
return SimpleBlock(Instant.EPOCH, Duration.ofNanos(pointLength), generated)
|
return SimpleBlock(Instant.EPOCH, Duration.ofNanos(pointLength.toLong()), generated)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registered(): NumassBlock {
|
fun registered(): NumassBlock {
|
||||||
return SimpleBlock(Instant.EPOCH, Duration.ofNanos(pointLength), registered)
|
return SimpleBlock(Instant.EPOCH, Duration.ofNanos(pointLength.toLong()), registered)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun pileup(): NumassBlock {
|
fun pileup(): NumassBlock {
|
||||||
return SimpleBlock(Instant.EPOCH, Duration.ofNanos(pointLength), pileup)
|
return SimpleBlock(Instant.EPOCH, Duration.ofNanos(pointLength.toLong()), pileup)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +84,7 @@ class PileUpSimulator {
|
|||||||
* @param x
|
* @param x
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private fun pileupChannel(x: Double, prevChanel: Short, nextChanel: Short): Short {
|
private fun pileupChannel(x: Double, prevChanel: UShort, nextChanel: UShort): UShort {
|
||||||
assert(x > 0)
|
assert(x > 0)
|
||||||
//эмпирическая формула для канала
|
//эмпирическая формула для канала
|
||||||
val coef = max(0.0, 0.99078 + 0.05098 * x - 0.45775 * x * x + 0.10962 * x * x * x)
|
val coef = max(0.0, 0.99078 + 0.05098 * x - 0.45775 * x * x + 0.10962 * x * x * x)
|
||||||
@ -90,7 +92,7 @@ class PileUpSimulator {
|
|||||||
throw Error()
|
throw Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return (prevChanel + coef * nextChanel).toInt().toShort()
|
return (prevChanel.toDouble() + coef * nextChanel.toDouble()).toInt().toUShort()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,9 +112,10 @@ class PileUpSimulator {
|
|||||||
* @param delay
|
* @param delay
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private fun nextEventRegistered(prevChanel: Short, delay: Double): Boolean {
|
private fun nextEventRegistered(prevChanel: UShort, delay: Double): Boolean {
|
||||||
val average = 6.76102 - 4.31897E-4 * prevChanel + 7.88429E-8 * prevChanel.toDouble() * prevChanel.toDouble() + 0.2
|
val average =
|
||||||
val prob = 1.0 - 1.0 / (1.0 + Math.pow(delay / average, 75.91))
|
6.76102 - 4.31897E-4 * prevChanel.toDouble() + 7.88429E-8 * prevChanel.toDouble() * prevChanel.toDouble() + 0.2
|
||||||
|
val prob = 1.0 - 1.0 / (1.0 + (delay / average).pow(75.91))
|
||||||
return random(prob)
|
return random(prob)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +127,7 @@ class PileUpSimulator {
|
|||||||
fun generate() {
|
fun generate() {
|
||||||
var next: OrphanNumassEvent
|
var next: OrphanNumassEvent
|
||||||
//var lastRegisteredTime = 0.0 // Time of DAQ closing
|
//var lastRegisteredTime = 0.0 // Time of DAQ closing
|
||||||
val last = AtomicReference<OrphanNumassEvent>(OrphanNumassEvent(0, 0))
|
val last = AtomicReference(OrphanNumassEvent(0U, 0))
|
||||||
|
|
||||||
//flag that shows that previous event was pileup
|
//flag that shows that previous event was pileup
|
||||||
var pileupFlag = false
|
var pileupFlag = false
|
||||||
@ -134,7 +137,8 @@ class PileUpSimulator {
|
|||||||
generated.add(next)
|
generated.add(next)
|
||||||
//not counting double pileups
|
//not counting double pileups
|
||||||
if (generated.size > 1) {
|
if (generated.size > 1) {
|
||||||
val delay = (next.timeOffset - last.get().timeOffset) / us //time between events in microseconds
|
val delay =
|
||||||
|
(next.timeOffset - last.get().timeOffset).toDouble() / us //time between events in microseconds
|
||||||
if (nextEventRegistered(next.amplitude, delay)) {
|
if (nextEventRegistered(next.amplitude, delay)) {
|
||||||
//just register new event
|
//just register new event
|
||||||
registered.add(next)
|
registered.add(next)
|
||||||
|
@ -23,7 +23,8 @@ fun main() {
|
|||||||
val regularChain = NumassGenerator.generateEvents(cr)
|
val regularChain = NumassGenerator.generateEvents(cr)
|
||||||
val bunchChain = NumassGenerator.generateBunches(40.0, 0.01, 5.0)
|
val bunchChain = NumassGenerator.generateBunches(40.0, 0.01, 5.0)
|
||||||
|
|
||||||
send(NumassGenerator.mergeEventChains(regularChain, bunchChain).generateBlock(start.plusNanos(it * length), length))
|
send(NumassGenerator.mergeEventChains(regularChain, bunchChain)
|
||||||
|
.generateBlock(start.plusNanos(it * length), length))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ fun main() {
|
|||||||
|
|
||||||
val sequence = TimeAnalyzer()
|
val sequence = TimeAnalyzer()
|
||||||
.getEventsWithDelay(point, metaForChainInverted)
|
.getEventsWithDelay(point, metaForChainInverted)
|
||||||
.filter { pair -> pair.second <= t0 }
|
.filter { pair -> pair.second.toDouble() <= t0 }
|
||||||
.map { it.first }
|
.map { it.first }
|
||||||
|
|
||||||
val pileupSpectrum = sequence.getAmplitudeSpectrum(point.length.toMillis().toDouble() / 1000.0).withBinning(20)
|
val pileupSpectrum = sequence.getAmplitudeSpectrum(point.length.toMillis().toDouble() / 1000.0).withBinning(20)
|
||||||
|
@ -109,7 +109,7 @@ fun main() {
|
|||||||
|
|
||||||
val sequence = TimeAnalyzer()
|
val sequence = TimeAnalyzer()
|
||||||
.getEventsWithDelay(point, metaForChainInverted)
|
.getEventsWithDelay(point, metaForChainInverted)
|
||||||
.filter { pair -> pair.second <= t0 }
|
.filter { pair -> pair.second.toDouble() <= t0 }
|
||||||
.map { it.first }
|
.map { it.first }
|
||||||
|
|
||||||
val pileupSpectrum = sequence.getAmplitudeSpectrum(point.length.toMillis().toDouble() / 1000.0).withBinning(20)
|
val pileupSpectrum = sequence.getAmplitudeSpectrum(point.length.toMillis().toDouble() / 1000.0).withBinning(20)
|
||||||
|
@ -64,7 +64,7 @@ fun main() {
|
|||||||
val histogram = SimpleHistogram(arrayOf(0.0, 0.0), arrayOf(20.0, 100.0))
|
val histogram = SimpleHistogram(arrayOf(0.0, 0.0), arrayOf(20.0, 100.0))
|
||||||
histogram.fill(
|
histogram.fill(
|
||||||
TimeAnalyzer().getEventsWithDelay(point, meta)
|
TimeAnalyzer().getEventsWithDelay(point, meta)
|
||||||
.filter { it.second <10000 }
|
.filter { it.second < 10000 }
|
||||||
.filter { it.first.channel == 0 }
|
.filter { it.first.channel == 0 }
|
||||||
.map { arrayOf(it.first.amplitude.toDouble(), it.second.toDouble()/1e3) }
|
.map { arrayOf(it.first.amplitude.toDouble(), it.second.toDouble()/1e3) }
|
||||||
.asStream()
|
.asStream()
|
||||||
|
@ -58,7 +58,7 @@ fun main() {
|
|||||||
//
|
//
|
||||||
// val time = totalT.get()
|
// val time = totalT.get()
|
||||||
|
|
||||||
println(time / 1e9)
|
println(time.toDouble() / 1e9)
|
||||||
|
|
||||||
//
|
//
|
||||||
// val cr = 80.0
|
// val cr = 80.0
|
||||||
|
@ -4,6 +4,7 @@ import hep.dataforge.context.Global
|
|||||||
import hep.dataforge.fx.output.FXOutputManager
|
import hep.dataforge.fx.output.FXOutputManager
|
||||||
import hep.dataforge.plots.jfreechart.JFreeChartPlugin
|
import hep.dataforge.plots.jfreechart.JFreeChartPlugin
|
||||||
import inr.numass.data.ProtoNumassPoint
|
import inr.numass.data.ProtoNumassPoint
|
||||||
|
import inr.numass.data.api.OrphanNumassEvent
|
||||||
import inr.numass.data.plotAmplitudeSpectrum
|
import inr.numass.data.plotAmplitudeSpectrum
|
||||||
import inr.numass.data.transformChain
|
import inr.numass.data.transformChain
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
@ -38,7 +39,7 @@ fun main() {
|
|||||||
Global.plotAmplitudeSpectrum(point.transformChain { first, second ->
|
Global.plotAmplitudeSpectrum(point.transformChain { first, second ->
|
||||||
val dt = second.timeOffset - first.timeOffset
|
val dt = second.timeOffset - first.timeOffset
|
||||||
if (second.channel == 4 && first.channel == 0 && dt > window && dt < 1000) {
|
if (second.channel == 4 && first.channel == 0 && dt > window && dt < 1000) {
|
||||||
Pair((first.amplitude + second.amplitude).toShort(), second.timeOffset)
|
OrphanNumassEvent((first.amplitude + second.amplitude).toUShort(), second.timeOffset)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -55,7 +56,7 @@ fun main() {
|
|||||||
Global.plotAmplitudeSpectrum(point.transformChain { first, second ->
|
Global.plotAmplitudeSpectrum(point.transformChain { first, second ->
|
||||||
val dt = second.timeOffset - first.timeOffset
|
val dt = second.timeOffset - first.timeOffset
|
||||||
if (second.channel == 0 && first.channel == 4 && dt > window && dt < 1000) {
|
if (second.channel == 0 && first.channel == 4 && dt > window && dt < 1000) {
|
||||||
Pair((first.amplitude + second.amplitude).toShort(), second.timeOffset)
|
OrphanNumassEvent((first.amplitude + second.amplitude).toUShort(), second.timeOffset)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ fun main() {
|
|||||||
|
|
||||||
val point: NumassPoint = set.points.first { it.index == 18 }
|
val point: NumassPoint = set.points.first { it.index == 18 }
|
||||||
(0..99).forEach { bin ->
|
(0..99).forEach { bin ->
|
||||||
val times = point.events.filter { it.amplitude > 0 }.map { it.timeOffset }.toList()
|
val times = point.events.filter { it.amplitude > 0U }.map { it.timeOffset }.toList()
|
||||||
val count = times.filter { it > bin.toDouble() / 10 * 1e9 && it < (bin + 1).toDouble() / 10 * 1e9 }.count()
|
val count = times.count { it.toDouble() > bin.toDouble() / 10 * 1e9 && it.toDouble() < (bin + 1).toDouble() / 10 * 1e9 }
|
||||||
println("${bin.toDouble() / 10.0}: $count")
|
println("${bin.toDouble() / 10.0}: $count")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package inr.numass.scripts.tristan
|
package inr.numass.scripts.tristan
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.value
|
|
||||||
import hep.dataforge.useValue
|
import hep.dataforge.useValue
|
||||||
import inr.numass.data.analyzers.TimeAnalyzer
|
import inr.numass.data.analyzers.TimeAnalyzer
|
||||||
import inr.numass.data.api.NumassBlock
|
import inr.numass.data.api.NumassBlock
|
||||||
@ -9,11 +8,11 @@ import inr.numass.data.api.NumassEvent
|
|||||||
|
|
||||||
object TristanAnalyzer : TimeAnalyzer() {
|
object TristanAnalyzer : TimeAnalyzer() {
|
||||||
override fun getEvents(block: NumassBlock, meta: Meta): List<NumassEvent> {
|
override fun getEvents(block: NumassBlock, meta: Meta): List<NumassEvent> {
|
||||||
val t0 = getT0(block, meta).toLong()
|
val t0 = getT0(block, meta)
|
||||||
val summTime = meta.getInt("summTime", 200) //time limit in nanos for event summation
|
val summTime = meta.getInt("summTime", 200) //time limit in nanos for event summation
|
||||||
var sequence = sequence {
|
var sequence = sequence {
|
||||||
var last: NumassEvent? = null
|
var last: NumassEvent? = null
|
||||||
var amp: Int = 0
|
var amp = 0U
|
||||||
getEventsWithDelay(block, meta).forEach { (event, time) ->
|
getEventsWithDelay(block, meta).forEach { (event, time) ->
|
||||||
when {
|
when {
|
||||||
last == null -> {
|
last == null -> {
|
||||||
@ -26,15 +25,15 @@ object TristanAnalyzer : TimeAnalyzer() {
|
|||||||
}
|
}
|
||||||
time > t0 -> {
|
time > t0 -> {
|
||||||
//accept new event and reset summator
|
//accept new event and reset summator
|
||||||
if (amp != 0) {
|
if (amp != 0U) {
|
||||||
//construct new event with pileup
|
//construct new event with pileup
|
||||||
yield(NumassEvent(amp.toShort(), last!!.timeOffset, last!!.owner))
|
yield(NumassEvent(amp.toUShort(), last!!.timeOffset, last!!.owner))
|
||||||
} else {
|
} else {
|
||||||
//yield event without changes if there is no pileup
|
//yield event without changes if there is no pileup
|
||||||
yield(last!!)
|
yield(last!!)
|
||||||
}
|
}
|
||||||
last = event
|
last = event
|
||||||
amp = event.amplitude.toInt()
|
amp = event.amplitude.toUInt()
|
||||||
}
|
}
|
||||||
//else ignore event
|
//else ignore event
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user