# CEA light-design calculations

Version 1.0.0. Synthetic data, no fitted plant response, randomness, network,
or file writes. Python >= 3.10; standard library only. License unspecified.

Save experiment.py and expected.json in the same directory:

    python3 experiment.py
    python3 experiment.py --verify expected.json
    python3 experiment.py --self-test

All schedules cover a fixed 24-hour day with contiguous ordered intervals
containing constant (or interval-average) PPFD in umol/(m2 s). Hours must
use the same time basis. DST days and sampled instantaneous-light
interpolation are outside scope. Zero PPFD explicitly represents darkness.
light_hours sums positive-PPFD intervals; it does not infer photoperiod or
distinguish interrupted exposure without the original schedule.

Spatial values represent defined cells, not unqualified point samples.
Each cell has positive area; relative area weights are sufficient. The
example uses equal cells at a fixed plane and constant 16-hour exposure.
Minimum/mean is descriptive, not a crop acceptance criterion. A zero mean
returns null. Values are incident light, not absorbed light or floor-to-leaf
conversion. The spectrum example sums three nonoverlapping photon bands:
400 <= wavelength < 500, 500 <= wavelength < 600, 600 <= wavelength <= 700 nm.
This is a bookkeeping convention, not a sensor-response simulation.

Change calls in examples(). Preserve complete day coverage when changing
switching times. The expected file remains the original baseline, so
changed examples should fail verification. Tolerances: absolute/relative
1e-10. Missing fields, invalid numbers, changed values and list lengths fail.

manifest.json records sizes and SHA-256 of code, expected JSON and this
README; it is an integrity record, not a signature. The bilingual article
contains references and limitations. No crop, yield, electricity or fixture
performance is predicted by the code.
