Compare commits

...

9 Commits

Author SHA1 Message Date
61598c79e5 fix: add missing rearwall-25-12-01.tsv 2026-01-20 13:07:41 +03:00
636f774177 test: add rearwall contribution compare 2026-01-20 13:06:01 +03:00
62f9d8522b fix: add missing reartrap-6-days.json 2026-01-20 13:04:24 +03:00
050dff11e8 chore: ignore ./data folder 2026-01-20 13:03:48 +03:00
dcc02006c7 refactor(trap,wall): move to typed variants
- make openInBrowser more robust (for graalvm)
2026-01-20 12:55:43 +03:00
8ac4d457d5 feat: add wall 25-12-01 model 2025-12-11 12:33:55 +03:00
3cbc28da58 feat: add faradey adiabacity model 2025-12-11 12:33:02 +03:00
824c3452f2 fix: correct rearWall derivative calculation 2025-12-11 12:32:30 +03:00
ad81b94021 refactor: make adiabacity typed enum 2025-12-11 12:29:37 +03:00
18 changed files with 1358 additions and 243 deletions

2
.gitignore vendored
View File

@@ -2,6 +2,8 @@
gradlew
gradlew.bat
data
.idea/
build/
/notebooks/.ipynb_checkpoints

View File

@@ -20,7 +20,7 @@ fun main() {
e - it
}
y.buffer = u.map {
adiabacity_2024_11(e, it)
AdiabaticityModel.`2024_11`(e, it)
}
}
}

View File

