337.1 / 777.4 nm photometer

Physicist verification companion · source release r4 · mathematical checks and unresolved limits

Review index · Download editable notebook

Executed top-to-bottom in a fresh kernel.
Cell 0 · statistics-00

03 — Poisson detection, pulse morphology and red upper limits

This is an executable, lightweight review of the statistical experiment. It uses synthetic receiver-input counts, not measured source-depth labels. It does not rerun the original 81,000-pulse generator.

Full derivations, equation IDs S01–S21, units, source functions and selection limits are in methods/statistics.md. The original scripts are retained for comparison; this notebook calls a new implementation.

Required: NumPy and SciPy in the portable runtime. Optional Node checks are labelled NOT_RUN when Node is unavailable. No downloads, installs or large simulations occur here.

Cell 1 · statistics-01 · execution 1
from pathlib import Path
import sys, json, shutil, time
start = Path.cwd().resolve()
ROOT = next((p for p in [start, *start.parents] if (p / "modules/common.py").is_file()), None)
if ROOT is None:
    raise RuntimeError("Open this notebook from within the verification package.")
for p in [ROOT / "runtime/deps", ROOT / "modules"]:
    if p.is_dir():
        sys.path.insert(0, str(p))
from common import table, H, C, PHOTON_ENERGY_337, PHOTON_ENERGY_777
import statistics_review as st
import numpy as np
import scipy
print("Package:", ROOT)
print("NumPy:", np.__version__, "SciPy:", scipy.__version__)
print("Source:", Path(st.__file__).relative_to(ROOT))
Package: D:\Photometer_research_20261022\verification_20261022_r1
NumPy: 2.3.5 SciPy: 1.18.1
Source: modules\statistics_review.py
Cell 2 · statistics-02

Execute the bounded checks

This call checks count tails and intervals, generates one explicit-bin pulse, independently fits its likelihood, and rebuilds decisions and intervals from the 81 saved synthetic trial summaries. It also checks source-free and background-free profile boundaries.

A software check does not establish physical source depth, hardware sensitivity or useful orbital event rate.

Cell 3 · statistics-03 · execution 2
tick = time.perf_counter()
audit = st.run_checks(write=True)
elapsed_s = time.perf_counter() - tick
assert audit["passed"]
print("Checks completed in", round(elapsed_s, 3), "s")
print("Output: checks/statistics_results.json")
print("Saved scenarios:", audit["confusions"]["scenarios"])
print("Recomputed metrics:", audit["confusions"]["metrics_recomputed"])
print("Optional JavaScript status:", audit["javascript"]["status"])
Checks completed in 3.927 s
Output: checks/statistics_results.json
Saved scenarios: 81
Recomputed metrics: 648
Optional JavaScript status: EXECUTED_OPTIONAL_NODE
Cell 4 · statistics-04

Photon reference planes — S01–S02

For an assumed efficiency η\eta and entrance area AA, expected primary counts are s=ηAΦaps=\eta A\Phi_{\rm ap}. The aperture fluence already includes atmospheric delivery. Multiplication gain is not another photon efficiency.

The following is an assumed conversion, not a threshold or emitted-source yield.

Cell 5 · statistics-05 · execution 3
table([audit["photon_planes"]], max_rows=1)
expected_source_primary_PEassumed_efficiencyarea_m2expected_aperture_photonsaperture_photon_fluence_m2aperture_energy_fluence_J_m2_at337E337_JE777_Jqualification
1000.21.9634954e-05500254647911.5005763e-115.8927495e-192.5552429e-19Aperture photons after propagation; no emitted-source yield or second cloud attenuation; no PMT/APD gain factor.

1 rows total; 1 shown.

Cell 6 · statistics-06

Detection with known background — S05–S06

The critical integer is the smallest kk such that PPois⁡(b)(N≥k)≤αP_{\operatorname{Pois}(b)}(N\ge k)\le\alpha. Required signal is an expected source count solving PPois⁡(b+s)(N≥k)=0.95P_{\operatorname{Pois}(b+s)}(N\ge k)=0.95.

