diff --git a/numass-core/src/main/java/inr/numass/data/analyzers/TimeAnalyzer.java b/numass-core/src/main/java/inr/numass/data/analyzers/TimeAnalyzer.java index 682dc712..7eadcfb8 100644 --- a/numass-core/src/main/java/inr/numass/data/analyzers/TimeAnalyzer.java +++ b/numass-core/src/main/java/inr/numass/data/analyzers/TimeAnalyzer.java @@ -103,14 +103,17 @@ public class TimeAnalyzer extends AbstractAnalyzer { return v1; } + + double t1 = v1.getDouble(LENGTH_KEY); + double t2 = v2.getDouble(LENGTH_KEY); double cr1 = v1.getDouble(COUNT_RATE_KEY); double cr2 = v2.getDouble(COUNT_RATE_KEY); - double w1 = Math.pow(v1.getDouble(COUNT_RATE_ERROR_KEY), -2); - double w2 = Math.pow(v2.getDouble(COUNT_RATE_ERROR_KEY), -2); + double err1 = v1.getDouble(COUNT_RATE_ERROR_KEY); + double err2 = v2.getDouble(COUNT_RATE_ERROR_KEY); - double countRate = (cr1 * w1 + cr2 * w2) / (1d * w1 + 1d * w2); + double countRate = (t1 * cr1 + t2 * cr2) / (t1 + t2); - double countRateErr = Math.sqrt(1d / (w1 + w2)); + double countRateErr = Math.sqrt(Math.pow(t1 * err1 / (t1 + t2), 2) + Math.pow(t2 * err1 / (t1 + t2), 2)); return ValueMap.of(NAME_LIST, @@ -141,7 +144,7 @@ public class TimeAnalyzer extends AbstractAnalyzer { Stream eventStream = super.getEvents(block, config);//using super implementation return eventStream.map(event -> { - long res = lastEvent.get() == null ? -1L : event.getTimeOffset() - lastEvent.get().getTimeOffset(); + long res = lastEvent.get() == null ? 0L : event.getTimeOffset() - lastEvent.get().getTimeOffset(); if (res < 0) { res = 0L; diff --git a/numass-main/src/main/groovy/inr/numass/scripts/times/TestAnalyzer.groovy b/numass-main/src/main/groovy/inr/numass/scripts/times/TestAnalyzer.groovy new file mode 100644 index 00000000..d57b9a77 --- /dev/null +++ b/numass-main/src/main/groovy/inr/numass/scripts/times/TestAnalyzer.groovy @@ -0,0 +1,43 @@ +package inr.numass.scripts.times + +import hep.dataforge.context.Context +import hep.dataforge.context.Global +import hep.dataforge.grind.Grind +import hep.dataforge.grind.GrindShell +import hep.dataforge.kodex.fx.plots.PlotManager +import inr.numass.NumassPlugin +import inr.numass.actions.TimeAnalyzedAction +import inr.numass.data.SimpleChainGenerator +import inr.numass.data.api.SimpleNumassPoint +import org.apache.commons.math3.random.JDKRandomGenerator + +import java.time.Instant + +/** + * Created by darksnake on 27-Jun-17. + */ + + +Context ctx = Global.instance() +ctx.pluginManager().load(PlotManager) +ctx.pluginManager().load(NumassPlugin.class) + +new GrindShell(ctx).eval { + + double cr = 15e3; + long length = 30e9; + def num = 5; + + + + def blocks = (1..num).collect { + def generator = new SimpleChainGenerator(1e4 + 1000*num, new JDKRandomGenerator(), { 1000 }) + generator.generateBlock(Instant.now().plusNanos(it * length), length) + } + + def point = new SimpleNumassPoint(10000, blocks) + + def meta = Grind.buildMeta(plotHist: false) + + new TimeAnalyzedAction().simpleRun(point, meta); +} \ No newline at end of file diff --git a/numass-main/src/main/java/inr/numass/utils/NMEventGenerator.java b/numass-main/src/main/java/inr/numass/utils/NMEventGenerator.java index 26307b47..2d225757 100644 --- a/numass-main/src/main/java/inr/numass/utils/NMEventGenerator.java +++ b/numass-main/src/main/java/inr/numass/utils/NMEventGenerator.java @@ -36,6 +36,7 @@ import static inr.numass.data.api.NumassAnalyzer.COUNT_RATE_KEY; * * @author Darksnake */ +@Deprecated public class NMEventGenerator { protected final RandomGenerator rnd; @@ -169,7 +170,7 @@ public class NMEventGenerator { } private double nextExpDecay(double mean) { - return -mean * Math.log(1 - rnd.nextDouble()); + return - mean * Math.log(1 - rnd.nextDouble()); } } diff --git a/numass-main/src/main/kotlin/inr/numass/actions/TimeAnalyzedAction.kt b/numass-main/src/main/kotlin/inr/numass/actions/TimeAnalyzedAction.kt index 0c4589bb..5b398f46 100644 --- a/numass-main/src/main/kotlin/inr/numass/actions/TimeAnalyzedAction.kt +++ b/numass-main/src/main/kotlin/inr/numass/actions/TimeAnalyzedAction.kt @@ -95,9 +95,19 @@ class TimeAnalyzedAction : OneToOneAction() { histPlot.add(histogramPlot) } - if(inputMeta.getBoolean("plotStat",true)) { + if (inputMeta.getBoolean("plotStat", true)) { - val statPlotPoints = (1..150).map { 1000 * it }.map { t -> + val statPlot = DataPlot(name).configure { + "showLine" to true + "thickness" to 4 + "title" to "${name}_${input.voltage}" + }.apply { + configure(inputMeta.getMetaOrEmpty("plot")) + } + + pm.getPlotFrame(getName(), "stat-method").add(statPlot) + + (1..100).map { 1000 * it }.map { t -> val result = analyzer.analyze(input, buildMeta { "t0" to t "window.lo" to loChannel @@ -111,22 +121,16 @@ class TimeAnalyzedAction : OneToOneAction() { 1.0 } - XYAdapter.DEFAULT_ADAPTER.buildXYDataPoint( - t / 1000.0, - result.getDouble("cr") / norm, - result.getDouble(NumassAnalyzer.COUNT_RATE_ERROR_KEY) / norm + statPlot.append( + XYAdapter.DEFAULT_ADAPTER.buildXYDataPoint( + t / 1000.0, + result.getDouble("cr") / norm, + result.getDouble(NumassAnalyzer.COUNT_RATE_ERROR_KEY) / norm + ) ) } - val statPlot = DataPlot(name).configure { - "showLine" to true - "thickness" to 4 - "title" to "${name}_${input.voltage}" - }.apply { - configure(inputMeta.getMetaOrEmpty("plot")) - }.fillData(statPlotPoints) - pm.getPlotFrame(getName(), "stat-method").add(statPlot) } return histogram; diff --git a/numass-main/src/main/kotlin/inr/numass/data/ChainGenerator.kt b/numass-main/src/main/kotlin/inr/numass/data/ChainGenerator.kt new file mode 100644 index 00000000..04cbbcd7 --- /dev/null +++ b/numass-main/src/main/kotlin/inr/numass/data/ChainGenerator.kt @@ -0,0 +1,45 @@ +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.* + +interface ChainGenerator { + + fun next(event: NumassEvent?): NumassEvent + + fun generateBlock(start: Instant, length: Long): NumassBlock { + val events = ArrayList() + var event = next(null) + while (event.timeOffset < length) { + events.add(event) + event = next(event) + } + return SimpleBlock(start, Duration.ofNanos(length), events) + } +} + +class SimpleChainGenerator(val cr: Double, private var rnd: RandomGenerator = JDKRandomGenerator(), private val amp: () -> Short = { 1 }) : ChainGenerator { + + override fun next(event: NumassEvent?): NumassEvent { + return if (event == null) { + NumassEvent(amp(), Instant.EPOCH, 0) + } else { + NumassEvent(amp(), event.blockTime, event.timeOffset + generateDeltaTime()) + } + } + + private fun nextExpDecay(mean: Double): Double { + return -mean * Math.log(1 - rnd.nextDouble()) + } + + private fun generateDeltaTime(): Long { + return (nextExpDecay(1.0 / cr) * 1e9).toLong() + } + +}