@@ -2,6 +2,67 @@ package ru.inr.mass.scripts
import org.apache.commons.math3.analysis.interpolation.LinearInterpolator
/**
* Единая модель адиабатичности: табличная или аналитическая
*/
enum class AdiabaticityModel(val description: String) {
`2024_11`("Оригинальная таблица Влада, ноябрь 2024"),
shifted("Со систематическим сдвигом"),
vasya("Вариант от Васи"),
faradey("Аналитическая модель для Цилиндра Фарадея");
// ← Здесь обязательно реализуем функцию для каждой модели
operator fun invoke(e: Double, u: Double): Double {
val delta = e - u
if (delta < 0.0) return 0.0
when (this) {
`2024_11` -> {
if (delta > TABLE_X_2024_11.last()) {
return 0.0;
}
if (delta < 3000.0) {
return 1.0
}
return ADIABACITY_INTERPOLATOR_2024_11.value(delta)
}
shifted -> {
if (delta > TABLE_X_2024_11.last()) {
return 0.0
}
if (delta < 3000.0) {
return 1.0
}
return ADIABACITY_INTERPOLATOR_SHIFT.value(delta)
}
vasya -> {
if (delta > TABLE_X_2024_11.last()) {
return 0.0
}
if (delta < 3000.0) {
return 1.0
}
return ADIABACITY_INTERPOLATOR_VASYA.value(delta)
}
faradey -> {
if (delta <= 6000.0) {
return 1.0
} else if (delta <= 14260.0) {
return -1.2187e-4 * delta + 1.7389
} else {
return 0.0
}
}
}
}
}
// Таблички дал Влад
private val TABLE_X_2024_11 = arrayOf<Double>(
0.0, 200.0, 300.0, 400.0, 500.0, 600.0, 700.0, 800.0, 900.0, 1000.0, 1100.0, 1200.0, 1300.0, 1400.0, 1500.0, 1600.0, 1700.0, 1800.0, 1900.0, 2000.0, 2100.0, 2200.0, 2300.0, 2400.0, 2500.0, 2600.0, 2700.0, 2800.0, 2900.0, 3000.0, 3100.0, 3200.0, 3300.0, 3400.0, 3500.0, 3600.0, 3700.0, 3800.0, 3900.0, 4000.0, 4100.0, 4200.0, 4210.0, 4400.0, 4500.0, 4600.0, 4700.0, 4800.0, 4900.0, 5000.0, 5100.0, 5200.0, 5300.0, 5400.0, 5500.0, 5600.0, 5700.0, 5800.0, 5850.0, 5900.0, 5950.0, 6000.0, 6050.0, 6100.0, 6150.0, 6200.0, 6250.0, 6300.0, 6350.0, 6400.0, 6450.0, 6500.0, 6550.0, 6600.0, 6650.0, 6700.0, 6750.0, 6800.0, 6850.0, 6900.0, 6950.0, 7000.0, 7050.0, 7100.0, 7150.0, 7200.0, 7250.0, 7300.0, 7350.0, 7400.0, 7450.0, 7500.0, 7550.0, 7600.0, 7650.0, 7700.0, 7750.0, 7800.0, 7850.0, 7900.0, 7950.0, 8000.0, 8050.0, 8100.0, 8150.0, 8200.0, 8250.0, 8300.0, 8350.0, 8400.0, 8450.0, 8500.0, 8550.0, 8600.0, 8650.0, 8700.0, 8750.0, 8800.0, 8850.0, 8900.0, 8950.0, 9000.0,
@@ -33,56 +94,4 @@ private val TABLE_VASYA = arrayOf<Double>(
private val ADIABACITY_INTERPOLATOR_VASYA = LinearInterpolator().interpolate(
TABLE_X_2024_11,
TABLE_VASYA
)
fun adiabacity_2024_11(e: Double, u: Double): Double {
val delta = e - u
if (delta > TABLE_X_2024_11.last() || delta < 0.0) {
error("adiabacity: delta ($delta) out of [0:${TABLE_X_2024_11.last()}]")
}
if (delta < 3000.0) {
return 1.0
}
return ADIABACITY_INTERPOLATOR_2024_11.value(delta)
}
fun adiabacy_shifted(e: Double, u: Double): Double {
val delta = e - u
if (delta > TABLE_X_2024_11.last() || delta < 0.0) {
return 0.0
}
if (delta < 3000.0) {
return 1.0
}
return ADIABACITY_INTERPOLATOR_SHIFT.value(delta)
}
fun adiabacy_vasya(e: Double, u: Double): Double {
val delta = e - u
if (delta > TABLE_X_2024_11.last() || delta < 0.0) {
return 0.0
}
if (delta < 3000.0) {
return 1.0
}
return ADIABACITY_INTERPOLATOR_VASYA.value(delta)
}
fun getAdiabByName(name: String): (Double, Double) -> Double {
return when(name) {
"2024_11" -> {e: Double, u: Double -> adiabacity_2024_11(e,u)}
"shifted" -> {e: Double, u: Double -> adiabacy_shifted(e,u)}
"vasya" -> {e: Double, u: Double -> adiabacy_vasya(e,u)}
else -> throw IllegalArgumentException()
}
}
)

View File

@@ -32,12 +32,12 @@ data class FitCustomParams(
val fixBkg: Boolean = false,
val fixU2: Boolean = false,
val fixTrap: Boolean = false,
val trapFunc: String = "TrapInterpolator",
val trapFunc: TrapModel = TrapModel.FINE_5DAY,
val fixRWall: Boolean = false,
val fixE0: Boolean = false,
val wallFunc: String = "wallStep",
val wallFunc: WallModel = WallModel.TSV_2025_12_01,
val noAdiabacity: Boolean = false,
val adiabacityFunc: String = "2024_11"
val adiabacityFunc: AdiabaticityModel = AdiabaticityModel.`2024_11`
)
fun main (args: Array<String>) {
@@ -63,13 +63,8 @@ fun main (args: Array<String>) {
val config = Yaml.default.decodeFromStream(FitCustomParams.serializer(), File(args[0]).inputStream())
val wallFunc = getWallByName(config.wallFunc)
println("using wall=${config.wallFunc}")
val trapFunc = getTrapByName(config.trapFunc)
println("using trap=${config.trapFunc}")
val adiabacityFunc = getAdiabByName(config.adiabacityFunc)
println("using adiabacity=${config.adiabacityFunc}")
val fitParams: Map<Symbol, Double> = mapOf(
@@ -93,12 +88,12 @@ fun main (args: Array<String>) {
fixBkg = config.fixBkg,
fixU2 = config.fixU2,
fixTrap = config.fixTrap,
trapFunc = trapFunc,
trapFunc = config.trapFunc,
fixRwall = config.fixRWall,
fixE0 = config.fixE0,
wallFunc = wallFunc,
wallFunc = config.wallFunc,
noAdiabacity = config.noAdiabacity,
adiabacityFunc = adiabacityFunc
adiabacityFunc = config.adiabacityFunc
)
}
}

View File

@@ -0,0 +1,17 @@
package ru.inr.mass.scripts
fun openInBrowser(url: String) {
val os = System.getProperty("os.name").lowercase()
val pb = ProcessBuilder().inheritIO() // чтобы не висел процесс
try {
when {
os.contains("win") -> pb.command("rundll32", "url.dll,FileProtocolHandler", url)
os.contains("mac") -> pb.command("open", url)
os.contains("nix") || os.contains("nux") || os.contains("aix") -> pb.command("xdg-open", url)
else -> throw UnsupportedOperationException("Unsupported OS: $os")
}
pb.start()
} catch (e: Exception) {
System.err.println("Не удалось открыть браузер: ${e.message}")
}
}

View File

@@ -2,6 +2,7 @@ package ru.inr.mass.scripts
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.context
import com.github.ajalt.clikt.core.main
import com.github.ajalt.clikt.output.MordantHelpFormatter
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.help
@@ -40,9 +41,9 @@ class CustomSterileNeutrinoSpectrum(
source: DifferentiableKernel = NumassBeta,
transmission: DifferentiableKernel = NumassTransmission(),
resolution: DifferentiableKernel = NumassResolution(),
val wallFunc: (u: Double) -> Double,
val wallFunc: WallModel,
fss: FSS? = null
): SterileNeutrinoSpectrumFast(source, transmission, resolution, fss) {
) : SterileNeutrinoSpectrumFast(source, transmission, resolution, fss) {
override fun invoke(u: Double, arguments: Map<Symbol, Double>): Double {
val rearWall = arguments[rearWall]!!
@@ -53,8 +54,9 @@ class CustomSterileNeutrinoSpectrum(
if (symbols.isEmpty()) return this
return when (symbols.singleOrNull() ?: TODO("First derivatives only")) {
rearWall -> Spectrum { u, arguments ->
wallStep(u) * super.invoke(u, arguments)
wallFunc(u) * super.invoke(u, arguments)
}
else -> super.derivativeOrNull(symbols)
}
}
@@ -91,14 +93,16 @@ class CustomArgs : CliktCommand() {
val fixTrap: Boolean by option().flag().help("Don't fit trap variable")
val trapFunc: String by option().default("TrapInterpolator").help(
"trap function by name (NozikTrap, Fine, Fine5, TrapInterpolator, TrapInterpolator_24_07_12, TrapInterpolatorFull)"
)
val trapFunc: TrapModel by option().enum<TrapModel>().default(TrapModel.FINE_5DAY)
.help(
"trap model"
)
val rwall: Double by option().double().default(0.17).help("rear wall")
val wallFunc: String by option().default("wallStep").help(
"wall function by name (wallStep, wallStep_24_07_12, wallStep_25_10_09)"
val wallFunc: WallModel by option().enum<WallModel>().default(WallModel.TSV_2025_12_01)
.help(
"wall model"
)
val fixRwall: Boolean by option().flag().help("Don't fit rwall variable")
@@ -108,9 +112,10 @@ class CustomArgs : CliktCommand() {
val fixE0: Boolean by option().flag().help("Don't fit e0 variable")
// TODO: convert to enum
val adiabacityFunc: String by option().default("2024_11").help(
"adiabacity type (one of 2024_11, shifted, vasya)"
)
val adiabacityFunc: AdiabaticityModel by option().enum<AdiabaticityModel>().default(AdiabaticityModel.`2024_11`)
.help(
"adiabacity model"
)
@UnstableKMathAPI
override fun run() {
@@ -137,19 +142,17 @@ class CustomArgs : CliktCommand() {
fixU2,
fixTrap,
fixE0,
getTrapByName(trapFunc),
trapFunc,
fixRwall,
noAdiabacity,
getWallByName(wallFunc),
cliArgs=this@CustomArgs,
adiabacityFunc=getAdiabByName(adiabacityFunc)
wallFunc,
cliArgs = this@CustomArgs,
adiabacityFunc = adiabacityFunc
)
}
}
}
fun main(args: Array<String>) = CustomArgs().main(args)
suspend fun fitNumassSpectrumCustom(
spectrum: NBkgSpectrum,
data: XYErrorColumnarData<Double, Double, Double>,
@@ -159,15 +162,11 @@ suspend fun fitNumassSpectrumCustom(
): XYFit {
return data.fitWith(
optimizer = QowOptimizer,
modelExpression = spectrum,
startingPoint = initial,
attributesBuilder = {
optimizer = QowOptimizer, modelExpression = spectrum, startingPoint = initial, attributesBuilder = {
freeParameters(*fitParams.toTypedArray())
iterations(20)
OptimizationLog(logger)
}
)
})
}
@UnstableKMathAPI
@@ -183,9 +182,9 @@ suspend fun processCustom(
trapFunc: ITrap,
fixRwall: Boolean,
noAdiabacity: Boolean,
wallFunc: (u: Double) -> Double,
cliArgs: Any?=null,
adiabacityFunc: (e: Double, u: Double) -> Double
wallFunc: WallModel,
cliArgs: Any? = null,
adiabacityFunc: AdiabaticityModel
) {
println(cliArgs)
@@ -202,12 +201,11 @@ suspend fun processCustom(
trapFunc.value(ei, delta)
},
adjustX = false,
),
resolution = NumassResolution(1.7e-4, tailFunction = { e,u ->
), resolution = NumassResolution(1.7e-4, tailFunction = { e, u ->
if (noAdiabacity) {
1.0
} else {
adiabacityFunc(e,u)
adiabacityFunc(e, u)
}
})
).withNBkg()
@@ -251,6 +249,9 @@ suspend fun processCustom(
val fit = fitNumassSpectrumCustom(spectrum, data, fitVars, fitParams, dumpLogger)
val dataPath = Path(spectrumFile)
val reportPath = Path(
dataPath.parent.toString(), dataPath.nameWithoutExtension + postfix + ".html"
)
Plotly.page {
h3 {
@@ -276,7 +277,7 @@ suspend fun processCustom(
y.numbers = data.x.toDoubleArray().map { spectrum(it, fitParams + fit.result) }
}
}
plot{
plot {
layout {
title = "Residuals"
}
@@ -284,22 +285,22 @@ suspend fun processCustom(
name = "Residuals"
mode = ScatterMode.markers
x.buffer = testData.x
y.numbers = testData.indices.map{
y.numbers = testData.indices.map {
val value = spectrum(testData.x[it], fitParams + fit.result)
val dif = testData.y[it] - value
dif/testData.yErr[it]
dif / testData.yErr[it]
}
File(dataPath.parent.toString(), dataPath.nameWithoutExtension + postfix + ".fit.tsv")
.printWriter().use {
out -> out.println("U_sp\tcounts\tresidials")
testData.indices.forEach{
val value = spectrum(testData.x[it], fitParams + fit.result)
val dif = testData.y[it] - value
val residial = dif/testData.yErr[it]
out.println("${testData.x[it]}\t${value}\t$residial")
File(dataPath.parent.toString(), dataPath.nameWithoutExtension + postfix + ".fit.tsv").printWriter()
.use { out ->
out.println("U_sp\tcounts\tresidials")
testData.indices.forEach {
val value = spectrum(testData.x[it], fitParams + fit.result)
val dif = testData.y[it] - value
val residial = dif / testData.yErr[it]
out.println("${testData.x[it]}\t${value}\t$residial")
}
}
}
}
}
plot {
@@ -307,12 +308,12 @@ suspend fun processCustom(
title = "Residuals distribution"
}
histogram {
x.numbers = data.indices.map{
val value = spectrum(data.x[it], fitParams + fit.result)
val dif = data.y[it] - value
dif/data.yErr[it]
}
name = "Res histo"
x.numbers = data.indices.map {
val value = spectrum(data.x[it], fitParams + fit.result)
val dif = data.y[it] - value
dif / data.yErr[it]
}
name = "Res histo"
}
}
p {
@@ -362,7 +363,7 @@ suspend fun processCustom(
td {
val value = spectrum(testData.x[it], fitParams + fit.result)
val dif = testData.y[it] - value
+(dif/testData.yErr[it]).toString()
+(dif / testData.yErr[it]).toString()
}
}
}
@@ -384,8 +385,8 @@ suspend fun processCustom(
}
}
}
}.makeFile(path = Path(
dataPath.parent.toString(),
dataPath.nameWithoutExtension + postfix + ".html"
))
}
}.makeFile(path = reportPath, show = false)
openInBrowser("file:///$reportPath")
}
fun main(args: Array<String>) = CustomArgs().main(args)

View File

@@ -2,6 +2,7 @@ package ru.inr.mass.scripts
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.context
import com.github.ajalt.clikt.core.main
import com.github.ajalt.clikt.output.MordantHelpFormatter
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.help
@@ -157,7 +158,7 @@ private suspend fun process(spectrumFile: String, full: String?, postfix: String
},
adjustX = false,
),
resolution = NumassResolution(1.7e-4, tailFunction = {e,u -> adiabacity_2024_11(e,u) })
resolution = NumassResolution(1.7e-4, tailFunction = {e,u -> AdiabaticityModel.`2024_11`(e,u) })
).withNBkg()

View File

@@ -2,11 +2,14 @@ package ru.inr.mass.scripts
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.context
import com.github.ajalt.clikt.core.main
import com.github.ajalt.clikt.output.MordantHelpFormatter
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.help
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.double
import com.github.ajalt.clikt.parameters.types.enum
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import ru.inr.mass.models.*
@@ -39,11 +42,31 @@ private class CalcSpectrum : CliktCommand() {
val trap: Double by option().double().default(1.0).help("NumassTransmission.trap")
val trapFunc: String by option().default("TrapInterpolator").help("trap function by name")
val fixTrap: Boolean by option().flag().help("Don't fit trap variable")
val trapFunc: TrapModel by option().enum<TrapModel>().default(TrapModel.FINE_5DAY)
.help(
"trap model"
)
val rwall: Double by option().double().default(0.17).help("rear wall")
val wallFunc: String by option().default("wallStep").help("wall function by name")
val wallFunc: WallModel by option().enum<WallModel>().default(WallModel.TSV_2025_12_01)
.help(
"wall model"
)
val fixRwall: Boolean by option().flag().help("Don't fit rwall variable")
val noAdiabacity: Boolean by option().flag().help("Use const 1 instead of adiabacity function")
val fixE0: Boolean by option().flag().help("Don't fit e0 variable")
// TODO: convert to enum
val adiabacityFunc: AdiabaticityModel by option().enum<AdiabaticityModel>().default(AdiabaticityModel.`2024_11`)
.help(
"adiabacity model"
)
@UnstableKMathAPI
override fun run() {
@@ -60,14 +83,14 @@ private class CalcSpectrum : CliktCommand() {
)
runBlocking {
calcSpectrum(fitParams, getTrapByName(trapFunc), getWallByName(wallFunc))
calcSpectrum(fitParams, trapFunc, wallFunc)
}
}
}
fun main(args: Array<String>) = CalcSpectrum().main(args)
suspend fun calcSpectrum(fitParams: Map<Symbol, Double>, trapFunc: ITrap, wallFunc: (u: Double) -> Double) {
suspend fun calcSpectrum(fitParams: Map<Symbol, Double>, trapFunc: ITrap, wallFunc: WallModel) {
val range = 2000.0..18000.0 step 50.0
runBlocking(Dispatchers.Default) {
@@ -81,7 +104,7 @@ suspend fun calcSpectrum(fitParams: Map<Symbol, Double>, trapFunc: ITrap, wallFu
},
adjustX = false,
),
resolution = NumassResolution(1.7e-4, tailFunction = {e,u -> adiabacity_2024_11(e,u) })
resolution = NumassResolution(1.7e-4, tailFunction = {e,u -> AdiabaticityModel.`2024_11`(e,u) })
).withNBkg()
val out = range.map {

View File

@@ -24,20 +24,20 @@ import kotlin.math.pow
fun main() {
val maxDelta = (WALL_R - WALL_L)
val rearTrapInterpolator = RearTrapInterpolator()
val range = (WALL_L - 10.0)..18600.0 step 10.0
val rearTrap2keV = getRearTrapByName("25-11-26-2+")
val range = (WALL_L + 10.0)..18600.0 step 10.0
val spectrum: NBkgSpectrum = SterileNeutrinoSpectrum(
fss = null,
transmission = NumassTransmission(
trapFunc = { ei, ef, _ ->
val delta = ei - ef
rearTrapInterpolator.value(ei, delta)
rearTrap2keV.value(ei, delta)
},
adjustX = false,
),
resolution = NumassResolution(1.7e-4, tailFunction = {
e,u -> adiabacity_2024_11(e,u)
e,u -> 1.0
})
).withNBkg()
@@ -86,7 +86,7 @@ fun main() {
val deltas = (0.0..maxDelta step 10.0).toDoubleArray()
val values = eis.map { ei ->
deltas.map { rearTrapInterpolator.value(ei, it) }.toList()
deltas.map { rearTrap2keV.value(ei, it) }.toList()
}
layout {
@@ -108,7 +108,7 @@ fun main() {
mode = ScatterMode.lines
x.buffer = (0.0..90.0 step 1.0).toDoubleArray().plus((100.0..maxDelta step 10.0).toDoubleArray()).asBuffer()
y.numbers = x.doubles.map {
rearTrapInterpolator.value(HV, it)
rearTrap2keV.value(HV, it)
}
}
}

View File

@@ -1,8 +1,8 @@
// Code generated by trap-spectrum-2024-11.jl Julia notebook 2025-03-11T12:56:45.212
package ru.inr.mass.scripts
import org.apache.commons.math3.analysis.interpolation.PiecewiseBicubicSplineInterpolator
class RearTrapInterpolator {
// Старый треппинг в заднюю стенку. Посчитан для 10+ кэВ
private class RearTrap10kev: ITrap {
private val x = arrayOf(10000.0, 12000.0, 14000.0, 16000.0, 18000.0, 19000.0, ).toDoubleArray()
private val yCoarse = arrayOf(
@@ -59,7 +59,7 @@ class RearTrapInterpolator {
// private val fineInterpolator = PiecewiseBicubicSplineInterpolator().interpolate(x, yFine, gridFine)
private val fineInterpolator = BilinearInterpolator(x, yFine, gridFine)
fun value(ei: Double, delta: Double): Double {
override fun value(ei: Double, delta: Double): Double {
if (ei < x.first() || ei > x.last())
error("trap: ei ($ei) not in [${x.first()}..${x.last()}]")
if (delta < yFine.first())
@@ -73,4 +73,21 @@ class RearTrapInterpolator {
coarseInterpolator.value(ei, delta)
}
}
}
fun getRearTrapByName(name: String): ITrap {
return when(name) {
"RearTrap10kev" -> RearTrap10kev()
"25-11-26-2+" -> {
val resourcePath = "reartrap-6-days.json"
// Load JSON from resources at compile-time
val jsonInput = {}::class.java.classLoader
.getResourceAsStream(resourcePath)
?.bufferedReader()
?.use { it.readText() }
?: throw IllegalArgumentException("Resource not found: $resourcePath")
FineGridInterpolation(jsonInput, 2000.0, 2.0)
}
else -> throw IllegalArgumentException()
}
}

View File

@@ -1,121 +1,134 @@
package ru.inr.mass.scripts
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlin.math.exp
import kotlinx.serialization.*
import kotlinx.serialization.json.*
/**
* Единая модель эффективности ловушки (trapping probability)
*/
enum class TrapModel(val description: String) : ITrap {
NOZIK("Аналитическая модель Нозика (экспоненциальный спад при delta > 10 эВ)"),
FINE_2DAY("Интерполяция по тонкой сетке (trap-fine-2-day.json, δ=1 эВ, wallL=2000 эВ)"),
FINE_5DAY("Интерполяция по тонкой сетке (trap-fine-5-day-2V.json, δ=2 эВ, wallL=2000 эВ)"),
LEGACY_2024_07_12("Старый интерполятор от 12 июля 2024"),
LEGACY_FULL("Полный старый интерполятор (TrapInterpolatorFull)"),
LEGACY_DEFAULT("Базовый старый интерполятор (TrapInterpolator)");
/**
* Вычисляет вероятность ловушки для начальной энергии ei и разницы delta = ei - u.
*/
override fun value(ei: Double, delta: Double): Double {
return when (this) {
NOZIK -> nozikValue(delta)
FINE_2DAY -> fine2DayInterpolator.value(ei, delta)
FINE_5DAY -> fine5DayInterpolator.value(ei, delta)
LEGACY_2024_07_12 -> TrapInterpolator_24_07_12().value(ei, delta)
LEGACY_FULL -> TrapInterpolatorFull().value(ei, delta)
LEGACY_DEFAULT -> TrapInterpolator().value(ei, delta)
}
}
private companion object {
// =====================================================================
// 1. Аналитическая модель Нозика
// =====================================================================
private fun nozikValue(delta: Double): Double {
return if (delta > 10.0) {
1.86e-4 * exp(-delta / 25.0) + 5.5e-5
} else {
0.0
}
}
// =====================================================================
// 2. Тонкая сетка из JSON (2-day)
// =====================================================================
private val fine2DayInterpolator: FineGridInterpolation by lazy {
val jsonInput = loadResourceAsString("trap-fine-2-day.json")
FineGridInterpolation(jsonInput, wallL = 2000.0, deltaStep = 1.0)
}
// =====================================================================
// 3. Тонкая сетка из JSON (5-day, шаг по delta = 2 эВ)
// =====================================================================
private val fine5DayInterpolator: FineGridInterpolation by lazy {
val jsonInput = loadResourceAsString("trap-fine-5-day-2V.json")
FineGridInterpolation(jsonInput, wallL = 2000.0, deltaStep = 2.0)
}
// =====================================================================
// Утилита для загрузки ресурсов
// =====================================================================
private fun loadResourceAsString(resourcePath: String): String {
return {}::class.java.classLoader
.getResourceAsStream(resourcePath)
?.bufferedReader()
?.use { it.readText() }
?: throw IllegalArgumentException("Ресурс не найден: $resourcePath")
}
}
}
/**
* Интерфейс для всех моделей ловушки
*/
interface ITrap {
fun value(ei: Double, delta: Double): Double
}
class NozikTrap: ITrap {
override fun value(ei: Double, delta: Double): Double {
return if (delta > 10) {
1.86e-04 * exp(-delta / 25.0) + 5.5e-05
} else {
0.0
}
}
}
/**
* Внутренний класс для интерполяции по тонкой сетке из JSON
*/
@Serializable
data class GridPoint(
private data class GridPoint(
val hv: Double,
val grid: List<Double>
)
class FineGridInterpolation(jsonInput: String, private val wall_l: Double, private val deltaStep: Double = 1.0) : ITrap {
class FineGridInterpolation(
jsonInput: String,
private val wallL: Double,
private val deltaStep: Double = 1.0
) : ITrap {
private val hvValues: DoubleArray
private val deltaLayers: Array<DoubleArray>
init {
// Parse JSON input
val gridPoints = Json.decodeFromString<List<GridPoint>>(jsonInput)
require(gridPoints.isNotEmpty()) { "Grid cannot be empty" }
val ySizeMax = gridPoints[0].grid.size
// Validate grid consistency
require(gridPoints.all { it.grid.size == ySizeMax }) { "Inconsistent grid sizes" }
// Sort by hv and preprocess grids
val sortedPoints = gridPoints.sortedBy { it.hv }
hvValues = DoubleArray(sortedPoints.size) { sortedPoints[it].hv }
deltaLayers = Array(sortedPoints.size) { layerIdx ->
val grid = sortedPoints[layerIdx].grid
val trimmedLength = grid.indexOfLast { it >= 1e-5 }.let { idx ->
if (idx == -1) 0 else idx + 1
}
val maxSize = gridPoints.maxOf { it.grid.size }
require(gridPoints.all { it.grid.size == maxSize }) { "Inconsistent grid sizes" }
val out = if (trimmedLength == 0) {
listOf<Double>(sortedPoints[layerIdx+1].grid.last { it >= 1e-5 }).toTypedArray().toDoubleArray()
} else {
DoubleArray(trimmedLength) { grid[it] }
}
val sorted = gridPoints.sortedBy { it.hv }
hvValues = sorted.map { it.hv }.toDoubleArray()
out
deltaLayers = Array(sorted.size) { i ->
val grid = sorted[i].grid
val lastRelevant = grid.indexOfLast { it >= 1e-5 }
val trimSize = if (lastRelevant == -1) 1 else lastRelevant + 1
DoubleArray(trimSize) { grid[it] }
}
}
override fun value(ei: Double, delta: Double): Double {
if (ei - delta <= wallL) return 0.0
if (ei - delta <= wall_l)
return 0.0
// Поиск интервала по ei
val eiDown = hvValues.indices.find { hvValues[it] <= ei && hvValues[it + 1] >= ei }
?: throw IllegalArgumentException("ei $ei вне диапазона ${hvValues.first()}..${hvValues.last()}")
var eiUp = -1
var eiDown = -1
for (i in 0..(hvValues.size-2)) {
if (hvValues[i] <= ei && hvValues[i+1] >= ei) {
eiDown = i
eiUp = i + 1
}
}
val eiUp = eiDown + 1
val xFrac = (ei - hvValues[eiDown]) / (hvValues[eiUp] - hvValues[eiDown])
require(ei >= hvValues.first() && ei <= hvValues.last()) {
"ei $ei out of range ${hvValues.first()}..${hvValues.last()}"
}
val yIdx = (delta / deltaStep).toInt()
if (yIdx >= deltaLayers[eiUp].size) return 0.0
val xFrac = ((ei - hvValues[eiDown]) / (hvValues[eiUp] - hvValues[eiDown])).coerceIn(0.0, 1.0)
// TODO: add assertions for eiUp, eiDown
val valUp = deltaLayers[eiUp][yIdx]
val valDown = deltaLayers[eiDown].getOrElse(yIdx) { deltaLayers[eiDown].last() }
// Linear interpolation for y (delta has step of 1)
val yScaled = (delta / deltaStep).toInt()
require(yScaled < deltaLayers.last().size) {
"delta $delta > ${deltaLayers.last().size * deltaStep}"
}
val valUp = deltaLayers[eiUp][yScaled]
val valDown = deltaLayers[eiDown].getOrElse(yScaled) { deltaLayers[eiDown].last() }
// Linear interpolation along x
return valDown + (valUp - valDown) * xFrac
}
}
fun getTrapByName(name: String): ITrap {
return when(name) {
"NozikTrap" -> NozikTrap()
"Fine" -> {
val resourcePath = "trap-fine-2-day.json"
// Load JSON from resources at compile-time
val jsonInput = {}::class.java.classLoader
.getResourceAsStream(resourcePath)
?.bufferedReader()
?.use { it.readText() }
?: throw IllegalArgumentException("Resource not found: $resourcePath")
FineGridInterpolation(jsonInput, 2000.0)
}
"Fine5" -> {
val resourcePath = "trap-fine-5-day-2V.json"
// Load JSON from resources at compile-time
val jsonInput = {}::class.java.classLoader
.getResourceAsStream(resourcePath)
?.bufferedReader()
?.use { it.readText() }
?: throw IllegalArgumentException("Resource not found: $resourcePath")
FineGridInterpolation(jsonInput, 2000.0, deltaStep = 2.0)
}
"TrapInterpolator" -> TrapInterpolator()
"TrapInterpolator_24_07_12" -> TrapInterpolator_24_07_12()
"TrapInterpolatorFull" -> TrapInterpolatorFull()
else -> throw IllegalArgumentException()
}
}

View File

@@ -0,0 +1,108 @@
package ru.inr.mass.scripts
import kotlinx.html.br
import kotlinx.html.p
import ru.inr.mass.models.*
import ru.inr.mass.models.NBkgSpectrum.Companion.bkg
import ru.inr.mass.models.NBkgSpectrum.Companion.norm
import ru.inr.mass.models.NumassBeta.e0
import ru.inr.mass.models.NumassBeta.mnu2
import ru.inr.mass.models.NumassBeta.msterile2
import ru.inr.mass.models.NumassBeta.u2
import ru.inr.mass.models.NumassTransmission.Companion.thickness
import ru.inr.mass.models.NumassTransmission.Companion.trap
import ru.inr.mass.workspace.buffer
import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.real.step
import space.kscience.plotly.*
import space.kscience.plotly.models.ScatterMode
fun main() {
val trapInterpolator = TrapModel.FINE_5DAY
val wallInterpolator = WallModel.TSV_2025_12_01
val range = 2000.0..18600.0 step 50.0
val args: Map<Symbol, Double> = mapOf(
norm to 492346.83,
bkg to 0.0,
mnu2 to 0.0,
e0 to 18478.14,
msterile2 to 0.0,
u2 to 0.0,
thickness to 0.1,
trap to 2.1051,
rearWall to 0.00
)
val rwall1 = args.toMutableMap();
rwall1[rearWall] = 1.0
val rwall2 = args.toMutableMap();
rwall2[rearWall] = 2.0
val rwall3 = args.toMutableMap();
rwall3[rearWall] = 3.0
val spectrumC: NBkgSpectrum = CustomSterileNeutrinoSpectrum(
fss = null,
transmission = NumassTransmission(
trapFunc = { ei, ef, _ ->
val delta = ei - ef
trapInterpolator.value(ei, delta)
},
adjustX = false,
),
wallFunc = wallInterpolator,
resolution = NumassResolution(1.7e-4, tailFunction = {
e,u -> AdiabaticityModel.vasya(e,u)
})
).withNBkg()
Plotly.page {
plot {
scatter {
name = "rwall=${args[rearWall]}"
mode = ScatterMode.lines
x.buffer = range
y.numbers = x.doubles.map { spectrumC(it, args) }
}
listOf(rwall1, rwall2, rwall3).forEach { rwall ->
scatter {
name = "rwall=${rwall[rearWall]}"
mode = ScatterMode.lines
x.buffer = range
y.numbers = x.doubles.map { spectrumC(it, rwall) }
}
}
layout {
title = "Rear Wall Contribution"
// yaxis.type = AxisType.log
}
}
p {
+"command args = $args"
}
br()
p {
+"trapping model = $trapInterpolator"
}
br()
p {
+"wall model = $wallInterpolator"
}
br()
}.makeFile()
println("HV\trwall=${args[rearWall]}\trwall=${rwall1[rearWall]}\trwall=${rwall2[rearWall]}\trwall=${rwall3[rearWall]}")
range.iterator().forEach {
val r0 = spectrumC(it, args)
val r1 = spectrumC(it, rwall1)
val r2 = spectrumC(it, rwall2)
val r3 = spectrumC(it, rwall3)
println("${it}\t${spectrumC(it, args)}\t${spectrumC(it, rwall1)}\t${spectrumC(it, rwall2)}\t${spectrumC(it, rwall3)}")
}
}

View File

@@ -17,8 +17,8 @@ import space.kscience.plotly.models.ScatterMode
fun main() {
val trapInterpolator = TrapInterpolator()
val range = 10000.0..18600.0 step 50.0
val trapInterpolator = TrapModel.FINE_5DAY
val range = 2000.0..18600.0 step 50.0
val args: Map<Symbol, Double> = mapOf(
norm to 231296.31435970013,
@@ -50,9 +50,9 @@ fun main() {
},
adjustX = false,
),
wallFunc = getWallByName("wallStep"),
wallFunc = WallModel.TSV_2025_12_01,
resolution = NumassResolution(1.7e-4, tailFunction = {
e,u -> adiabacity_2024_11(e,u)
e,u -> AdiabaticityModel.vasya(e,u)
})
).withNBkg()
@@ -79,8 +79,8 @@ fun main() {
}
}.makeFile()
println("HV\ttrap=${args[trap]}\ttrap=${argsTrap3[trap]}")
println("HV\ttrap=${args[trap]}\ttrap=${argsTrap1[trap]}\ttrap=${argsTrap2[trap]}\ttrap=${argsTrap3[trap]}")
range.iterator().forEach {
println("${it}\t${spectrumC(it, args)}\t${spectrumC(it, argsTrap3)}")
println("${it}\t${spectrumC(it, args)}\t${spectrumC(it, argsTrap1)}\t${spectrumC(it, argsTrap2)}\t${spectrumC(it, argsTrap3)}")
}
}

View File

@@ -19,9 +19,7 @@ fun main() {
val maxDelta = (WALL_R - WALL_L)
val interpolatorName = "Fine"
val interpolator = getTrapByName(interpolatorName)
val interpolator = TrapModel.FINE_2DAY
Plotly.page {
plot {
val eis = (WALL_L..WALL_R step 100.0).toDoubleArray()
@@ -34,7 +32,7 @@ fun main() {
layout {
width = 1800
height = 800
title = "Trapping function ${interpolatorName}"
title = "Trapping function $interpolator"
}
trace {

View File

@@ -44,9 +44,9 @@ fun main() {
},
adjustX = false,
),
wallFunc = getWallByName("wallStep"),
wallFunc = WallModel.GEANT_2025_03_10,
resolution = NumassResolution(1.7e-4, tailFunction = {
e,u -> adiabacity_2024_11(e,u)
e,u -> AdiabaticityModel.`2024_11`(e,u)
})
).withNBkg()

View File

@@ -1,8 +1,584 @@
package ru.inr.mass.scripts
import org.apache.commons.math3.analysis.interpolation.LinearInterpolator
import space.kscience.kmath.real.step
import space.kscience.kmath.structures.toDoubleArray
/**
* Единая модель задней стенки (rear wall transmission)
*/
enum class WallModel(val description: String) {
GEANT_2025_03_10("Geant4 симуляция, угол 170.4°, март 2025"),
GEANT_2025_10_09("Geant4 симуляция, угол ~174.3°, октябрь 2025"),
GEANT_2024_07_12("Geant4 симуляция, старая версия, июль 2024"),
TSV_2025_12_01("Данные из файла rearwall-25-12-01.tsv, декабрь 2025");
/**
* Возвращает коэффициент пропускания задней стенки для остаточной энергии u (в эВ).
* u — остаточная энергия электрона после прохождения через детектор.
*/
operator fun invoke(u: Double): Double {
return when (this) {
GEANT_2025_03_10 -> interpolator20250310.value(u.coerceIn(10000.0, 19000.0))
GEANT_2025_10_09 -> interpolator20251009.value(u.coerceIn(10000.0, 19000.0))
GEANT_2024_07_12 -> stepInterpolator20240712(u)
TSV_2025_12_01 -> interpolator20251201.value(u.coerceIn(2000.0, 19000.0))
}.coerceAtMost(1.0).coerceAtLeast(0.0) // на всякий случай защищаем границы
}
private companion object {
// =====================================================================
// 1. Geant4, угол 170.4°, симуляция от 10 марта 2025 (weekend simulation)
// =====================================================================
private val X_COMMON = (10000.0..19000.0 step 50.0).toDoubleArray()
private val Y_2025_03_10 = doubleArrayOf(
1.0,
0.974889596797131,
0.950165449373342,
0.925878240027274,
0.902311758151626,
0.879132319047274,
0.856348579628581,
0.834079847915328,
0.812201149543789,
0.790758287460869,
0.769751104268126,
0.749232643240847,
0.729118853610476,
0.709528256404582,
0.690139758799478,
0.671295072814881,
0.652845299523728,
0.634648150733563,
0.616858191715396,
0.599567815355257,
0.582656454445821,
0.566172272910642,
0.549971565971275,
0.534191899866888,
0.518664543466603,
0.503475593718732,
0.488613875333822,
0.474227972442051,
0.460122868372562,
0.446209318208182,
0.432675413088279,
0.419513597887587,
0.406557974647203,
0.39401237435079,
0.381752137431506,
0.369754755912004,
0.358029988495748,
0.346635285614428,
0.335533816032385,
0.324734236663984,
0.314120544856746,
0.303777263574553,
0.293732881935585,
0.284010852307847,
0.274466525522236,
0.265141454767701,
0.25609466446036,
0.247273111324928,
0.238704969682699,
0.23032838194558,
0.222270998250831,
0.214340005505798,
0.206652508152059,
0.199180961462093,
0.191947716014804,
0.184905394878853,
0.178079181805118,
0.171412570752568,
0.164988038505326,
0.158764504069773,
0.152701043850734,
0.146805212973472,
0.141124703166211,
0.135583805777877,
0.130177484058292,
0.124914394921823,
0.119823499681976,
0.1149093628936,
0.110161438861015,
0.105554071638013,
0.101109611803498,
0.0968214486228659,
0.0926755736346905,
0.0886904024568008,
0.084864990698539,
0.081125675888589,
0.0775395097636615,
0.0740462087200941,
0.070699130830058,
0.0674773421006365,
0.0643366135693513,
0.061336127050764,
0.0583973407218261,
0.0556094994997091,
0.0529393923129434,
0.0503435771912657,
0.0478253595019787,
0.0454036270582404,
0.0430920735245903,
0.0408570156342299,
0.0387310348648569,
0.0366708466446508,
0.0347000607400591,
0.0328421295190864,
0.0310358249874121,
0.0293187653729092,
0.0276646651355995,
0.0261045317687508,
0.0245946085052137,
0.0231578755176638,
0.02176631588325,
0.0204498353061392,
0.0191941105280198,
0.0180100020414578,
0.0168789368301811,
0.0157873786280931,
0.0147616129751721,
0.0137995936916593,
0.0128448147365237,
0.0119873080191516,
0.011181270592635,
0.010398370737237,
0.00964521918756275,
0.00893724099102467,
0.00828797241371929,
0.00766215620441839,
0.00708025416070979,
0.00652825782116798,
0.00602001824877548,
0.00555034129491384,
0.00508947865385926,
0.00466733602977853,
0.00426014625778119,
0.00388002901797695,
0.00352808609946669,
0.0032043175022504,
0.00290069590573596,
0.00261753610680932,
0.00236428201204948,
0.00212330499584232,
0.00191302067601687,
0.00170981928612566,
0.0015275518891512,
0.00136794986796632,
0.00121228280785601,
0.00107487396713174,
0.00094974220496016,
0.000832952560266683,
0.000731587962985553,
0.000632899139235135,
0.000551366745769878,
0.000469519555418654,
0.000398375459190283,
0.000341239824387409,
0.000290714924189827,
0.000243652789737873,
0.000211071312040367,
0.000175971459255131,
0.000143704778443591,
0.000117576636908392,
9.41242689039072E-05,
7.47642604169831E-05,
5.54042519300591E-05,
4.28123764914093E-05,
3.44702590133038E-05,
2.75447275220464E-05,
2.1878383574654E-05,
1.69990318421772E-05,
1.24344769956667E-05,
7.86992214915612E-06,
5.35154706142616E-06,
3.30536730264557E-06,
2.04617975878059E-06,
9.44390657898734E-07,
6.29593771932489E-07,
1.57398442983122E-07,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
)
private val interpolator20250310 = LinearInterpolator().interpolate(X_COMMON, Y_2025_03_10)
// =====================================================================
// 2. Geant4, угол ~174.3°, октябрь 2025
// =====================================================================
private val Y_2025_10_09 = doubleArrayOf(
1.0,
0.975153367,
0.950706856,
0.927038707,
0.903997312,
0.881265386,
0.859041427,
0.836837787,
0.815604755,
0.794446745,
0.773863912,
0.753388923,
0.733701675,
0.714484882,
0.695413446,
0.676732755,
0.658711639,
0.640663952,
0.623121107,
0.60617063,
0.589246724,
0.572630723,
0.556691492,
0.541024218,
0.525582013,
0.510480537,
0.49595111,
0.481331031,
0.467479935,
0.453788264,
0.440585803,
0.427184845,
0.414276225,
0.401777104,
0.389528059,
0.37760724,
0.365892733,
0.35433765,
0.343152992,
0.33232313,
0.321849626,
0.31156368,
0.301393393,
0.291452865,
0.281964036,
0.272684646,
0.263394315,
0.254711983,
0.246340682,
0.237985011,
0.22964497,
0.221551879,
0.213833903,
0.206411328,
0.198993443,
0.191830323,
0.184787552,
0.177897953,
0.171449113,
0.165142504,
0.15904846,
0.152915341,
0.147105759,
0.141311806,
0.135811693,
0.130564781,
0.125475731,
0.120438259,
0.115750893,
0.111013512,
0.106216738,
0.101821649,
0.09761568,
0.093578512,
0.089433499,
0.085544814,
0.081801486,
0.07809567,
0.074625863,
0.071213885,
0.067906628,
0.064710341,
0.061743813,
0.058810106,
0.055970178,
0.053184955,
0.050573222,
0.048105282,
0.045731121,
0.043375716,
0.041206305,
0.039141613,
0.037000336,
0.034998164,
0.03310071,
0.031254835,
0.02952931,
0.02792257,
0.026390853,
0.024777862,
0.023293035,
0.021931682,
0.020710998,
0.019380905,
0.01820711,
0.017122404,
0.016061144,
0.01498269,
0.01402146,
0.013018029,
0.012130258,
0.011279999,
0.010517267,
0.009798298,
0.009073077,
0.008480709,
0.007949297,
0.00735224,
0.006775502,
0.006250342,
0.005712678,
0.005232844,
0.004779581,
0.004398215,
0.004001219,
0.003663616,
0.003369777,
0.003071248,
0.00269926,
0.00242105,
0.002180352,
0.001964661,
0.001772415,
0.001592673,
0.001405116,
0.001251944,
0.00108158,
0.000970608,
0.00087683,
0.000779925,
0.000670517,
0.000578301,
0.000478271,
0.000418878,
0.000356359,
0.000311032,
0.000256328,
0.000209439,
0.000181305,
0.000140668,
0.000117223,
9.53415E-05,
7.18969E-05,
5.47042E-05,
4.37633E-05,
3.43855E-05,
2.96965E-05,
2.50076E-05,
1.71927E-05,
1.40668E-05,
1.25038E-05,
1.25038E-05,
6.2519E-06,
4.68893E-06,
3.12595E-06,
1.56298E-06,
1.56298E-06,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
)
private val interpolator20251009 = LinearInterpolator().interpolate(X_COMMON, Y_2025_10_09)
// =====================================================================
// 3. Geant4 старая версия, июль 2024 (ступенчатая до 11000 эВ)
// =====================================================================
private val Y_2024_07_12 = doubleArrayOf(
1.0,
0.972786442674142,
0.945952334545635,
0.91964489360908,
0.894233201597419,
0.869259016583796,
0.844669464499728,
0.820761054827299,
0.797111831765082,
0.773672031483916,
0.750952769979141,
0.728844152128026,
0.707387647788205,
0.686195513790801,
0.665647199333165,
0.64545448890474,
0.625764600500126,
0.606609673258992,
0.58788603253725,
0.569558428955913,
0.551775117256022,
0.534257212644989,
0.517156080103177,
0.500604423175015,
0.484208278212981,
0.46834087393578,
0.452845661630844,
0.437580607035776,
0.423030907484895,
0.408756982487279,
0.394878057883627,
0.381282165058327,
0.368184947271076,
0.355217322788931,
0.342516142142084,
0.330340591940748,
0.318597365005246,
0.306926710320603,
0.29577961258859,
0.284894811706111,
0.27455533945152,
0.264394187584754,
0.254267248350536,
0.244669049801152,
0.235251245132475,
0.226043899991291,
0.217203563090168,
0.208591310406031,
0.200293191893472,
0.192330979227748,
0.184710892887505,
0.177080439082853,
0.169739237535198,
0.162683141258776,
0.155818843073912,
0.149170188148744,
0.142737176483273,
0.136596527314122,
0.13056473652126,
0.124614848697224,
0.119119055814281,
0.113816097769336,
0.108600226425423,
0.103514985133056,
0.0987107021261596,
0.0941251726182824,
0.0896816773728016,
0.0853667386859861,
0.0811399234466428,
0.077199250224974,
0.0733674353795943,
0.069575016898967,
0.06596610253837,
0.06248781822932,
0.0592915289521811,
0.0562300167123526,
0.0531114834182774,
0.0501629765405015,
0.0474021207685194,
0.0446547427002683,
0.0420856850198433,
0.0396928742343628,
0.0373207983776992,
0.0351291164017434,
0.0330442193091951,
0.0309966450885174,
0.0290807376658276,
0.0272104470865351,
0.0254904847411659,
0.0237788163673234,
0.0221884473270603,
0.0206779077627426,
0.0193125127001439,
0.0179792567772115,
0.0167144261193751,
0.0155138737408714,
0.0143454605020341,
0.013340853200851,
0.0123165477172917,
0.0113409693164523,
0.0104555878559669,
0.0095546551988687,
0.0087833158468767,
0.00807729152065821,
0.00740029609478351,
0.00677306449806958,
0.006136502183388,
0.0055517771907489,
0.00502822023811992,
0.0045772355363504,
0.00415113274916127,
0.00373747091926233,
0.00334350727173954,
0.00298271951032392,
0.0026385196919619,
0.00233371623835215,
0.00206727240305384,
0.00182363698945422,
0.00158207506873629,
0.00138924023073829,
0.00121403008223473,
0.00102948921576352,
0.000883307967603747,
0.000751641169615865,
0.000640709300444972,
0.00054636537432767,
0.000460315419737164,
0.000386706422436852,
0.000307913692932292,
0.000243635413599625,
0.000193871584438851,
0.000148254741041474,
0.000121299333579388,
9.43439261173016E-05,
6.6351772214366E-05,
5.49475613650218E-05,
3.52493789888819E-05,
1.96981823761399E-05,
9.33071796764522E-06,
3.11023932254841E-06
)
private fun stepInterpolator20240712(u: Double): Double {
if (u < 11000.0) return 1.0
if (u > 17950.0) return 0.0
val idx = ((u - 11000.0) / 50.0).toInt()
return Y_2024_07_12.getOrElse(idx) { 0.0 }
}
// =====================================================================
// 4. Данные из внешнего TSV-файла (декабрь 2025)
// =====================================================================
private val Y_2025_12_01 = {}::class.java.classLoader
.getResourceAsStream("rearwall-25-12-01.tsv")
?.bufferedReader()
?.readLines()
?.filter { it.isNotBlank() }
?.map { it.trim().toDouble() }
?.toDoubleArray()
?: throw IllegalStateException("Не найден файл rearwall-25-12-01.tsv в ресурсах")
private val X_TSV = (2000.0..19000.0 step 50.0).toDoubleArray()
private val interpolator20251201 = LinearInterpolator().interpolate(X_TSV, Y_2025_12_01)
}
}
//fun wallStep(u: Double): Double {
// return (3.932729e-13 * u.pow(4.0)
// - 2.827187e-8 * u.pow(3.0)
@@ -13,7 +589,6 @@ import space.kscience.kmath.structures.toDoubleArray
// это с этим фитом предположительно все ок
val WALL_FROM_GEANT_24_07_12 = arrayOf<Double>(
1.0, 0.972786442674142, 0.945952334545635, 0.91964489360908, 0.894233201597419, 0.869259016583796, 0.844669464499728, 0.820761054827299, 0.797111831765082, 0.773672031483916, 0.750952769979141, 0.728844152128026, 0.707387647788205, 0.686195513790801, 0.665647199333165, 0.64545448890474, 0.625764600500126, 0.606609673258992, 0.58788603253725, 0.569558428955913, 0.551775117256022, 0.534257212644989, 0.517156080103177, 0.500604423175015, 0.484208278212981, 0.46834087393578, 0.452845661630844, 0.437580607035776, 0.423030907484895, 0.408756982487279, 0.394878057883627, 0.381282165058327, 0.368184947271076, 0.355217322788931, 0.342516142142084, 0.330340591940748, 0.318597365005246, 0.306926710320603, 0.29577961258859, 0.284894811706111, 0.27455533945152, 0.264394187584754, 0.254267248350536, 0.244669049801152, 0.235251245132475, 0.226043899991291, 0.217203563090168, 0.208591310406031, 0.200293191893472, 0.192330979227748, 0.184710892887505, 0.177080439082853, 0.169739237535198, 0.162683141258776, 0.155818843073912, 0.149170188148744, 0.142737176483273, 0.136596527314122, 0.13056473652126, 0.124614848697224, 0.119119055814281, 0.113816097769336, 0.108600226425423, 0.103514985133056, 0.0987107021261596, 0.0941251726182824, 0.0896816773728016, 0.0853667386859861, 0.0811399234466428, 0.077199250224974, 0.0733674353795943, 0.069575016898967, 0.06596610253837, 0.06248781822932, 0.0592915289521811, 0.0562300167123526, 0.0531114834182774, 0.0501629765405015, 0.0474021207685194, 0.0446547427002683, 0.0420856850198433, 0.0396928742343628, 0.0373207983776992, 0.0351291164017434, 0.0330442193091951, 0.0309966450885174, 0.0290807376658276, 0.0272104470865351, 0.0254904847411659, 0.0237788163673234, 0.0221884473270603, 0.0206779077627426, 0.0193125127001439, 0.0179792567772115, 0.0167144261193751, 0.0155138737408714, 0.0143454605020341, 0.013340853200851, 0.0123165477172917, 0.0113409693164523, 0.0104555878559669, 0.0095546551988687, 0.0087833158468767, 0.00807729152065821, 0.00740029609478351, 0.00677306449806958, 0.006136502183388, 0.0055517771907489, 0.00502822023811992, 0.0045772355363504, 0.00415113274916127, 0.00373747091926233, 0.00334350727173954, 0.00298271951032392, 0.0026385196919619, 0.00233371623835215, 0.00206727240305384, 0.00182363698945422, 0.00158207506873629, 0.00138924023073829, 0.00121403008223473, 0.00102948921576352, 0.000883307967603747, 0.000751641169615865, 0.000640709300444972, 0.00054636537432767, 0.000460315419737164, 0.000386706422436852, 0.000307913692932292, 0.000243635413599625, 0.000193871584438851, 0.000148254741041474, 0.000121299333579388, 9.43439261173016E-05, 6.6351772214366E-05, 5.49475613650218E-05, 3.52493789888819E-05, 1.96981823761399E-05, 9.33071796764522E-06, 3.11023932254841E-06
)
fun wallstep240712(u: Double): Double {
@@ -30,14 +605,13 @@ fun wallstep240712(u: Double): Double {
// Angle = 170.4, 2025-03-10 (weekend simulation)
private val WALL_FROM_GEANT = arrayOf<Double>(
1.0, 0.974889596797131, 0.950165449373342, 0.925878240027274, 0.902311758151626, 0.879132319047274, 0.856348579628581, 0.834079847915328, 0.812201149543789, 0.790758287460869, 0.769751104268126, 0.749232643240847, 0.729118853610476, 0.709528256404582, 0.690139758799478, 0.671295072814881, 0.652845299523728, 0.634648150733563, 0.616858191715396, 0.599567815355257, 0.582656454445821, 0.566172272910642, 0.549971565971275, 0.534191899866888, 0.518664543466603, 0.503475593718732, 0.488613875333822, 0.474227972442051, 0.460122868372562, 0.446209318208182, 0.432675413088279, 0.419513597887587, 0.406557974647203, 0.39401237435079, 0.381752137431506, 0.369754755912004, 0.358029988495748, 0.346635285614428, 0.335533816032385, 0.324734236663984, 0.314120544856746, 0.303777263574553, 0.293732881935585, 0.284010852307847, 0.274466525522236, 0.265141454767701, 0.25609466446036, 0.247273111324928, 0.238704969682699, 0.23032838194558, 0.222270998250831, 0.214340005505798, 0.206652508152059, 0.199180961462093, 0.191947716014804, 0.184905394878853, 0.178079181805118, 0.171412570752568, 0.164988038505326, 0.158764504069773, 0.152701043850734, 0.146805212973472, 0.141124703166211, 0.135583805777877, 0.130177484058292, 0.124914394921823, 0.119823499681976, 0.1149093628936, 0.110161438861015, 0.105554071638013, 0.101109611803498, 0.0968214486228659, 0.0926755736346905, 0.0886904024568008, 0.084864990698539, 0.081125675888589, 0.0775395097636615, 0.0740462087200941, 0.070699130830058, 0.0674773421006365, 0.0643366135693513, 0.061336127050764, 0.0583973407218261, 0.0556094994997091, 0.0529393923129434, 0.0503435771912657, 0.0478253595019787, 0.0454036270582404, 0.0430920735245903, 0.0408570156342299, 0.0387310348648569, 0.0366708466446508, 0.0347000607400591, 0.0328421295190864, 0.0310358249874121, 0.0293187653729092, 0.0276646651355995, 0.0261045317687508, 0.0245946085052137, 0.0231578755176638, 0.02176631588325, 0.0204498353061392, 0.0191941105280198, 0.0180100020414578, 0.0168789368301811, 0.0157873786280931, 0.0147616129751721, 0.0137995936916593, 0.0128448147365237, 0.0119873080191516, 0.011181270592635, 0.010398370737237, 0.00964521918756275, 0.00893724099102467, 0.00828797241371929, 0.00766215620441839, 0.00708025416070979, 0.00652825782116798, 0.00602001824877548, 0.00555034129491384, 0.00508947865385926, 0.00466733602977853, 0.00426014625778119, 0.00388002901797695, 0.00352808609946669, 0.0032043175022504, 0.00290069590573596, 0.00261753610680932, 0.00236428201204948, 0.00212330499584232, 0.00191302067601687, 0.00170981928612566, 0.0015275518891512, 0.00136794986796632, 0.00121228280785601, 0.00107487396713174, 0.00094974220496016, 0.000832952560266683, 0.000731587962985553, 0.000632899139235135, 0.000551366745769878, 0.000469519555418654, 0.000398375459190283, 0.000341239824387409, 0.000290714924189827, 0.000243652789737873, 0.000211071312040367, 0.000175971459255131, 0.000143704778443591, 0.000117576636908392, 9.41242689039072E-05, 7.47642604169831E-05, 5.54042519300591E-05, 4.28123764914093E-05, 3.44702590133038E-05, 2.75447275220464E-05, 2.1878383574654E-05, 1.69990318421772E-05, 1.24344769956667E-05, 7.86992214915612E-06, 5.35154706142616E-06, 3.30536730264557E-06, 2.04617975878059E-06, 9.44390657898734E-07, 6.29593771932489E-07, 1.57398442983122E-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
)
const val WALL_STEP = 50.0
const val WALL_L = 10_000.0
const val WALL_L = 2_000.0
const val WALL_R = 19_000.0
private val WALL_INTERPOLATOR = LinearInterpolator().interpolate(
(WALL_L..WALL_R step WALL_STEP).toDoubleArray(),
(10_000.0..WALL_R step WALL_STEP).toDoubleArray(),
WALL_FROM_GEANT.toDoubleArray()
)
@@ -47,21 +621,36 @@ fun wallStep(u: Double): Double {
// исходный угол до 14.2, выходной - 174.3
private val WALL_25_10_09 = arrayOf<Double>(
1.0, 0.975153367, 0.950706856, 0.927038707, 0.903997312, 0.881265386, 0.859041427, 0.836837787, 0.815604755, 0.794446745, 0.773863912, 0.753388923, 0.733701675, 0.714484882, 0.695413446, 0.676732755, 0.658711639, 0.640663952, 0.623121107, 0.60617063, 0.589246724, 0.572630723, 0.556691492, 0.541024218, 0.525582013, 0.510480537, 0.49595111, 0.481331031, 0.467479935, 0.453788264, 0.440585803, 0.427184845, 0.414276225, 0.401777104, 0.389528059, 0.37760724, 0.365892733, 0.35433765, 0.343152992, 0.33232313, 0.321849626, 0.31156368, 0.301393393, 0.291452865, 0.281964036, 0.272684646, 0.263394315, 0.254711983, 0.246340682, 0.237985011, 0.22964497, 0.221551879, 0.213833903, 0.206411328, 0.198993443, 0.191830323, 0.184787552, 0.177897953, 0.171449113, 0.165142504, 0.15904846, 0.152915341, 0.147105759, 0.141311806, 0.135811693, 0.130564781, 0.125475731, 0.120438259, 0.115750893, 0.111013512, 0.106216738, 0.101821649, 0.09761568, 0.093578512, 0.089433499, 0.085544814, 0.081801486, 0.07809567, 0.074625863, 0.071213885, 0.067906628, 0.064710341, 0.061743813, 0.058810106, 0.055970178, 0.053184955, 0.050573222, 0.048105282, 0.045731121, 0.043375716, 0.041206305, 0.039141613, 0.037000336, 0.034998164, 0.03310071, 0.031254835, 0.02952931, 0.02792257, 0.026390853, 0.024777862, 0.023293035, 0.021931682, 0.020710998, 0.019380905, 0.01820711, 0.017122404, 0.016061144, 0.01498269, 0.01402146, 0.013018029, 0.012130258, 0.011279999, 0.010517267, 0.009798298, 0.009073077, 0.008480709, 0.007949297, 0.00735224, 0.006775502, 0.006250342, 0.005712678, 0.005232844, 0.004779581, 0.004398215, 0.004001219, 0.003663616, 0.003369777, 0.003071248, 0.00269926, 0.00242105, 0.002180352, 0.001964661, 0.001772415, 0.001592673, 0.001405116, 0.001251944, 0.00108158, 0.000970608, 0.00087683, 0.000779925, 0.000670517, 0.000578301, 0.000478271, 0.000418878, 0.000356359, 0.000311032, 0.000256328, 0.000209439, 0.000181305, 0.000140668, 0.000117223, 9.53415E-05, 7.18969E-05, 5.47042E-05, 4.37633E-05, 3.43855E-05, 2.96965E-05, 2.50076E-05, 1.71927E-05, 1.40668E-05, 1.25038E-05, 1.25038E-05, 6.2519E-06, 4.68893E-06, 3.12595E-06, 1.56298E-06, 1.56298E-06, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
)
private val WALL_25_10_09_INTERPOLATOR = LinearInterpolator().interpolate(
(WALL_L..WALL_R step WALL_STEP).toDoubleArray(),
(10_000.0..WALL_R step WALL_STEP).toDoubleArray(),
WALL_25_10_09.toDoubleArray()
)
fun wall251009(u: Double): Double {
return WALL_25_10_09_INTERPOLATOR.value(u)
return WALL_25_10_09_INTERPOLATOR.value(u)
}
private val WALL_25_12_01 = {}::class.java.classLoader
.getResourceAsStream("rearwall-25-12-01.tsv")
?.bufferedReader()!!
.readLines()
.filter { it.isNotBlank() }
.map { it.trim().toDouble() }
.toDoubleArray()
private val WALL_25_12_01_INTERPOLATOR = LinearInterpolator().interpolate(
(2000.0..19000.0 step 50.0).toDoubleArray(),
WALL_25_12_01
)
fun getWallByName(name: String): (u: Double) -> Double {
return when(name) { // TODO: switch to enum
"wallStep" -> {u: Double -> wallStep(u)}
"wallStep_24_07_12" -> {u: Double -> wallstep240712(u) }
"wallStep_25_10_09" -> {u: Double -> wall251009(u)}
return when (name) { // TODO: switch to enum
"wallStep" -> { u: Double -> wallStep(u) }
"wallStep_24_07_12" -> { u: Double -> wallstep240712(u) }
"wallStep_25_10_09" -> { u: Double -> wall251009(u) }
"25-12-01" -> { u: Double -> WALL_25_12_01_INTERPOLATOR.value(u) }
else -> throw IllegalArgumentException()
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,341 @@
1
0.984706357
0.969653543
0.954822714
0.940128819
0.925555596
0.91122075
0.896936625
0.882740133
0.868702257
0.854812802
0.841128812
0.827738179
0.814441115
0.801446442
0.788602642
0.775989991
0.763565898
0.751361985
0.739306749
0.727425102
0.715667611
0.70407661
0.692602925
0.681291213
0.670257111
0.65937685
0.648638945
0.638085468
0.627561158
0.617304264
0.607245221
0.59736054
0.587604662
0.577912412
0.56844034
0.559059643
0.549928164
0.540887158
0.53204426
0.523351073
0.514778301
0.506348658
0.498041881
0.489850743
0.481840162
0.473958126
0.466237933
0.458618408
0.451146271
0.443819716
0.436597054
0.429550433
0.422535173
0.415702535
0.408987601
0.402390371
0.395865803
0.389505014
0.383228372
0.377092666
0.371023942
0.365036656
0.359163977
0.353387448
0.347711974
0.342132522
0.33668923
0.33130479
0.325958681
0.320682523
0.315575048
0.310467058
0.305436762
0.300492292
0.2956099
0.290795524
0.286075492
0.281386692
0.276782041
0.272244501
0.267786721
0.263359917
0.259019066
0.254755782
0.250512503
0.246374279
0.242279033
0.238234637
0.234251803
0.23034305
0.226510444
0.222717072
0.219000234
0.215326889
0.211719624
0.208164112
0.204654934
0.20119041
0.197771833
0.194444502
0.191131496
0.187870632
0.184658036
0.181490096
0.178406304
0.175328448
0.172313317
0.169300121
0.166350165
0.163447317
0.160551309
0.157744095
0.154975342
0.152287639
0.14959103
0.146925655
0.144326488
0.141745777
0.139185587
0.136615846
0.13411967
0.131706351
0.129272641
0.12691198
0.124548737
0.122170394
0.119897107
0.117646277
0.115395576
0.113190304
0.110993938
0.108829191
0.106682385
0.104591849
0.10250583
0.100447946
0.098401549
0.096414004
0.094390322
0.092450788
0.090520675
0.088626828
0.086753244
0.084921993
0.083079125
0.081269298
0.079477023
0.077719207
0.075993398
0.074290175
0.072605795
0.070946066
0.069306471
0.067669714
0.066064578
0.064492611
0.062953812
0.061421466
0.059937132
0.058434857
0.056990144
0.055579504
0.054188093
0.052820043
0.051496002
0.050206163
0.048893867
0.047633711
0.046383236
0.045176512
0.043988373
0.042804622
0.04167327
0.040546565
0.03944993
0.038394337
0.037345843
0.036325225
0.035320354
0.03432942
0.033352426
0.032417376
0.03148323
0.030578639
0.029698182
0.028836698
0.028002961
0.027184067
0.026393437
0.025625522
0.024871674
0.0240995
0.023351202
0.022640719
0.021927526
0.021225303
0.020539213
0.019898036
0.019274541
0.018650529
0.018055169
0.017471812
0.016904071
0.016341105
0.015807565
0.015295192
0.014763588
0.014256893
0.013776785
0.013310486
0.01284935
0.012399313
0.011959084
0.011525051
0.011100052
0.010694412
0.010291483
0.009903782
0.009538151
0.009174585
0.008811665
0.008477396
0.008144159
0.007810278
0.007507371
0.007212336
0.006929305
0.006649371
0.006386602
0.006127317
0.005870098
0.005627592
0.005390377
0.005160519
0.004945244
0.0047341
0.004517793
0.004310004
0.004114347
0.003919336
0.003738133
0.003560674
0.003391087
0.003230148
0.00307037
0.002913689
0.002766947
0.00263169
0.002500951
0.002373309
0.002252508
0.00213532
0.002023166
0.001916819
0.00182183
0.001723227
0.001628625
0.001540864
0.001454134
0.001370503
0.001287903
0.001215113
0.001136643
0.001064369
0.000998161
0.000926661
0.000870648
0.000807408
0.000749072
0.000695254
0.000645436
0.000598716
0.000552125
0.000513793
0.000479334
0.000444487
0.00041119
0.000375052
0.000347304
0.000319943
0.000292195
0.000263414
0.000240829
0.000219662
0.000199787
0.000179137
0.000164037
0.000147517
0.000131772
0.00011693
0.000104153
9.21498E-05
8.32446E-05
7.21453E-05
6.33691E-05
5.61417E-05
4.94305E-05
4.2074E-05
3.58791E-05
3.00713E-05
2.67157E-05
2.21986E-05
1.81977E-05
1.51002E-05
1.27771E-05
1.09702E-05
8.38899E-06
6.58213E-06
5.29152E-06
4.12996E-06
3.09747E-06
2.19404E-06
2.06498E-06
1.80686E-06
1.16155E-06
5.16245E-07
2.58123E-07
2.58123E-07
2.58123E-07
1.29061E-07
1.29061E-07
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1 1
2 0.984706357
3 0.969653543
4 0.954822714
5 0.940128819
6 0.925555596
7 0.91122075
8 0.896936625
9 0.882740133
10 0.868702257
11 0.854812802
12 0.841128812
13 0.827738179
14 0.814441115
15 0.801446442
16 0.788602642
17 0.775989991
18 0.763565898
19 0.751361985
20 0.739306749
21 0.727425102
22 0.715667611
23 0.70407661
24 0.692602925
25 0.681291213
26 0.670257111
27 0.65937685
28 0.648638945
29 0.638085468
30 0.627561158
31 0.617304264
32 0.607245221
33 0.59736054
34 0.587604662
35 0.577912412
36 0.56844034
37 0.559059643
38 0.549928164
39 0.540887158
40 0.53204426
41 0.523351073
42 0.514778301
43 0.506348658
44 0.498041881
45 0.489850743
46 0.481840162
47 0.473958126
48 0.466237933
49 0.458618408
50 0.451146271
51 0.443819716
52 0.436597054
53 0.429550433
54 0.422535173
55 0.415702535
56 0.408987601
57 0.402390371
58 0.395865803
59 0.389505014
60 0.383228372
61 0.377092666
62 0.371023942
63 0.365036656
64 0.359163977
65 0.353387448
66 0.347711974
67 0.342132522
68 0.33668923
69 0.33130479
70 0.325958681
71 0.320682523
72 0.315575048
73 0.310467058
74 0.305436762
75 0.300492292
76 0.2956099
77 0.290795524
78 0.286075492
79 0.281386692
80 0.276782041
81 0.272244501
82 0.267786721
83 0.263359917
84 0.259019066
85 0.254755782
86 0.250512503
87 0.246374279
88 0.242279033
89 0.238234637
90 0.234251803
91 0.23034305
92 0.226510444
93 0.222717072
94 0.219000234
95 0.215326889
96 0.211719624
97 0.208164112
98 0.204654934
99 0.20119041
100 0.197771833
101 0.194444502
102 0.191131496
103 0.187870632
104 0.184658036
105 0.181490096
106 0.178406304
107 0.175328448
108 0.172313317
109 0.169300121
110 0.166350165
111 0.163447317
112 0.160551309
113 0.157744095
114 0.154975342
115 0.152287639
116 0.14959103
117 0.146925655
118 0.144326488
119 0.141745777
120 0.139185587
121 0.136615846
122 0.13411967
123 0.131706351
124 0.129272641
125 0.12691198
126 0.124548737
127 0.122170394
128 0.119897107
129 0.117646277
130 0.115395576
131 0.113190304
132 0.110993938
133 0.108829191
134 0.106682385
135 0.104591849
136 0.10250583
137 0.100447946
138 0.098401549
139 0.096414004
140 0.094390322
141 0.092450788
142 0.090520675
143 0.088626828
144 0.086753244
145 0.084921993
146 0.083079125
147 0.081269298
148 0.079477023
149 0.077719207
150 0.075993398
151 0.074290175
152 0.072605795
153 0.070946066
154 0.069306471
155 0.067669714
156 0.066064578
157 0.064492611
158 0.062953812
159 0.061421466
160 0.059937132
161 0.058434857
162 0.056990144
163 0.055579504
164 0.054188093
165 0.052820043
166 0.051496002
167 0.050206163
168 0.048893867
169 0.047633711
170 0.046383236
171 0.045176512
172 0.043988373
173 0.042804622
174 0.04167327
175 0.040546565
176 0.03944993
177 0.038394337
178 0.037345843
179 0.036325225
180 0.035320354
181 0.03432942
182 0.033352426
183 0.032417376
184 0.03148323
185 0.030578639
186 0.029698182
187 0.028836698
188 0.028002961
189 0.027184067
190 0.026393437
191 0.025625522
192 0.024871674
193 0.0240995
194 0.023351202
195 0.022640719
196 0.021927526
197 0.021225303
198 0.020539213
199 0.019898036
200 0.019274541
201 0.018650529
202 0.018055169
203 0.017471812
204 0.016904071
205 0.016341105
206 0.015807565
207 0.015295192
208 0.014763588
209 0.014256893
210 0.013776785
211 0.013310486
212 0.01284935
213 0.012399313
214 0.011959084
215 0.011525051
216 0.011100052
217 0.010694412
218 0.010291483
219 0.009903782
220 0.009538151
221 0.009174585
222 0.008811665
223 0.008477396
224 0.008144159
225 0.007810278
226 0.007507371
227 0.007212336
228 0.006929305
229 0.006649371
230 0.006386602
231 0.006127317
232 0.005870098
233 0.005627592
234 0.005390377
235 0.005160519
236 0.004945244
237 0.0047341
238 0.004517793
239 0.004310004
240 0.004114347
241 0.003919336
242 0.003738133
243 0.003560674
244 0.003391087
245 0.003230148
246 0.00307037
247 0.002913689
248 0.002766947
249 0.00263169
250 0.002500951
251 0.002373309
252 0.002252508
253 0.00213532
254 0.002023166
255 0.001916819
256 0.00182183
257 0.001723227
258 0.001628625
259 0.001540864
260 0.001454134
261 0.001370503
262 0.001287903
263 0.001215113
264 0.001136643
265 0.001064369
266 0.000998161
267 0.000926661
268 0.000870648
269 0.000807408
270 0.000749072
271 0.000695254
272 0.000645436
273 0.000598716
274 0.000552125
275 0.000513793
276 0.000479334
277 0.000444487
278 0.00041119
279 0.000375052
280 0.000347304
281 0.000319943
282 0.000292195
283 0.000263414
284 0.000240829
285 0.000219662
286 0.000199787
287 0.000179137
288 0.000164037
289 0.000147517
290 0.000131772
291 0.00011693
292 0.000104153
293 9.21498E-05
294 8.32446E-05
295 7.21453E-05
296 6.33691E-05
297 5.61417E-05
298 4.94305E-05
299 4.2074E-05
300 3.58791E-05
301 3.00713E-05
302 2.67157E-05
303 2.21986E-05
304 1.81977E-05
305 1.51002E-05
306 1.27771E-05
307 1.09702E-05
308 8.38899E-06
309 6.58213E-06
310 5.29152E-06
311 4.12996E-06
312 3.09747E-06
313 2.19404E-06
314 2.06498E-06
315 1.80686E-06
316 1.16155E-06
317 5.16245E-07
318 2.58123E-07
319 2.58123E-07
320 2.58123E-07
321 1.29061E-07
322 1.29061E-07
323 0
324 0
325 0
326 0
327 0
328 0
329 0
330 0
331 0
332 0
333 0
334 0
335 0
336 0
337 0
338 0
339 0
340 0
341 0