The two alphas are a single-gate tail and a hypothetical fixed search allocation. Neither validates an adaptive spacecraft trigger or a physical false-event rate.

Cell 7 · statistics-07 · execution 4
table(audit["counts"]["threshold_power_checks"], max_rows=20)
print("Zero-background critical count:", st.critical_known(0))
print("Zero-background source mean for 95% detection:", st.required_signal_known(0)["source_mean_PE"])
background_PEalpha_per_testcriticalsource_mean_PEbackground_mean_PEpowertailcritical_direct_sumpower_direct_sum
02.8665157e-0712.995732300.95010.95
07.7160494e-1212.995732300.95010.95
0.012.8665157e-0736.28579360.010.951.6542165e-0730.95
0.017.7160494e-1259.1435190.010.958.2641856e-1350.95
12.8665157e-071014.70521610.951.1142548e-07100.95
17.7160494e-121419.66856910.954.5198525e-12140.95
102.8665157e-073029.540972100.952.5099512e-07300.95
107.7160494e-123939.808464100.952.9598815e-12390.95
1002.8665157e-0715576.0308251000.952.1239031e-071550.95
1007.7160494e-1217597.312881000.957.5905324e-121750.95
10002.8665157e-071163219.6568310000.952.6749344e-0711630.95
10007.7160494e-121222280.0622210000.956.3394806e-1212220.95
1000002.8665157e-071015862110.82481000000.952.8493978e-071015860.95
1000007.7160494e-121021412667.2551000000.957.6279109e-121021410.95
10000002.8665157e-0710050056654.533110000000.952.859063e-0710050050.95
10000007.7160494e-1210067528402.965610000000.957.6994181e-1210067520.95

16 rows total; 16 shown.

Zero-background critical count: 1
Zero-background source mean for 95% detection: 2.995732273553991
Cell 8 · statistics-08

Downstream threshold bindings

All 216 FOV and 192 auroral rows are checked against their declared known-background mean and false-alarm allocation. The FOV variable named alpha is a population slope, not the false-alarm alpha. The latter is recovered from the retained source constants without executing that source.

This verifies only the statistical columns. It does not validate a brightness population, sky scene, field geometry or useful mission rate.

Cell 9 · statistics-09 · execution 5
bindings = audit["downstream_threshold_bindings"]
print(bindings["status"])
print("Rows:", bindings["rows_checked"], "Unique (background, alpha) computations:",
      bindings["unique_background_alpha_computations"])
print("Largest S95 difference (PE):", bindings["maximum_S95_absolute_difference_PE"])
print("Largest power difference:", bindings["maximum_power_absolute_difference"])
show = [r for r in bindings["rows"] if r["study"] == "fov_population"][:2]
show += [r for r in bindings["rows"] if r["study"] == "auroral_counts"][:2]
table(show, max_rows=4)
ALL408_STATISTICAL_COLUMN_BINDINGS_CHECKED
Rows: 408 Unique (background, alpha) computations: 228
Largest S95 difference (PE): 1.2287055142223835e-06
Largest power difference: 1.2996648202090455e-10
studyrow_indexbackground_mean_PEalpha_per_testalpha_sourcestored_criticalrecomputed_criticalstored_S95_PErecomputed_S95_PES95_abs_difference_PEpower_at_stored_S95
fov_population00.27976997.7160494e-12reference/analytic/fov_population.py:41 -> count_requirements.py ALPHA_OPERATIONAL101015.42544715.4254475.3290705e-150.95
fov_population10.27976997.7160494e-12reference/analytic/fov_population.py:41 -> count_requirements.py ALPHA_OPERATIONAL101015.42544715.4254475.3290705e-150.95
auroral_counts00.0456786472.8665157e-07row.per_test_alpha447.70797797.70797793.5527137e-150.95
auroral_counts10.0456786477.7160494e-12row.per_test_alpha7711.79671711.7967175.3290705e-150.95

4 rows total; 4 shown.

Cell 10 · statistics-10

Finite baseline and red limits — S03–S12

