Быстрый старт
Это руководство проведёт вас от нуля до первого статистического фита за 5 минут. Убедитесь, что NextStat установлен — см. Инструкцию по установке.
Шаг 1: Создайте тестовый workspace
«Workspace» — это JSON-файл, описывающий вашу статистическую модель: наблюдаемые данные, ожидания сигнала и фона, и систематические неопределённости. NextStat использует тот же формат JSON, что и pyhf.
Создадим минимальный workspace с одной сигнальной областью, одним сигнальным и одним фоновым сэмплом:
# Сохраните как workspace.json (или скопируйте в файл)
cat > workspace.json << 'EOF'
{
"channels": [
{
"name": "singlechannel",
"samples": [
{
"name": "signal",
"data": [5.0, 10.0],
"modifiers": [
{ "name": "mu", "type": "normfactor", "data": null }
]
},
{
"name": "background",
"data": [50.0, 60.0],
"modifiers": [
{ "name": "uncorr_bkguncrt", "type": "shapesys", "data": [5.0, 12.0] }
]
}
]
}
],
"observations": [
{ "name": "singlechannel", "data": [55.0, 65.0] }
],
"measurements": [
{ "name": "Measurement", "config": { "poi": "mu", "parameters": [] } }
],
"version": "1.0.0"
}
EOFШаг 2: Запустите первый фит (Python)
Откройте Python-оболочку или создайте скрипт my_first_fit.py:
import json
import nextstat
# 1. Загружаем workspace JSON
with open("workspace.json") as f:
workspace = json.load(f)
# 2. Строим модель из workspace'а
model = nextstat.from_pyhf(json.dumps(workspace))
# 3. Запускаем фит методом максимального правдоподобия
result = nextstat.fit(model)
# 4. Печатаем результаты
poi_idx = model.poi_index()
print("Сила сигнала (mu):", result.bestfit[poi_idx])
print("Неопределённость: ", result.uncertainties[poi_idx])
print("Все параметры: ", result.bestfit)
print("Все неопред-ти: ", result.uncertainties)Запустите:
python3 my_first_fit.py
Ожидаемый вывод (значения могут незначительно отличаться):
Сила сигнала (mu): 0.9999... Неопределённость: 0.3... Все параметры: [0.999..., 1.0..., 0.99...] Все неопред-ти: [0.3..., 0.08..., 0.15...]
Что произошло? NextStat нашёл значения параметров, которые лучше всего описывают наблюдаемые данные. Сила сигнала mu ≈ 1.0 означает, что данные согласуются с гипотезой сигнал+фон. Остальные параметры — это нюисанс-параметры (систематические неопределённости), которые были профилированы в ходе фита.
Шаг 3: Проверьте гипотезу
Проверка гипотезы определяет, совместимы ли данные с заданной силой сигнала. Метод CLs — стандартный подход в физике частиц:
import json
import nextstat
with open("workspace.json") as f:
workspace = json.load(f)
model = nextstat.from_pyhf(json.dumps(workspace))
# Проверяем гипотезу mu=1.0 (сигнал существует с номинальной силой)
result = nextstat.hypotest(model, mu_test=1.0)
print("CLs: ", result.cls)
print("CLs+b: ", result.clsb)
print("CLb: ", result.clb)
print("Исключён (95%)? ", "ДА" if result.cls < 0.05 else "НЕТ")Ожидаемый вывод:
CLs: 0.43... CLs+b: 0.24... CLb: 0.55... Исключён (95%)? НЕТ
Что это значит? CLs > 0.05 означает, что мы не можем исключить гипотезу сигнала на уровне достоверности 95%. Сигнал совместим с данными.
Шаг 4: Вычислите верхние пределы (Brazil band)
Скан верхнего предела находит максимальную силу сигнала, совместимую с данными:
import json
import nextstat
with open("workspace.json") as f:
workspace = json.load(f)
model = nextstat.from_pyhf(json.dumps(workspace))
# Вычисляем ожидаемые и наблюдаемые верхние пределы
limits = nextstat.upper_limit(model)
print("Наблюдаемый предел:", limits.observed)
print("Ожидаемый -2σ: ", limits.expected_minus2)
print("Ожидаемый -1σ: ", limits.expected_minus1)
print("Ожидаемый медиана: ", limits.expected)
print("Ожидаемый +1σ: ", limits.expected_plus1)
print("Ожидаемый +2σ: ", limits.expected_plus2)Шаг 5: Используйте командную строку
NextStat также поставляется с CLI-бинарником. Все те же операции доступны из терминала:
# Фит workspace'а nextstat fit --input workspace.json # Проверка гипотезы (асимптотический CLs) nextstat hypotest --input workspace.json --mu 1.0 # Проверка гипотезы с ожидаемыми бандами nextstat hypotest --input workspace.json --mu 1.0 --expected-set # Скан верхнего предела (201 точка от mu=0 до mu=5) nextstat upper-limit --input workspace.json \ --expected --scan-start 0 --scan-stop 5 --scan-points 201 # Проверка гипотезы на тоях (10k тоев, все ядра CPU) nextstat hypotest-toys --input workspace.json \ --mu 1.0 --n-toys 10000 --seed 42 --threads 0 # GPU-ускоренные тои (NVIDIA) nextstat hypotest-toys --input workspace.json \ --mu 1.0 --n-toys 10000 --gpu cuda # GPU-ускоренные тои (Apple Silicon) nextstat hypotest-toys --input workspace.json \ --mu 1.0 --n-toys 10000 --gpu metal
Шаг 6: Использование из Rust (опционально)
Если вы Rust-разработчик, вы можете использовать NextStat как библиотеку в своём проекте:
use ns_inference::mle::MaximumLikelihoodEstimator;
use ns_translate::pyhf::{HistFactoryModel, Workspace};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. Загружаем workspace
let json = std::fs::read_to_string("workspace.json")?;
let workspace: Workspace = serde_json::from_str(&json)?;
// 2. Строим модель
let model = HistFactoryModel::from_workspace(&workspace)?;
// 3. Фит
let mle = MaximumLikelihoodEstimator::new();
let result = mle.fit(&model)?;
// 4. Печатаем результаты
println!("Параметры фита: {:?}", result.parameters);
println!("NLL в минимуме: {}", result.nll);
Ok(())
}Попробуйте в браузере (без установки)
Не хотите ничего устанавливать? Попробуйте WASM-песочницу — NextStat работает целиком в вашем браузере через WebAssembly. Без сервера, без Python, без настройки.
Что изучить дальше
- Архитектура — как устроен NextStat
- Python API — все функции и классы
- Байесовское семплирование (NUTS) — апостериорный вывод с MCMC
- Регрессия и GLM — линейные, логистические, пуассоновские модели
- Анализ выживаемости — Каплан-Мейер, Cox PH, параметрические модели
- GPU-ускорение — CUDA и Metal для пакетного фитинга
- CLI справочник — все опции командной строки
