Sterile neutrino model
This commit is contained in:
parent
9be30e716f
commit
a1dea9cac9
@ -13,7 +13,7 @@ allprojects {
|
||||
}
|
||||
|
||||
val dataforgeVersion by extra("0.4.0")
|
||||
val kmathVersion by extra("0.3.0-dev-9")
|
||||
val kmathVersion by extra("0.3.0-dev-10")
|
||||
|
||||
apiValidation{
|
||||
validationDisabled = true
|
||||
|
@ -3,7 +3,7 @@ package ru.inr.mass.data.api
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.nanoseconds
|
||||
import kotlin.time.DurationUnit
|
||||
|
||||
public interface ParentBlock : NumassBlock {
|
||||
|
||||
@ -26,7 +26,8 @@ public class MetaBlock(private val blocks: List<NumassBlock>) : ParentBlock {
|
||||
override val startTime: Instant
|
||||
get() = blocks.first().startTime
|
||||
|
||||
override suspend fun getLength(): Duration = blocks.sumOf { it.getLength().inNanoseconds }.nanoseconds
|
||||
override suspend fun getLength(): Duration =
|
||||
Duration.nanoseconds(blocks.sumOf { it.getLength().toDouble(DurationUnit.NANOSECONDS) })
|
||||
|
||||
override val events: Flow<NumassEvent>
|
||||
get() = flow {
|
||||
|
@ -22,6 +22,7 @@ import space.kscience.dataforge.meta.double
|
||||
import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.int
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.nanoseconds
|
||||
|
||||
/**
|
||||
@ -57,7 +58,7 @@ public interface NumassPoint : ParentBlock {
|
||||
* Get the length key of meta or calculate length as a sum of block lengths. The latter could be a bit slow
|
||||
*/
|
||||
override suspend fun getLength(): Duration =
|
||||
flowBlocks().filter { it.channel == 0 }.toList().sumOf { it.getLength().inNanoseconds }.nanoseconds
|
||||
flowBlocks().filter { it.channel == 0 }.toList().sumOf { it.getLength().toDouble(DurationUnit.NANOSECONDS) }.nanoseconds
|
||||
|
||||
/**
|
||||
* Get all events it all blocks as a single sequence
|
||||
|
@ -32,8 +32,6 @@ import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
import java.util.zip.Inflater
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.milliseconds
|
||||
import kotlin.time.nanoseconds
|
||||
|
||||
/**
|
||||
* Protobuf based numass point
|
||||
@ -67,7 +65,7 @@ internal class ProtoNumassPoint(
|
||||
} ?: Instant.DISTANT_PAST
|
||||
|
||||
override suspend fun getLength(): Duration = meta["acquisition_time"].double?.let {
|
||||
(it * 1000).toLong().milliseconds
|
||||
Duration.milliseconds(it * 1000)
|
||||
} ?: super.getLength()
|
||||
|
||||
override fun toString(): String = "ProtoNumassPoint(index = ${index}, hv = $voltage)"
|
||||
@ -130,15 +128,15 @@ public class ProtoNumassBlock(
|
||||
}
|
||||
|
||||
override suspend fun getLength(): Duration = when {
|
||||
block.length > 0 -> block.length.nanoseconds
|
||||
block.length > 0 -> Duration.nanoseconds(block.length)
|
||||
parent?.meta["acquisition_time"] != null ->
|
||||
(parent?.meta["acquisition_time"].double ?: 0.0 * 1000).milliseconds
|
||||
Duration.milliseconds((parent?.meta["acquisition_time"].double ?: 0.0 * 1000))
|
||||
else -> {
|
||||
LoggerFactory.getLogger(javaClass)
|
||||
.error("No length information on block. Trying to infer from first and last events")
|
||||
val times = runBlocking { events.map { it.timeOffset }.toList() }
|
||||
val nanos = (times.maxOrNull()!! - times.minOrNull()!!)
|
||||
nanos.nanoseconds
|
||||
Duration.nanoseconds(nanos)
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,7 +170,7 @@ public class ProtoNumassBlock(
|
||||
|
||||
override val frames: Flow<NumassFrame>
|
||||
get() {
|
||||
val tickSize = block.bin_size.nanoseconds
|
||||
val tickSize = Duration.nanoseconds(block.bin_size)
|
||||
return block.frames.asFlow().map { frame ->
|
||||
val time = startTime.plus(frame.time, DateTimeUnit.NANOSECOND)
|
||||
val frameData = frame.data_
|
||||
|
193
numass-model/src/commonMain/resources/data/FS.txt
Normal file
193
numass-model/src/commonMain/resources/data/FS.txt
Normal file
@ -0,0 +1,193 @@
|
||||
0.000 0.008
|
||||
0.097 0.005
|
||||
0.197 0.028
|
||||
0.297 0.055
|
||||
0.397 0.056
|
||||
0.497 0.218
|
||||
0.597 0.191
|
||||
0.697 0.434
|
||||
0.797 0.429
|
||||
0.897 0.688
|
||||
0.997 1.300
|
||||
1.097 1.078
|
||||
1.197 2.793
|
||||
1.297 3.715
|
||||
1.397 4.480
|
||||
1.497 7.176
|
||||
1.597 6.825
|
||||
1.697 5.171
|
||||
1.797 6.187
|
||||
1.897 5.023
|
||||
1.997 3.334
|
||||
2.097 2.239
|
||||
2.197 1.493
|
||||
2.297 1.008
|
||||
2.397 1.562
|
||||
2.647 0.940
|
||||
2.897 0.518
|
||||
3.147 0.249
|
||||
3.397 0.116
|
||||
3.647 0.055
|
||||
3.897 0.036
|
||||
4.397 0.007
|
||||
4.897 0.001
|
||||
20.881 0.003
|
||||
21.881 0.021
|
||||
22.881 0.109
|
||||
23.881 0.385
|
||||
24.881 0.973
|
||||
25.881 1.833
|
||||
26.881 2.671
|
||||
27.881 3.093
|
||||
28.881 2.913
|
||||
29.881 2.276
|
||||
30.881 1.503
|
||||
31.881 0.882
|
||||
32.881 0.727
|
||||
33.881 1.389
|
||||
34.881 2.175
|
||||
35.881 2.086
|
||||
36.881 1.310
|
||||
37.881 0.676
|
||||
38.725 0.010
|
||||
38.881 0.416
|
||||
39.881 0.370
|
||||
40.881 0.350
|
||||
41.881 0.269
|
||||
42.732 0.965
|
||||
42.881 0.166
|
||||
43.405 0.029
|
||||
43.881 0.091
|
||||
43.963 0.372
|
||||
44.147 0.128
|
||||
44.881 0.043
|
||||
45.881 0.016
|
||||
46.881 0.004
|
||||
47.913 0.129
|
||||
50.599 1.216
|
||||
52.553 0.440
|
||||
55.109 0.065
|
||||
55.852 0.154
|
||||
57.004 0.159
|
||||
58.092 0.000
|
||||
58.592 0.001
|
||||
59.092 0.003
|
||||
59.592 0.010
|
||||
60.092 0.026
|
||||
60.592 0.058
|
||||
61.092 0.126
|
||||
61.592 0.206
|
||||
62.092 0.301
|
||||
62.592 0.377
|
||||
63.092 0.418
|
||||
63.592 0.377
|
||||
64.092 0.301
|
||||
64.386 0.003
|
||||
64.592 0.206
|
||||
64.886 0.007
|
||||
65.092 0.126
|
||||
65.386 0.023
|
||||
65.592 0.058
|
||||
65.886 0.060
|
||||
66.092 0.026
|
||||
66.386 0.133
|
||||
66.592 0.010
|
||||
66.886 0.288
|
||||
67.092 0.003
|
||||
67.386 0.471
|
||||
67.592 0.001
|
||||
67.886 0.688
|
||||
68.092 0.000
|
||||
68.386 0.863
|
||||
68.886 0.956
|
||||
69.386 0.863
|
||||
69.886 0.688
|
||||
70.386 0.471
|
||||
70.886 0.288
|
||||
71.386 0.133
|
||||
71.725 0.306
|
||||
71.886 0.060
|
||||
72.386 0.023
|
||||
72.886 0.007
|
||||
73.386 0.003
|
||||
74.820 0.245
|
||||
76.169 0.088
|
||||
76.868 0.100
|
||||
77.221 0.273
|
||||
79.427 0.020
|
||||
80.865 0.238
|
||||
81.965 0.137
|
||||
83.429 0.151
|
||||
84.170 0.212
|
||||
84.218 0.112
|
||||
86.123 0.014
|
||||
87.374 0.010
|
||||
88.259 0.009
|
||||
88.876 0.013
|
||||
89.871 0.026
|
||||
90.690 0.023
|
||||
91.784 0.052
|
||||
93.247 0.178
|
||||
94.333 0.133
|
||||
96.192 0.026
|
||||
96.701 0.054
|
||||
97.543 0.023
|
||||
98.514 0.005
|
||||
98.840 0.010
|
||||
100.263 0.014
|
||||
100.784 0.003
|
||||
101.620 0.003
|
||||
102.426 0.005
|
||||
102.842 0.001
|
||||
103.170 0.001
|
||||
103.594 0.006
|
||||
104.236 0.002
|
||||
105.008 0.001
|
||||
105.799 0.002
|
||||
106.990 0.006
|
||||
108.711 0.010
|
||||
109.189 0.008
|
||||
109.975 0.007
|
||||
111.148 0.005
|
||||
112.339 0.013
|
||||
113.145 0.010
|
||||
113.882 0.005
|
||||
114.892 0.002
|
||||
115.612 0.002
|
||||
116.455 0.001
|
||||
117.594 0.005
|
||||
118.481 0.023
|
||||
119.245 0.023
|
||||
120.360 0.009
|
||||
121.764 0.013
|
||||
123.594 0.009
|
||||
124.247 0.005
|
||||
125.709 0.012
|
||||
127.715 0.003
|
||||
129.373 0.002
|
||||
130.271 0.004
|
||||
132.887 0.060
|
||||
133.402 0.025
|
||||
134.813 0.082
|
||||
135.371 0.006
|
||||
136.379 0.005
|
||||
136.916 0.003
|
||||
138.243 0.008
|
||||
139.737 0.010
|
||||
141.093 0.006
|
||||
142.461 0.047
|
||||
144.001 0.004
|
||||
144.391 0.007
|
||||
147.073 0.021
|
||||
148.311 0.015
|
||||
148.895 0.001
|
||||
150.849 0.004
|
||||
151.442 0.001
|
||||
152.854 0.000
|
||||
154.169 0.002
|
||||
156.093 0.001
|
||||
157.003 0.003
|
||||
158.134 0.003
|
||||
159.271 0.002
|
||||
162.054 0.007
|
||||
164.173 0.002
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Alexander Nozik.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ru.inr.mass.maths
|
||||
|
||||
import hep.dataforge.stat.fit.Param
|
||||
import hep.dataforge.stat.parametric.ParametricValue
|
||||
|
||||
/**
|
||||
*
|
||||
* DerivativeCalculator class.
|
||||
*
|
||||
* @author Alexander Nozik
|
||||
* @version $Id: $Id
|
||||
*/
|
||||
object DerivativeCalculator {
|
||||
private const val numPoints = 3
|
||||
|
||||
/**
|
||||
* Calculates finite differences derivative via 3 points differentiator.
|
||||
*
|
||||
* @param function a [hep.dataforge.stat.parametric.ParametricValue] object.
|
||||
* @param point a [hep.dataforge.stat.fit.ParamSet] object.
|
||||
* @param parName a [String] object.
|
||||
* @return a double.
|
||||
*/
|
||||
fun calculateDerivative(function: ParametricValue?, point: ParamSet, parName: String?): Double {
|
||||
val projection: UnivariateFunction = ParametricUtils.getNamedProjection(function, parName, point)
|
||||
val par: Param = point.getByName(parName)
|
||||
val diff =
|
||||
FiniteDifferencesDifferentiator(numPoints, par.getErr() / 2.0, par.getLowerBound(), par.getUpperBound())
|
||||
val derivative: UnivariateDifferentiableFunction = diff.differentiate(projection)
|
||||
val x = DerivativeStructure(1, 1, 0, point.getDouble(parName))
|
||||
val y: DerivativeStructure = derivative.value(x)
|
||||
return y.getPartialDerivative(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates finite differences derivative via 3 points differentiator.
|
||||
*
|
||||
* @param function a [org.apache.commons.math3.analysis.UnivariateFunction] object.
|
||||
* @param point a double.
|
||||
* @param step a double.
|
||||
* @return a double.
|
||||
*/
|
||||
fun calculateDerivative(function: UnivariateFunction?, point: Double, step: Double): Double {
|
||||
val diff = FiniteDifferencesDifferentiator(numPoints, step)
|
||||
val derivative: UnivariateDifferentiableFunction = diff.differentiate(function)
|
||||
val x = DerivativeStructure(1, 1, 0, point)
|
||||
val y: DerivativeStructure = derivative.value(x)
|
||||
return y.getPartialDerivative(1)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* providesValidDerivative.
|
||||
*
|
||||
* @param function a [hep.dataforge.stat.parametric.ParametricValue] object.
|
||||
* @param point a [hep.dataforge.stat.fit.ParamSet] object.
|
||||
* @param tolerance a double.
|
||||
* @param parName a [String] object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
fun providesValidDerivative(
|
||||
function: ParametricValue,
|
||||
point: ParamSet,
|
||||
tolerance: Double,
|
||||
parName: String?
|
||||
): Boolean {
|
||||
if (!function.providesDeriv(parName)) {
|
||||
return false
|
||||
}
|
||||
val calculatedDeriv = calculateDerivative(function, point, parName)
|
||||
val providedDeriv: Double = function.derivValue(parName, point)
|
||||
return safeRelativeDifference(calculatedDeriv, providedDeriv) <= tolerance
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns safe from (no devision by zero) relative difference between two
|
||||
* input values
|
||||
*
|
||||
* @param val1
|
||||
* @param val2
|
||||
* @return
|
||||
*/
|
||||
private fun safeRelativeDifference(val1: Double, val2: Double): Double {
|
||||
if (Precision.equals(val1, val2, Precision.EPSILON)) {
|
||||
return 0
|
||||
}
|
||||
val average: Double = Math.abs(val1 + val2) / 2
|
||||
return if (average > Precision.EPSILON) {
|
||||
Math.abs(val1 - val2) / average
|
||||
} else {
|
||||
Double.POSITIVE_INFINITY
|
||||
}
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ import space.kscience.kmath.structures.DoubleBuffer
|
||||
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public class FSS(public val ps: DoubleBuffer, public val es: DoubleBuffer) : ColumnarData<Double> {
|
||||
public class FSS(public val es: DoubleBuffer, public val ps: DoubleBuffer) : ColumnarData<Double> {
|
||||
|
||||
override val size: Int get() = ps.size
|
||||
|
||||
@ -37,5 +37,18 @@ public class FSS(public val ps: DoubleBuffer, public val es: DoubleBuffer) : Col
|
||||
public companion object {
|
||||
public val p: Symbol by symbol
|
||||
public val e: Symbol by symbol
|
||||
|
||||
public val default: FSS by lazy {
|
||||
val stream = FSS::class.java.getResourceAsStream("/data/FS.txt") ?: error("Default FS resource not found")
|
||||
stream.use { inputStream ->
|
||||
val data = inputStream.bufferedReader().lineSequence().map {
|
||||
val (e, p) = it.split("\t")
|
||||
e.toDouble() to p.toDouble()
|
||||
}.toList()
|
||||
val es = DoubleBuffer(data.size) { data[it].first }
|
||||
val ps = DoubleBuffer(data.size) { data[it].second }
|
||||
FSS(es, ps)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -167,9 +167,9 @@ public object NumassBeta : DifferentiableKernel {
|
||||
override val x: Symbol = StringSymbol("fs")
|
||||
override val y: Symbol = StringSymbol("eIn")
|
||||
|
||||
override fun invoke(x: Double, y: Double, arguments: Map<Symbol, Double>): Double {
|
||||
override fun invoke(fs: Double, eIn: Double, arguments: Map<Symbol, Double>): Double {
|
||||
val e0 = arguments.getValue(e0)
|
||||
return rootsterile(y, e0 - x, arguments)
|
||||
return rootsterile(eIn, e0 - fs, arguments)
|
||||
}
|
||||
|
||||
override fun derivativeOrNull(symbols: List<Symbol>): Kernel? = when (symbols.size) {
|
||||
@ -180,47 +180,12 @@ public object NumassBeta : DifferentiableKernel {
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
//
|
||||
// override fun getDefaultParameter(name: String): Double {
|
||||
// return when (name) {
|
||||
// "mnu2", "U2", "msterile2" -> 0.0
|
||||
// else -> super.getDefaultParameter(name)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun derivValue(parName: String, fs: Double, eIn: Double, pars: Values): Double {
|
||||
// val e0 = getParameter("E0", pars)
|
||||
// return derivRootsterile(parName, eIn, e0 - fs, pars)
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get univariate spectrum with given final state
|
||||
// */
|
||||
// fun getSpectrum(fs: Double = 0.0): ParametricFunction {
|
||||
// return BetaSpectrum(fs);
|
||||
// }
|
||||
//
|
||||
// inner class BetaSpectrum(val fs: Double) : AbstractParametricFunction(*list) {
|
||||
//
|
||||
// override fun providesDeriv(name: String): Boolean {
|
||||
// return this@NumassBeta.providesDeriv(name)
|
||||
// }
|
||||
//
|
||||
// override fun derivValue(parName: String, x: Double, set: Values): Double {
|
||||
// return this@NumassBeta.derivValue(parName, fs, x, set)
|
||||
// }
|
||||
//
|
||||
// override fun value(x: Double, set: Values): Double {
|
||||
// return this@NumassBeta.value(fs, x, set)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
private const val K: Double = 1E-23
|
||||
public val e0: Symbol by symbol
|
||||
public val mnu2: Symbol by symbol
|
||||
public val msterile2: Symbol by symbol
|
||||
public val u2: Symbol by symbol
|
||||
private const val K: Double = 1E-23
|
||||
public val e0: Symbol by symbol
|
||||
public val mnu2: Symbol by symbol
|
||||
public val msterile2: Symbol by symbol
|
||||
public val u2: Symbol by symbol
|
||||
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ public fun PiecewisePolynomial<Double>.asFunction(defaultValue: Double = 0.0): U
|
||||
* @author [Alexander Nozik](mailto:altavir@gmail.com)
|
||||
*/
|
||||
public class NumassTransmission(
|
||||
public val trapFunc: Kernel,
|
||||
private val adjustX: Boolean = false,
|
||||
public val trapFunc: Kernel = defaultTrapping,
|
||||
// private val adjustX: Boolean = false,
|
||||
) : DifferentiableKernel {
|
||||
// private val trapFunc: Kernel = if (meta.hasValue("trapping")) {
|
||||
// val trapFuncStr = meta.getString("trapping")
|
||||
@ -83,7 +83,7 @@ public class NumassTransmission(
|
||||
// }
|
||||
|
||||
//trapping part
|
||||
val trap = arguments.getOrElse(trap) { 1.0 } * trapFunc(x, y, arguments)
|
||||
val trap = arguments[trap] ?: 1.0 * trapFunc(x, y, arguments)
|
||||
return loss + trap
|
||||
}
|
||||
|
||||
@ -97,15 +97,16 @@ public class NumassTransmission(
|
||||
|
||||
|
||||
private fun getX(arguments: Map<Symbol, Double>, eIn: Double, adjustX: Boolean = false): Double {
|
||||
val thickness = arguments[thickness] ?: 0.0
|
||||
return if (adjustX) {
|
||||
//From our article
|
||||
arguments.getValue(thickness) * ln(eIn / ION_POTENTIAL) * eIn * ION_POTENTIAL / 1.9580741410115568e6
|
||||
thickness * ln(eIn / ION_POTENTIAL) * eIn * ION_POTENTIAL / 1.9580741410115568e6
|
||||
} else {
|
||||
arguments.getValue(thickness)
|
||||
thickness
|
||||
}
|
||||
}
|
||||
|
||||
private fun p0(eIn: Double, set: Map<Symbol, Double>): Double = getLossProbability(0, getX(set, eIn))
|
||||
internal fun p0(eIn: Double, set: Map<Symbol, Double>): Double = getLossProbability(0, getX(set, eIn))
|
||||
|
||||
private fun getGunLossProbabilities(X: Double): List<Double> {
|
||||
val res = ArrayList<Double>()
|
||||
@ -132,7 +133,7 @@ public class NumassTransmission(
|
||||
return res
|
||||
}
|
||||
|
||||
fun getGunZeroLossProb(x: Double): Double {
|
||||
private fun getGunZeroLossProb(x: Double): Double {
|
||||
return exp(-x)
|
||||
}
|
||||
|
||||
@ -207,9 +208,10 @@ public class NumassTransmission(
|
||||
return res
|
||||
}
|
||||
|
||||
fun getLossProbabilities(x: Double): List<Double> = lossProbCache.getOrPut(x) { calculateLossProbabilities(x) }
|
||||
private fun getLossProbabilities(x: Double): List<Double> =
|
||||
lossProbCache.getOrPut(x) { calculateLossProbabilities(x) }
|
||||
|
||||
fun getLossProbability(order: Int, X: Double): Double {
|
||||
private fun getLossProbability(order: Int, X: Double): Double {
|
||||
if (order == 0) {
|
||||
return if (X > 0) {
|
||||
1 / X * (1 - exp(-X))
|
||||
@ -225,7 +227,7 @@ public class NumassTransmission(
|
||||
}
|
||||
}
|
||||
|
||||
fun getLossValue(order: Int, Ei: Double, Ef: Double): Double {
|
||||
private fun getLossValue(order: Int, Ei: Double, Ef: Double): Double {
|
||||
return when {
|
||||
Ei - Ef < 5.0 -> 0.0
|
||||
Ei - Ef >= getMargin(order) -> 0.0
|
||||
@ -241,7 +243,7 @@ public class NumassTransmission(
|
||||
* @param Ef
|
||||
* @return
|
||||
*/
|
||||
fun getLossValue(probs: List<Double>, Ei: Double, Ef: Double): Double {
|
||||
private fun getLossValue(probs: List<Double>, Ei: Double, Ef: Double): Double {
|
||||
var sum = 0.0
|
||||
for (i in 1 until probs.size) {
|
||||
sum += probs[i] * getLossValue(i, Ei, Ef)
|
||||
@ -305,7 +307,7 @@ public class NumassTransmission(
|
||||
* @param Ef
|
||||
* @return
|
||||
*/
|
||||
fun getTotalLossValue(x: Double, Ei: Double, Ef: Double): Double {
|
||||
private fun getTotalLossValue(x: Double, Ei: Double, Ef: Double): Double {
|
||||
return if (x == 0.0) {
|
||||
0.0
|
||||
} else {
|
||||
@ -464,6 +466,11 @@ public class NumassTransmission(
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
internal val defaultTrapping: Kernel = Kernel { e, u, arguments ->
|
||||
val d = e - u
|
||||
0.99797 - 3.05346E-7 * d - 5.45738E-10 * d.pow(2.0) - 6.36105E-14 * d.pow(3.0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,24 +6,30 @@
|
||||
package inr.numass.models.sterile
|
||||
|
||||
|
||||
import ru.inr.mass.models.DifferentiableKernel
|
||||
import ru.inr.mass.models.DifferentiableSpectrum
|
||||
import ru.inr.mass.models.FSS
|
||||
import ru.inr.mass.models.Spectrum
|
||||
import space.kscience.dataforge.context.Context
|
||||
import inr.numass.models.sterile.NumassBeta.e0
|
||||
import inr.numass.models.sterile.NumassBeta.mnu2
|
||||
import inr.numass.models.sterile.NumassBeta.msterile2
|
||||
import inr.numass.models.sterile.NumassBeta.u2
|
||||
import inr.numass.models.sterile.NumassTransmission.Companion.thickness
|
||||
import inr.numass.models.sterile.NumassTransmission.Companion.trap
|
||||
import ru.inr.mass.models.*
|
||||
import space.kscience.kmath.expressions.derivative
|
||||
import space.kscience.kmath.integration.integrate
|
||||
import space.kscience.kmath.integration.value
|
||||
import space.kscience.kmath.misc.Symbol
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* @param source variables:Eo offset,Ein; parameters: "mnu2", "msterile2", "U2"
|
||||
* @param transmission variables:Ein,Eout; parameters: "A"
|
||||
* @param resolution variables:Eout,U; parameters: "X", "trap"
|
||||
*/
|
||||
class SterileNeutrinoSpectrum(
|
||||
context: Context,
|
||||
public class SterileNeutrinoSpectrum(
|
||||
public val source: DifferentiableKernel = NumassBeta,
|
||||
public val transmission: DifferentiableKernel,
|
||||
public val resolution: DifferentiableKernel,
|
||||
public val fss: FSS?
|
||||
public val transmission: DifferentiableKernel = NumassTransmission(),
|
||||
public val resolution: DifferentiableKernel = NumassResolution(),
|
||||
public val fss: FSS? = FSS.default,
|
||||
) : DifferentiableSpectrum {
|
||||
|
||||
|
||||
@ -36,111 +42,93 @@ class SterileNeutrinoSpectrum(
|
||||
//private val fast: Boolean = configuration.getBoolean("fast", true)
|
||||
|
||||
|
||||
override fun invoke(x: Double, arguments: Map<Symbol, Double>): Double {
|
||||
TODO("Not yet implemented")
|
||||
override fun invoke(u: Double, arguments: Map<Symbol, Double>): Double {
|
||||
return convolute(u, source, transRes, arguments)
|
||||
}
|
||||
|
||||
override fun derivativeOrNull(symbols: List<Symbol>): Spectrum? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun derivValue(parName: String, u: Double, set: Values): Double {
|
||||
return when (parName) {
|
||||
"U2", "msterile2", "mnu2", "E0" -> integrate(u, source.derivative(parName), transRes, set)
|
||||
"X", "trap" -> integrate(u, source, transRes.derivative(parName), set)
|
||||
else -> throw NotDefinedException()
|
||||
if (symbols.isEmpty()) return this
|
||||
return when (symbols.singleOrNull() ?: TODO("First derivatives only")) {
|
||||
u2, msterile2, mnu2, e0 -> Spectrum { u, arguments ->
|
||||
convolute(u, source.derivative(symbols), transRes, arguments)
|
||||
}
|
||||
thickness, trap -> Spectrum { u, arguments ->
|
||||
convolute(u, source, transRes.derivative(symbols), arguments)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun value(u: Double, set: Values): Double {
|
||||
return integrate(u, source, transRes, set)
|
||||
}
|
||||
|
||||
override fun providesDeriv(name: String): Boolean {
|
||||
return source.providesDeriv(name) && transmission.providesDeriv(name) && resolution.providesDeriv(name)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Direct Gauss-Legendre integration
|
||||
*
|
||||
* @param u
|
||||
* @param sourceFunction
|
||||
* @param transResFunction
|
||||
* @param set
|
||||
* @param arguments
|
||||
* @return
|
||||
*/
|
||||
private fun integrate(
|
||||
private fun convolute(
|
||||
u: Double,
|
||||
sourceFunction: DifferentiableKernel,
|
||||
transResFunction: DifferentiableKernel,
|
||||
set: Map<Symbol, Double>,
|
||||
sourceFunction: Kernel,
|
||||
transResFunction: Kernel,
|
||||
arguments: Map<Symbol, Double>,
|
||||
): Double {
|
||||
|
||||
val eMax = set.getDouble("E0") + 5.0
|
||||
val eMax = arguments.getValue(e0) + 5.0
|
||||
|
||||
if (u >= eMax) {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
val integrator: UnivariateIntegrator<*> = if (fast) {
|
||||
when {
|
||||
eMax - u < 300 -> NumassIntegrator.getFastInterator()
|
||||
eMax - u > 2000 -> NumassIntegrator.getHighDensityIntegrator()
|
||||
else -> NumassIntegrator.getDefaultIntegrator()
|
||||
}
|
||||
// val integrator: UnivariateIntegrator<*> = if (fast) {
|
||||
// when {
|
||||
// eMax - u < 300 -> getFastInterator()
|
||||
// eMax - u > 2000 -> getHighDensityIntegrator()
|
||||
// else -> getDefaultIntegrator()
|
||||
// }
|
||||
// } else {
|
||||
// getHighDensityIntegrator()
|
||||
// }
|
||||
|
||||
} else {
|
||||
NumassIntegrator.getHighDensityIntegrator()
|
||||
}
|
||||
|
||||
return integrator.integrate(u, eMax) { eIn ->
|
||||
sumByFSS(eIn, sourceFunction, set) * transResFunction.value(eIn,
|
||||
u,
|
||||
set)
|
||||
}
|
||||
return DoubleField.integrate(u..eMax) { eIn ->
|
||||
sumByFSS(eIn, sourceFunction, arguments) * transResFunction(eIn, u, arguments)
|
||||
}.value ?: error("Integration failed")
|
||||
}
|
||||
|
||||
private fun sumByFSS(eIn: Double, sourceFunction: ParametricBiFunction, set: Values): Double {
|
||||
private fun sumByFSS(eIn: Double, sourceFunction: Kernel, arguments: Map<Symbol, Double>): Double {
|
||||
return if (fss == null) {
|
||||
sourceFunction.value(0.0, eIn, set)
|
||||
sourceFunction(0.0, eIn, arguments)
|
||||
} else {
|
||||
(0 until fss.size()).sumByDouble { fss.getP(it) * sourceFunction.value(fss.getE(it), eIn, set) }
|
||||
(0 until fss.size).sumOf { fss.ps[it] * sourceFunction(fss.es[it], eIn, arguments) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private inner class TransRes : DifferentiableKernel {
|
||||
|
||||
override fun providesDeriv(name: String): Boolean {
|
||||
return true
|
||||
override fun invoke(eIn: Double, u: Double, arguments: Map<Symbol, Double>): Double {
|
||||
val p0 = NumassTransmission.p0(eIn, arguments)
|
||||
return p0 * resolution(eIn, u, arguments) + lossRes(transmission, eIn, u, arguments)
|
||||
}
|
||||
|
||||
override fun derivValue(parName: String, eIn: Double, u: Double, set: Values): Double {
|
||||
return when (parName) {
|
||||
"X" -> throw NotDefinedException()//TODO implement p0 derivative
|
||||
"trap" -> lossRes(transmission.derivative(parName), eIn, u, set)
|
||||
else -> super.derivValue(parName, eIn, u, set)
|
||||
override fun derivativeOrNull(symbols: List<Symbol>): Kernel? {
|
||||
if (symbols.isEmpty()) return this
|
||||
return when (symbols.singleOrNull() ?: TODO("First derivatives only")) {
|
||||
thickness -> null//TODO implement p0 derivative
|
||||
trap -> Kernel { eIn, u, arguments -> lossRes(transmission.derivative(symbols), eIn, u, arguments) }
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun value(eIn: Double, u: Double, set: Values): Double {
|
||||
|
||||
val p0 = LossCalculator.p0(set, eIn)
|
||||
return p0 * resolution.value(eIn, u, set) + lossRes(transmission, eIn, u, set)
|
||||
}
|
||||
|
||||
private fun lossRes(transFunc: ParametricBiFunction, eIn: Double, u: Double, set: Values): Double {
|
||||
val integrand = { eOut: Double -> transFunc.value(eIn, eOut, set) * resolution.value(eOut, u, set) }
|
||||
private fun lossRes(transFunc: Kernel, eIn: Double, u: Double, arguments: Map<Symbol, Double>): Double {
|
||||
val integrand = { eOut: Double -> transFunc(eIn, eOut, arguments) * resolution(eOut, u, arguments) }
|
||||
|
||||
val border = u + 30
|
||||
val firstPart = NumassIntegrator.getFastInterator().integrate(u, Math.min(eIn, border), integrand)
|
||||
val firstPart = DoubleField.integrate(u..min(eIn, border), function = integrand).value
|
||||
?: error("Integration failed")
|
||||
val secondPart: Double = if (eIn > border) {
|
||||
if (fast) {
|
||||
NumassIntegrator.getDefaultIntegrator().integrate(border, eIn, integrand)
|
||||
} else {
|
||||
NumassIntegrator.getHighDensityIntegrator().integrate(border, eIn, integrand)
|
||||
}
|
||||
DoubleField.integrate(border..eIn, function = integrand).value ?: error("Integration failed")
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
@ -149,9 +137,5 @@ class SterileNeutrinoSpectrum(
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val list = arrayOf("X", "trap", "E0", "mnu2", "msterile2", "U2")
|
||||
}
|
||||
|
||||
public companion object
|
||||
}
|
||||
|
@ -10,11 +10,12 @@ kotlin {
|
||||
}
|
||||
|
||||
val dataforgeVersion: String by rootProject.extra
|
||||
val plotlyVersion: String by rootProject.extra("0.4.0-dev-1")
|
||||
val plotlyVersion: String by rootProject.extra("0.4.0")
|
||||
val kmathVersion: String by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
implementation(project(":numass-data-proto"))
|
||||
implementation(project(":numass-model"))
|
||||
implementation("space.kscience:dataforge-workspace:$dataforgeVersion")
|
||||
implementation("space.kscience:plotlykt-core:$plotlyVersion")
|
||||
implementation("space.kscience:kmath-histograms:$kmathVersion")
|
||||
|
@ -0,0 +1,31 @@
|
||||
package ru.inr.mass.scripts
|
||||
|
||||
import inr.numass.models.sterile.NumassBeta.e0
|
||||
import inr.numass.models.sterile.NumassBeta.mnu2
|
||||
import inr.numass.models.sterile.NumassBeta.msterile2
|
||||
import inr.numass.models.sterile.NumassBeta.u2
|
||||
import inr.numass.models.sterile.SterileNeutrinoSpectrum
|
||||
import space.kscience.kmath.misc.Symbol
|
||||
import space.kscience.kmath.real.step
|
||||
import space.kscience.kmath.structures.asIterable
|
||||
import space.kscience.plotly.Plotly
|
||||
import space.kscience.plotly.makeFile
|
||||
import space.kscience.plotly.models.ScatterMode
|
||||
import space.kscience.plotly.scatter
|
||||
|
||||
fun main() {
|
||||
val spectrum = SterileNeutrinoSpectrum()
|
||||
val args: Map<Symbol, Double> = mapOf(
|
||||
mnu2 to 0.0,
|
||||
e0 to 18575.0,
|
||||
msterile2 to 1e6,
|
||||
u2 to 1e-2
|
||||
)
|
||||
Plotly.plot {
|
||||
scatter {
|
||||
mode = ScatterMode.lines
|
||||
x.numbers = (14000.0..18600.0 step 1.0).asIterable()
|
||||
y.numbers = x.numbers.map { spectrum(it.toDouble(), args) }
|
||||
}
|
||||
}.makeFile()
|
||||
}
|
@ -8,6 +8,7 @@ import space.kscience.dataforge.context.warn
|
||||
import space.kscience.kmath.histogram.UnivariateHistogram
|
||||
import space.kscience.kmath.histogram.center
|
||||
import space.kscience.kmath.histogram.put
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
|
||||
@ -41,6 +42,7 @@ fun Collection<NumassPoint>.spectrum(): UnivariateHistogram {
|
||||
/**
|
||||
* Re-shape the spectrum with the increased bin size and range. Throws a error if new bin is smaller than before.
|
||||
*/
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
fun UnivariateHistogram.reShape(
|
||||
binSize: Int,
|
||||
channelRange: IntRange,
|
||||
|
@ -4,7 +4,8 @@ import ru.inr.mass.data.proto.NumassProtoPlugin
|
||||
import space.kscience.dataforge.workspace.Workspace
|
||||
|
||||
val NUMASS = Workspace {
|
||||
context("NUMASS") {
|
||||
context{
|
||||
name("NUMASS")
|
||||
plugin(NumassProtoPlugin)
|
||||
}
|
||||
}
|
193
numass-workspace/src/main/resources/data/FS.txt
Normal file
193
numass-workspace/src/main/resources/data/FS.txt
Normal file
@ -0,0 +1,193 @@
|
||||
0.000 0.008
|
||||
0.097 0.005
|
||||
0.197 0.028
|
||||
0.297 0.055
|
||||
0.397 0.056
|
||||
0.497 0.218
|
||||
0.597 0.191
|
||||
0.697 0.434
|
||||
0.797 0.429
|
||||
0.897 0.688
|
||||
0.997 1.300
|
||||
1.097 1.078
|
||||
1.197 2.793
|
||||
1.297 3.715
|
||||
1.397 4.480
|
||||
1.497 7.176
|
||||
1.597 6.825
|
||||
1.697 5.171
|
||||
1.797 6.187
|
||||
1.897 5.023
|
||||
1.997 3.334
|
||||
2.097 2.239
|
||||
2.197 1.493
|
||||
2.297 1.008
|
||||
2.397 1.562
|
||||
2.647 0.940
|
||||
2.897 0.518
|
||||
3.147 0.249
|
||||
3.397 0.116
|
||||
3.647 0.055
|
||||
3.897 0.036
|
||||
4.397 0.007
|
||||
4.897 0.001
|
||||
20.881 0.003
|
||||
21.881 0.021
|
||||
22.881 0.109
|
||||
23.881 0.385
|
||||
24.881 0.973
|
||||
25.881 1.833
|
||||
26.881 2.671
|
||||
27.881 3.093
|
||||
28.881 2.913
|
||||
29.881 2.276
|
||||
30.881 1.503
|
||||
31.881 0.882
|
||||
32.881 0.727
|
||||
33.881 1.389
|
||||
34.881 2.175
|
||||
35.881 2.086
|
||||
36.881 1.310
|
||||
37.881 0.676
|
||||
38.725 0.010
|
||||
38.881 0.416
|
||||
39.881 0.370
|
||||
40.881 0.350
|
||||
41.881 0.269
|
||||
42.732 0.965
|
||||
42.881 0.166
|
||||
43.405 0.029
|
||||
43.881 0.091
|
||||
43.963 0.372
|
||||
44.147 0.128
|
||||
44.881 0.043
|
||||
45.881 0.016
|
||||
46.881 0.004
|
||||
47.913 0.129
|
||||
50.599 1.216
|
||||
52.553 0.440
|
||||
55.109 0.065
|
||||
55.852 0.154
|
||||
57.004 0.159
|
||||
58.092 0.000
|
||||
58.592 0.001
|
||||
59.092 0.003
|
||||
59.592 0.010
|
||||
60.092 0.026
|
||||
60.592 0.058
|
||||
61.092 0.126
|
||||
61.592 0.206
|
||||
62.092 0.301
|
||||
62.592 0.377
|
||||
63.092 0.418
|
||||
63.592 0.377
|
||||
64.092 0.301
|
||||
64.386 0.003
|
||||
64.592 0.206
|
||||
64.886 0.007
|
||||
65.092 0.126
|
||||
65.386 0.023
|
||||
65.592 0.058
|
||||
65.886 0.060
|
||||
66.092 0.026
|
||||
66.386 0.133
|
||||
66.592 0.010
|
||||
66.886 0.288
|
||||
67.092 0.003
|
||||
67.386 0.471
|
||||
67.592 0.001
|
||||
67.886 0.688
|
||||
68.092 0.000
|
||||
68.386 0.863
|
||||
68.886 0.956
|
||||
69.386 0.863
|
||||
69.886 0.688
|
||||
70.386 0.471
|
||||
70.886 0.288
|
||||
71.386 0.133
|
||||
71.725 0.306
|
||||
71.886 0.060
|
||||
72.386 0.023
|
||||
72.886 0.007
|
||||
73.386 0.003
|
||||
74.820 0.245
|
||||
76.169 0.088
|
||||
76.868 0.100
|
||||
77.221 0.273
|
||||
79.427 0.020
|
||||
80.865 0.238
|
||||
81.965 0.137
|
||||
83.429 0.151
|
||||
84.170 0.212
|
||||
84.218 0.112
|
||||
86.123 0.014
|
||||
87.374 0.010
|
||||
88.259 0.009
|
||||
88.876 0.013
|
||||
89.871 0.026
|
||||
90.690 0.023
|
||||
91.784 0.052
|
||||
93.247 0.178
|
||||
94.333 0.133
|
||||
96.192 0.026
|
||||
96.701 0.054
|
||||
97.543 0.023
|
||||
98.514 0.005
|
||||
98.840 0.010
|
||||
100.263 0.014
|
||||
100.784 0.003
|
||||
101.620 0.003
|
||||
102.426 0.005
|
||||
102.842 0.001
|
||||
103.170 0.001
|
||||
103.594 0.006
|
||||
104.236 0.002
|
||||
105.008 0.001
|
||||
105.799 0.002
|
||||
106.990 0.006
|
||||
108.711 0.010
|
||||
109.189 0.008
|
||||
109.975 0.007
|
||||
111.148 0.005
|
||||
112.339 0.013
|
||||
113.145 0.010
|
||||
113.882 0.005
|
||||
114.892 0.002
|
||||
115.612 0.002
|
||||
116.455 0.001
|
||||
117.594 0.005
|
||||
118.481 0.023
|
||||
119.245 0.023
|
||||
120.360 0.009
|
||||
121.764 0.013
|
||||
123.594 0.009
|
||||
124.247 0.005
|
||||
125.709 0.012
|
||||
127.715 0.003
|
||||
129.373 0.002
|
||||
130.271 0.004
|
||||
132.887 0.060
|
||||
133.402 0.025
|
||||
134.813 0.082
|
||||
135.371 0.006
|
||||
136.379 0.005
|
||||
136.916 0.003
|
||||
138.243 0.008
|
||||
139.737 0.010
|
||||
141.093 0.006
|
||||
142.461 0.047
|
||||
144.001 0.004
|
||||
144.391 0.007
|
||||
147.073 0.021
|
||||
148.311 0.015
|
||||
148.895 0.001
|
||||
150.849 0.004
|
||||
151.442 0.001
|
||||
152.854 0.000
|
||||
154.169 0.002
|
||||
156.093 0.001
|
||||
157.003 0.003
|
||||
158.134 0.003
|
||||
159.271 0.002
|
||||
162.054 0.007
|
||||
164.173 0.002
|
@ -6,7 +6,7 @@ pluginManagement {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
val toolsVersion = "0.9.6"
|
||||
val toolsVersion = "0.9.7"
|
||||
val kotlinVersion = "1.5.0"
|
||||
|
||||
plugins {
|
||||
|
Loading…
Reference in New Issue
Block a user