For N∼Pois⁡(s+b)N\sim\operatorname{Pois}(s+b), M∼Pois⁡(rb)M\sim\operatorname{Pois}(rb), r=Toff/Tonr=T_{\rm off}/T_{\rm on}, condition on N+M under the null:

N∣N+M∼Binom⁡(N+M,1/(1+r)).N\mid N+M \sim \operatorname{Binom}(N+M,1/(1+r)).
Inspect original LaTeX
N\mid N+M \sim \operatorname{Binom}(N+M,1/(1+r)).

Known-background upper limits subtract a known fixed bb. Finite-baseline limits use a conservative union-bound construction with a prechosen alpha split. Plugging M/rM/r into a known-background limit is a different procedure.

Selecting only nondetections using the same counts can alter conditional coverage.

Cell 11 · statistics-11 · execution 6
table(audit["counts"]["onoff_checks"], max_rows=10)
table(audit["counts"]["upper_inversions"], max_rows=10)
print(json.dumps(audit["counts"]["zero_count_controls"], indent=2))
table(audit["counts"]["coverage_finite_enumerations"], max_rows=10)
n_onm_offr_off_over_onSciPyfinite_sum
001011
10100.0909090910.090909091
100103.8554329e-113.8554329e-11
5230.0128784180.012878418
3040108.0370233e-148.0370233e-14
100200101.9795037e-311.9795037e-31

6 rows total; 6 shown.

n_onknown_b_PEsource95_upper_PEtotal_mean_inversion_CDF
002.99573230.05
020.995732270.05
104.74386450.05
325.75365650.05
10511.9622190.05
1008038.0792730.05

6 rows total; 6 shown.

{
  "known_zero_background95": 2.9957322735539913,
  "finite_baseline_zero_zero95": 3.6888794541139363
}
source_PEb_on_PErknown_b_enumerated_coveragefinite_off_enumerated_coverageomitted_probability_bound
0010110
1010110
32100.959572320.993510674.2188475e-15
10350.974113080.992228987.7715612e-16

4 rows total; 4 shown.

Cell 12 · statistics-12

Worked likelihood with every bin exposed — S13–S16

The unit-peak ramp has an 80 µs 10–90% rise and ends 3 ms after onset. Early bins, one late plateau and an independent 10 ms prewindow form this example.

For each bin, λj=Aqj+βdj\lambda_j=Aq_j+\beta d_j. Both djd_j and qjq_j are in seconds; A,βA,\beta are primary count rates; nj,λjn_j,\lambda_j are counts.

With Q=∑qjQ=\sum q_j, D=∑djD=\sum d_j, h=q/Qh=q/Q, w=d/Dw=d/D, the total-scale MLE is η^tot=∑nj\widehat\eta_{\rm tot}=\sum n_j. A concave profile gives A^=θ^N/Q\widehat A=\widehat\theta N/Q, β^=(1−θ^)N/D\widehat\beta=(1-\widehat\theta)N/D.

A separate two-rate optimizer checks the original likelihood. It does not call the old R4 fitter. The table includes all bins in early/late/prewindow order, not chronological order.

Cell 13 · statistics-13 · execution 7
example = audit["worked_example"]
print("Seed:", example["seed"], "Observed total:", example["observed_total_PE"])
table([
    {"method": "concave mixture profile", **example["profile"]},
    {"method": "direct two-rate SciPy optimization", **example["direct_SciPy_two_parameter_fit"]},
], max_rows=2)
print("Absolute log-likelihood difference:", example["absolute_loglikelihood_difference"])
print("Fitted total minus observed counts:", example["fitted_total_minus_observed_PE"])
table(example["bins"], max_rows=40)
Seed: 202610221110 Observed total: 743
methodthetaA_cpsb_cpslogL
concave mixture profile0.83793731343023.3710034.381-51.507368
direct two-rate SciPy optimization343023.3710034.381-51.507368

2 rows total; 2 shown.

