"""S1-T10: Excel parity gate for the Nagasamudra reference scenario. HOW TO UNLOCK THIS TEST ─────────────────────── 1. Open tests/fixtures/nagasamudra_inputs.json. 2. Replace the solar/wind config values with the actual project inputs. 3. Fill in _expected.solar_y1_mwh and _expected.wind_y1_mwh from the Excel model. 4. Remove the `pytest.skip` call below. The test will then verify that year-1 generation matches Excel within 0.1 % (the sprint parity gate from PROJECT.md). """ import json from pathlib import Path import pytest FIXTURE = Path(__file__).parent.parent / "fixtures" / "nagasamudra_inputs.json" @pytest.mark.skip(reason="Parity gate: awaiting real Nagasamudra data from user (S1-T10)") def test_nagasamudra_solar_y1_parity() -> None: raw = json.loads(FIXTURE.read_text()) expected_mwh = raw["_expected"]["solar_y1_mwh"] assert expected_mwh is not None, "Fill _expected.solar_y1_mwh in fixture" from remodel_engine.generation.solar import simulate_solar from remodel_engine.schemas.generation import SolarConfig cfg = SolarConfig(**raw["solar"]) df = simulate_solar(cfg) actual_mwh = float(df[df["year"] == 1]["ac_power_mw"].sum()) rel_error = abs(actual_mwh - expected_mwh) / expected_mwh assert rel_error <= 0.001, ( f"Solar Y1 parity FAIL: engine={actual_mwh:.1f} MWh, " f"Excel={expected_mwh:.1f} MWh, error={rel_error:.4%}" ) @pytest.mark.skip(reason="Parity gate: awaiting real Nagasamudra data from user (S1-T10)") def test_nagasamudra_wind_y1_parity() -> None: raw = json.loads(FIXTURE.read_text()) expected_mwh = raw["_expected"]["wind_y1_mwh"] assert expected_mwh is not None, "Fill _expected.wind_y1_mwh in fixture" from remodel_engine.generation.wind import simulate_wind from remodel_engine.schemas.generation import WindConfig cfg = WindConfig(**raw["wind"]) df = simulate_wind(cfg) actual_mwh = float(df[df["year"] == 1]["ac_power_mw"].sum()) rel_error = abs(actual_mwh - expected_mwh) / expected_mwh assert rel_error <= 0.001, ( f"Wind Y1 parity FAIL: engine={actual_mwh:.1f} MWh, " f"Excel={expected_mwh:.1f} MWh, error={rel_error:.4%}" )