"""P4-M5: L0 pre-screening promoted to shared core (single implementation). Run: python scripts/test_p4_m5_l0.py (exit 0 = PASS) Verifies: 1. The single implementation lives at src/afmcore/l0/prescreening.py. 2. The web re-export references the same classes (no drift). 3. Core behavior is unchanged: geometric/electrical/thermal/manufacturing checks, evaluate(), filter_feasible(), empty-input gate. 4. Consumers (feasibility_search) still work through the re-export. """ import os import sys _ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) _BACKEND = os.path.join(_ROOT, "web", "backend") sys.path.insert(0, _BACKEND) sys.path.insert(0, _ROOT) from src.afmcore.l0.prescreening import ( # noqa: E402 L0PreScreeningEngine as SrcEngine, FeasibilityReport, ConstraintResult, ) from app.services.l0_prescreening import L0PreScreeningEngine as WebEngine # noqa: E402 # 1) single definition, no drift assert SrcEngine is WebEngine, "re-export must point at the same class" assert SrcEngine.__module__ == "src.afmcore.l0.prescreening" print("[1] single implementation in shared core OK (%s)" % SrcEngine.__module__) eng = SrcEngine() # 2) geometric: valid vs invalid diameter ratio r = eng.evaluate({"outer_diameter_mm": 150, "inner_diameter_mm": 80}) assert r.feasible r_bad = eng.evaluate({"outer_diameter_mm": 150, "inner_diameter_mm": 10}) assert not r_bad.feasible # ratio 0.067 < 0.2 print("[2] geometric diameter-ratio gate OK") # 3) electrical: current density limit r = eng.evaluate({"current_a": 10, "conductor_area_mm2": 2.0}) # 5 A/mm2 assert r.feasible r2 = eng.evaluate({"current_a": 100, "conductor_area_mm2": 2.0}) # 50 A/mm2 assert not r2.feasible print("[3] electrical current-density gate OK") # 4) thermal: winding temp limit r = eng.evaluate({"winding_temp_c": 120}) # below 150 assert r.feasible r2 = eng.evaluate({"winding_temp_c": 160}) # above 150 assert not r2.feasible print("[4] thermal winding-temp gate OK") # 5) manufacturing: PCB line width r = eng.evaluate({"pcb_line_width_mm": 0.5}) assert r.feasible r2 = eng.evaluate({"pcb_line_width_mm": 0.05}) assert not r2.feasible print("[5] manufacturing PCB line-width gate OK") # 6) empty input -> infeasible with UNKNOWN risk item (C3 gate) r = eng.evaluate({}) assert not r.feasible assert any("[UNKNOWN]" in x for x in r.risk_items) print("[6] empty-input gate OK") # 7) filter_feasible splits sets sets = [ {"outer_diameter_mm": 150, "inner_diameter_mm": 80}, {"outer_diameter_mm": 150, "inner_diameter_mm": 10}, ] feas, infeas = eng.filter_feasible(sets) assert len(feas) == 1 and len(infeas) == 1 print("[7] filter_feasible split OK") # 8) consumers still work through the re-export from app.services.feasibility_search import ( # noqa: E402 FeasibilityFirstSearch, ParameterRange, ) search = FeasibilityFirstSearch( parameters=[ParameterRange(name="outer_diameter_mm", min_value=100, max_value=300), ParameterRange(name="inner_diameter_mm", min_value=50, max_value=150)], l0_engine=WebEngine(), total_budget=20, batch_size=4, initial_samples=6, objective_metric="tavg_nm", objective_direction="maximize", seed=1, ) ini = search.generate_initial_batch() assert len(ini) > 0 print("[8] feasibility_search L0 integration OK (%d initial pts)" % len(ini)) print("\nALL P4-M5 L0 PROMOTION TESTS PASSED")