Absolute log-likelihood difference: 2.1316282072803006e-14
Fitted total minus observed counts: 0.0
binlabelleft_sright_sd_sq_sn_PEtruth_mean_PEfitted_mean_PE
0early-0.0001-8e-052e-05000.20.20068763
1early-8e-05-6e-052e-05010.20.20068763
2early-6e-05-4e-052e-05000.20.20068763
3early-4e-05-2e-052e-05000.20.20068763
4early-2e-0502e-05000.20.20068763
5early02e-052e-05010.20.20068763
6early2e-054e-052e-051.25e-0700.241666670.24356555
7early4e-056e-052e-053e-0601.21.2297577
8early6e-058e-052e-057e-0622.53333332.6018512
9early8e-050.00012e-051.1e-0523.86666673.9739447
10early0.00010.000122e-051.5e-0545.25.3460382
11early0.000120.000142e-051.8875e-05106.49166676.6752538
12early0.000140.000162e-052e-0576.86666677.0611551
13early0.000160.000182e-052e-0546.86666677.0611551
14early0.000180.00022e-052e-05106.86666677.0611551
15early0.00020.000222e-052e-0556.86666677.0611551
16early0.000220.000242e-052e-0536.86666677.0611551
17early0.000240.000262e-052e-0596.86666677.0611551
18early0.000260.000282e-052e-0556.86666677.0611551
19early0.000280.00032e-052e-0586.86666677.0611551
20early0.00030.000322e-052e-05106.86666677.0611551
21early0.000320.000342e-052e-0576.86666677.0611551
22early0.000340.000362e-052e-0576.86666677.0611551
23early0.000360.000382e-052e-05126.86666677.0611551
24early0.000380.00042e-052e-0586.86666677.0611551
25late_plateau0.0010.00250.00150.0015528515529.58663
26prewindow-0.0105-0.00050.010100100100.34381

27 rows total; 27 shown.

Cell 14 · statistics-14

The next table searches three rise templates and an onset grid with unknown amplitude/background. Its winning template is a waveform morphology, not cloud depth. An individual noisy outcome may differ from its generating label.

Cell 15 · statistics-15 · execution 8
table(example["top_grid_candidates"], max_rows=9)
rise_usonset_usA_cpsb_cpslogL
8050345828.0710042.456-50.573975
8045344901.8610037.678-50.664439
8055346734.810050.919-50.757771
8040343965.5610035.194-50.978595
8060347599.5410066.402-51.306984
3065342710.210046.05-51.408867
3070343482.8810072.219-51.500882
8035343023.3710034.381-51.507368
3060341831.6310036.596-51.761316

9 rows total; 9 shown.

Cell 16 · statistics-16

Rebuild denominators and Monte Carlo intervals — S17–S19

A fixed profile-score gap ln⁡19\ln19 is a rejection heuristic, not calibrated 95% confidence. Detection/all trials, acceptance/all trials and wrong/accepted trials have different denominators.

The summaries contain fitted scores and gate/prewindow counts, not every original bin count. Reconstructing them verifies decisions, tables and intervals; it does not independently refit 81,000 pulses.

The table shows the 50 kS/s low-background subset. Full results remain in the machine-readable output. Error is undefined when no trial is accepted.

Cell 17 · statistics-17 · execution 9
rebuilt = audit["confusions"]
print("Scenarios:", rebuilt["scenarios"], "Synthetic pulses:", rebuilt["signal_trials"])
print("Metrics:", rebuilt["metrics_recomputed"])
print("Largest interval difference from retained report:", rebuilt["max_interval_absolute_difference"])
rows = []
for x in rebuilt["rows"]:
    if x["sample_khz"] == 50 and x["background_cps"] == 50:
        detected, a3, w3, a2, w2, r3, r2, allerr = x["rebuilt_metrics"]
        rows.append({
            "plateau_equivalent_PE": x["N_plateau_equivalent_PE"],
            "true_receiver_rise_us": x["truth_rise_us"],
            "detected_n": detected["k"],
            "accepted_n": a2["k"],
            "wrong_n": w2["k"],
            "wrong_denominator": w2["n"],
            "wrong_fraction": w2["fraction"],
            "individual_exact95_interval": w2["Clopper_Pearson"],
            "confusion_fast_slow_reject_undetected": x["confusion_fastslow"],
        })
table(rows, max_rows=12)
Scenarios: 81 Synthetic pulses: 81000
Metrics: 648
Largest interval difference from retained report: 2.220446049250313e-16
plateau_equivalent_PEtrue_receiver_rise_usdetected_naccepted_nwrong_nwrong_denominatorwrong_fractionindividual_exact95_intervalconfusion_fast_slow_reject_undetected
100301000210210[0.0, 0.16109761521907962][21, 0, 979, 0]
1008010002020[0.0, 0.841886116991581][2, 0, 998, 0]
1002001000000None[null, null][0, 0, 1000, 0]
100030100095609560[0.0, 0.0038512254525673623][956, 0, 44, 0]
100080100069346930.0057720058[0.0015748498838513603, 0.014712188300512097][689, 4, 307, 0]
10002001000580155800.025862069[0.014545446707021925, 0.04229721667197348][15, 565, 420, 0]
100003010001000010000[0.0, 0.003682083896865672][1000, 0, 0, 0]
100008010001000010000[0.0, 0.003682083896865672][1000, 0, 0, 0]
1000020010001000010000[0.0, 0.003682083896865672][0, 1000, 0, 0]

9 rows total; 9 shown.

Cell 18 · statistics-18

Independent numerical precision checks

Selected tails are summed from Poisson masses; selected on/off tails are finite binomial sums. No Gaussian approximation replaces the count probabilities.

The high-mean pins come from a retained 60-digit Decimal/Stirling/geometric-remainder calculation. They expose a small SciPy incomplete-gamma precision limitation near a mean of 10610^6. The tested critical integers agree. This is bounded floating-point QA, not formal directed interval arithmetic.

Cell 19 · statistics-19 · execution 10
table(audit["counts"]["pinned_high_mean_controls"], max_rows=4)
table(audit["counts"]["tail_checks"], max_rows=12)
meann_inclusivepinned_60digit_Decimal_taildirect_recurrencerelative_differenceSciPy_tailprovenance
100000010050002.934034e-072.934034e-071.7763568e-132.9340205e-07R4 qa/browser_large_mean_tail_control.json;60digit Decimal/Stirling/geometric-remainder calculation, not empirical data.
100000010070001.3595738e-121.3595738e-121.2878587e-131.3595736e-12R4 qa/browser_large_mean_tail_control.json;60digit Decimal/Stirling/geometric-remainder calculation, not empirical data.
100000010050042.8739184e-072.8739184e-075.0759397e-132.8739052e-07R4 qa/browser_large_mean_tail_control.json;60digit Decimal/Stirling/geometric-remainder calculation, not empirical data.
100000010050052.859076e-072.859076e-072.6023628e-132.859063e-07R4 qa/browser_large_mean_tail_control.json;60digit Decimal/Stirling/geometric-remainder calculation, not empirical data.

4 rows total; 4 shown.

kindmeann_inclusivedirect_sumSciPyabs_differencerelative_difference
Poisson_tail001100
Poisson_tail01000None
Poisson_tail05000None
Poisson_tail1e-1201100
Poisson_tail1e-1211e-121e-122.6253291e-272.6645353e-15
Poisson_tail1e-1258.3333333e-638.3333333e-639.2838812e-771.110223e-14
Poisson_tail0.0101100
Poisson_tail0.0110.00995016630.00995016635.2041704e-185.5511151e-16
Poisson_tail0.0158.2641856e-138.2641856e-135.149684e-276.2172489e-15
Poisson_tail0.101100
Poisson_tail0.110.0951625820.0951625821.3877788e-171.110223e-16
Poisson_tail0.157.6678017e-087.6678017e-089.2644229e-231.2212453e-15

35 rows total; 12 shown.

Cell 20 · statistics-20

Known-parameter oracle — S20–S21

For known independent Poisson means, BC=exp⁡[−12∑j(μj−νj)2]{\rm BC}=\exp[-\tfrac12\sum_j(\sqrt{\mu_j}-\sqrt{\nu_j})^2]. Under equal priors and zero-one loss:

(1−1−BC2)/2≤Pe⋆≤BC/2.(1-\sqrt{1-{\rm BC}^2})/2\le P_e^\star\le{\rm BC}/2.
Inspect original LaTeX
(1-\sqrt{1-{\rm BC}^2})/2\le P_e^\star\le{\rm BC}/2.

Three new small two-bin joint-PMF controls test the formula and bounds. The original 320-row grid is not independently rebuilt here. Unknown nuisance fits and accepted-only practical errors have different assumptions and loss/selection rules.

Cell 21 · statistics-21 · execution 11
table(audit["oracle_affinity"]["rows"], max_rows=3)
print("Original 320-row grid:", audit["oracle_affinity"]["retained320_grid"])
mu_PE_per_binnu_PE_per_binexplicit_joint_PMF_affinityexplicit_equal_prior_Bayes_erroraffinityBayes_error_lowerBayes_error_upperfinite_grid_mass_Pfinite_grid_mass_Q
[0.2, 1.0][1.3, 2.5]0.664341320.1820320.664341320.126285330.3321706611
[0.0, 0.3][0.2, 1.0]0.816868260.2801880.816868260.211587860.4084341311
[1.0, 0.1][1.0, 3.0]0.367042570.0724748250.367042570.0348979270.1835212911

3 rows total; 3 shown.

Original 320-row grid: NOT_INDEPENDENTLY_REBUILT_IN_THIS_LIGHT_REVIEW
Cell 22 · statistics-22

Source-function audit and optional browser execution

Retaining original code is provenance; running it twice is not independent theory validation. The likelihood is derived in the methods chapter, and this new profile is checked against direct two-parameter optimization.

The browser copy is linked by hash/function lines. Optional actual Node checks exercise thresholds, red limits and the corrected tiny-background boundary. NOT_RUN means JavaScript was not executed in this environment.

Cell 23 · statistics-23 · execution 12
for row in audit["source_map"]:
    print(json.dumps(row, indent=2))
print(json.dumps({k:v for k,v in audit["javascript"].items() if k != "checks"}, indent=2))
table(audit["javascript"].get("checks", []), max_rows=12)
equations = []
for eq, funcs in audit["equation_function_map"].items():
    for f in funcs:
        equations.append({"equation": eq, **f})
table(equations, max_rows=40)
{
  "file": "reference\\statistics\\oracle_reference\\calculate_ideal_poisson_rise.py",
  "present": true,
  "sha256": "542d4cc4495b0e7d379b3d6071bc668d904533567638ccca35853ac56abc3269",
  "functions": {
    "experiment": 18,
    "affinity_bounds": 28
  }
}
{
  "file": "reference\\statistics\\practical_morphology.py",
  "present": true,
  "sha256": "08df8f61294885ba658d75ae23bc3a7bb6511ffd01f9608a0de5a143f33f477c",
  "functions": {
    "primitive": 25,
    "fit_one": 57,
    "draw_case": 138,
    "analyze_case": 154
  }
}
{
  "file": "reference\\statistics\\count_inference\\count_inference.py",
  "present": true,
  "sha256": "4e4e25ae4db608500fb51c8406b599a7ee8efb92a3adee0f49e8a6d2a45eba9c",
  "functions": {
    "count_threshold_known_background": 78,
    "exact_onoff_pvalue": 96,
    "poisson_total_mean_upper": 133,
    "poisson_total_mean_lower": 140,
    "red_source_upper_known_background": 147,
    "red_source_upper_finite_baseline": 156
  }
}
{
  "file": "reference\\statistics\\browser_math.js",
  "sha256": "69186918327b076b053769ad3597c3f472a93919e5cd73057303f8034704bd37",
  "function_lines": {
    "sf": 5,
    "critical": 7,
    "threshold": 8,
    "upper": 9
  },
  "status": "EXECUTED_OPTIONAL_NODE",
  "node_version": "v24.19.0",
  "red_upper_checks": [
    {
      "n_on": 0,
      "b_on_PE": 0,
      "JS_upper95": 2.995732273553991,
      "Python_upper95": 2.9957322735539913,
      "abs_difference": 4.440892098500626e-16
    },
    {
      "n_on": 0,
      "b_on_PE": 2,
      "JS_upper95": 0.9957322735539909,
      "Python_upper95": 0.9957322735539913,
      "abs_difference": 4.440892098500626e-16
    },
    {
      "n_on": 1,
      "b_on_PE": 0,
      "JS_upper95": 4.743864518390579,
      "Python_upper95": 4.743864518390579,
      "abs_difference": 0.0
    },
    {
      "n_on": 3,
      "b_on_PE": 2,
      "JS_upper95": 5.753656527932727,
      "Python_upper95": 5.753656527932727,
      "abs_difference": 0.0
    },
    {
      "n_on": 10,
      "b_on_PE": 5,
      "JS_upper95": 11.962219235721907,
      "Python_upper95": 11.962219235721896,
      "abs_difference": 1.0658141036401503e-14
    },
    {
      "n_on": 100,
      "b_on_PE": 80,
      "JS_upper95": 38.07927278209726,
      "Python_upper95": 38.079272782097064,
      "abs_difference": 1.9895196601282805e-13
    }
  ],
  "tiny_background_boundary_checks": [
    {
      "b_PE": 2.8665161009724685e-07,
      "alpha": 2.866515718791933e-07,
      "JS": {
        "sf1": 2.86651569012678e-07,
        "critical": 1
      },
      "expected_sf1": 2.86651569012678e-07,
      "expected_critical": 1
    },
    {
      "b_PE": 2.866516158302791e-07,
      "alpha": 2.866515718791933e-07,
      "JS": {
        "sf1": 2.8665157474570857e-07,
        "critical": 2
      },
      "expected_sf1": 2.8665157474570857e-07,
      "expected_critical": 2
    },
    {
      "b_PE": 7.716049305585323e-12,
      "alpha": 7.716049382716049e-12,
      "JS": {
        "sf1": 7.716049305555554e-12,
        "critical": 1
      },
      "expected_sf1": 7.716049305555554e-12,
      "expected_critical": 1
    },
    {
      "b_PE": 7.716049459906311e-12,
      "alpha": 7.716049382716049e-12,
      "JS": {
        "sf1": 7.716049459876542e-12,
        "critical": 2
      },
      "expected_sf1": 7.716049459876542e-12,
      "expected_critical": 2
    }
  ]
}
b_PEalphaJSPythonsignal_abs_difference
02.8665157e-07{"critical": 1, "signal": 2.995732273553989, "power": 0.95, "tail": 0}{"critical": 1, "source_mean_PE": 2.995732273553991, "background_mean_PE": 0.0, "power": 0.95, "tail": 0.0}1.7763568e-15
07.7160494e-12{"critical": 1, "signal": 2.995732273553989, "power": 0.95, "tail": 0}{"critical": 1, "source_mean_PE": 2.995732273553991, "background_mean_PE": 0.0, "power": 0.95, "tail": 0.0}1.7763568e-15
0.012.8665157e-07{"critical": 3, "signal": 6.285793621871987, "power": 0.95, "tail": 1.6542165280748786e-07}{"critical": 3, "source_mean_PE": 6.285793621871989, "background_mean_PE": 0.01, "power": 0.95, "tail": 1.6542165280748778e-07}2.6645353e-15
0.017.7160494e-12{"critical": 5, "signal": 9.143519026637575, "power": 0.95, "tail": 8.264185641806491e-13}{"critical": 5, "source_mean_PE": 9.143519026637573, "background_mean_PE": 0.01, "power": 0.95, "tail": 8.264185641806515e-13}1.7763568e-15
12.8665157e-07{"critical": 10, "signal": 14.705216422115452, "power": 0.95, "tail": 1.1142547833872041e-07}{"critical": 10, "source_mean_PE": 14.705216422115463, "background_mean_PE": 1.0, "power": 0.9499999999999998, "tail": 1.1142547833872071e-07}1.0658141e-14
17.7160494e-12{"critical": 14, "signal": 19.668569075713677, "power": 0.95, "tail": 4.519852546965104e-12}{"critical": 14, "source_mean_PE": 19.668569075713705, "background_mean_PE": 1.0, "power": 0.9500000000000001, "tail": 4.519852546965122e-12}2.8421709e-14
102.8665157e-07{"critical": 30, "signal": 29.540972243924358, "power": 0.9500000000000001, "tail": 2.5099512015279526e-07}{"critical": 30, "source_mean_PE": 29.540972243924372, "background_mean_PE": 10.0, "power": 0.95, "tail": 2.509951201527959e-07}1.4210855e-14
107.7160494e-12{"critical": 39, "signal": 39.808463662141904, "power": 0.9500000000000001, "tail": 2.9598814575402454e-12}{"critical": 39, "source_mean_PE": 39.80846366214213, "background_mean_PE": 10.0, "power": 0.9500000000000028, "tail": 2.9598814575402995e-12}2.2737368e-13
10002.8665157e-07{"critical": 1163, "signal": 219.65682567491922, "power": 0.9500000000000111, "tail": 2.6749344185905257e-07}{"critical": 1163, "source_mean_PE": 219.65682567495128, "background_mean_PE": 1000.0, "power": 0.9500000000000016, "tail": 2.674934418591886e-07}3.2059688e-11
10007.7160494e-12{"critical": 1222, "signal": 280.06221661812697, "power": 0.9500000000000106, "tail": 6.339480605104741e-12}{"critical": 1222, "source_mean_PE": 280.06221661811855, "background_mean_PE": 1000.0, "power": 0.9499999999999994, "tail": 6.339480605102249e-12}8.412826e-12
10000002.8665157e-07{"critical": 1005005, "signal": 6654.5330544832395, "power": 0.9500000000931117, "tail": 2.8590760129493844e-07}{"critical": 1005005, "source_mean_PE": 6654.533054276719, "background_mean_PE": 1000000.0, "power": 0.9500000000000056, "tail": 2.859062985845651e-07}2.0652078e-07
10000007.7160494e-12{"critical": 1006752, "signal": 8402.965629891492, "power": 0.9500000000003141, "tail": 7.699419230852799e-12}{"critical": 1006752, "source_mean_PE": 8402.96562969836, "background_mean_PE": 1000000.0, "power": 0.9499999999999954, "tail": 7.699418061156473e-12}1.9313302e-07

12 rows total; 12 shown.

equationfilefunctionline
S01modules/statistics_review.pyphoton_planes199
S02modules/statistics_review.pyphoton_planes199
S03modules/statistics_review.pyonoff_pvalue88
S04modules/statistics_review.pyonoff_pvalue88
S05modules/statistics_review.pycritical_known65
S06modules/statistics_review.pyrequired_signal_known77
S07modules/statistics_review.pyonoff_pvalue88
S07modules/statistics_review.pydirect_onoff_tail94
S08modules/statistics_review.pycount_checks210
S09modules/statistics_review.pysource_upper_known103
S10modules/statistics_review.pysource_upper_known103
S11modules/statistics_review.pysource_upper_off107
S12modules/statistics_review.pysource_upper_off107
S13modules/statistics_review.pyq_integrals131
S13modules/statistics_review.pypoisson_loglik134
S14modules/statistics_review.pynuisance_profile139
S15modules/statistics_review.pynuisance_profile139
S16modules/statistics_review.pynuisance_profile139
S16modules/statistics_review.pyworked_example156
S17modules/statistics_review.pyconfusion_checks272
S18modules/statistics_review.pymc_intervals115
S19modules/statistics_review.pymc_intervals115
S20modules/statistics_review.pyaffinity_bound_values386
S21modules/statistics_review.pyoracle_affinity_controls394

24 rows total; 24 shown.

Cell 24 · statistics-24

Interpretation limits

Expected controls: 2.995732 PE known-zero-background upper limit; 3.688879 PE specified finite-baseline zero/zero bound; 81 scenarios, 81,000 saved pulses and 648 rebuilt metrics. Worked log-likelihood difference tolerance is 2×10−72\times10^{-7}; interval differences must be below 2×10−122\times10^{-12}.