Spaces:
Sleeping
Sleeping
| """Tests for experimental observable lookups and model validation.""" | |
| from kingdom.core.experimental_data import ( | |
| allen_electronegativity, | |
| calculate_comparison_fidelity, | |
| compare_atomic_radius, | |
| compare_electronegativity, | |
| estimate_model_covalent_radius_pm, | |
| estimate_model_electronegativity_allen, | |
| compare_ionization_energy_relative, | |
| compare_to_experiment, | |
| covalent_radius_pm, | |
| experimental_magnetic_moment, | |
| magnetic_moment_validation, | |
| observable_match_score, | |
| ) | |
| from kingdom.core.flux_explorer import explore_flux_element_extended | |
| from kingdom.core.flux_explorer import build_observables_table, build_observables_validation | |
| from kingdom.core.flux_flywheel import map_z_to_flywheel_extended | |
| def test_compare_to_experiment_iron_magnetic_moment(): | |
| result = compare_to_experiment(26, 6.71, "magnetic_moment") | |
| assert result["available"] is True | |
| assert result["experimental_value"] == 6.71 | |
| assert result["source"] == "NIST ASD / atomic beam" | |
| assert result["quality"] == "Direct measurement" | |
| assert result["delta"] == 0.0 | |
| assert result["within_range"] is True | |
| def test_compare_to_experiment_missing_data(): | |
| result = compare_to_experiment(50, 3.0, "magnetic_moment") | |
| assert result["available"] is False | |
| assert result["experimental_value"] is None | |
| assert result["quality"] == "No experimental data" | |
| def test_experimental_magnetic_moment_iron(): | |
| entry = experimental_magnetic_moment(26) | |
| assert entry is not None | |
| assert entry["low"] == 6.0 | |
| assert entry["high"] == 6.8 | |
| def test_fe_soc_matches_experimental_range(): | |
| result = map_z_to_flywheel_extended(26) | |
| assert result["magnetic_moment_exp_available"] is True | |
| assert result["mu_within_exp_range"] is True | |
| assert result["mu_validation_score"] == 10.0 | |
| assert abs(result["mu_delta_soc_vs_exp_BM"]) < 0.05 | |
| def test_fe_soc_closer_to_exp_than_spin_only(): | |
| result = map_z_to_flywheel_extended(26) | |
| assert abs(result["mu_delta_soc_vs_exp_BM"]) < abs(result["mu_delta_spin_vs_exp_BM"]) | |
| def test_helium_experimental_zero(): | |
| result = map_z_to_flywheel_extended(2) | |
| assert result["magnetic_moment_exp_available"] is True | |
| assert result["magnetic_moment_exp_BM"] == 0.0 | |
| assert result["mu_validation_score"] == 10.0 | |
| def test_unknown_z_no_experimental_mu(): | |
| result = magnetic_moment_validation(spin_only_bm=2.8, soc_bm=3.0, z=50) | |
| assert result["magnetic_moment_exp_available"] is False | |
| assert result["mu_validation_score"] is None | |
| def test_observable_match_score_in_range(): | |
| assert observable_match_score(6.71, 26, "magnetic_moment") == 10.0 | |
| def test_build_observables_validation_iron(): | |
| extended = map_z_to_flywheel_extended(26) | |
| validation = build_observables_validation(26, extended) | |
| rows = validation["rows"] | |
| assert len(rows) == 5 | |
| mu_row = rows[0] | |
| assert mu_row["category"] == "Magnetic Moment" | |
| assert mu_row["model_spin_only"] == "4.90 BM" | |
| assert "g_J=1.5" in mu_row["model_soc"] | |
| assert mu_row["delta"] == "+0.00 BM" | |
| assert rows[2]["category"] == "Electron Affinity" | |
| assert rows[3]["category"] == "Atomic Radius (Covalent)" | |
| assert "132 pm" in rows[3]["experimental"] | |
| assert "pm" in rows[3]["model_spin_only"] | |
| assert rows[3]["delta"].endswith("pm") | |
| assert rows[4]["category"] == "Electronegativity (Allen)" | |
| assert "Δz" in rows[4]["delta"] | |
| assert "Period-relative" in rows[4]["source"] | |
| assert validation["fidelity_score"] is not None | |
| assert "magnetic_moment" in validation["fidelity_details"] | |
| assert "electronegativity" in validation["fidelity_details"] | |
| def test_build_observables_table_backward_compat(): | |
| extended = map_z_to_flywheel_extended(26) | |
| assert len(build_observables_table(26, extended)) == 5 | |
| def test_compare_atomic_radius_iron(): | |
| result = compare_atomic_radius(26, 5.5) | |
| assert result["available"] is True | |
| assert result["experimental_value"] == 132 | |
| assert result["model_value"] == estimate_model_covalent_radius_pm(5.5, 26) | |
| assert result["delta"] == round(result["model_value"] - 132, 1) | |
| assert "Cordero" in result["source"] | |
| def test_estimate_model_covalent_radius_pm_bounds(): | |
| r = estimate_model_covalent_radius_pm(8.0, 2) | |
| assert 40 <= r <= 220 | |
| assert estimate_model_covalent_radius_pm(5.0, 29) > 0 | |
| def test_estimate_model_covalent_radius_pm_iron_closer_to_experiment(): | |
| model = estimate_model_covalent_radius_pm(5.5, 26) | |
| assert 110 <= model <= 140 | |
| assert abs(model - 132) < 20 | |
| def test_covalent_radius_fallback(): | |
| assert covalent_radius_pm(26) == 132.0 | |
| assert covalent_radius_pm(50) > 0 | |
| def test_calculate_comparison_fidelity_iron(): | |
| extended = map_z_to_flywheel_extended(26) | |
| validation = build_observables_validation(26, extended) | |
| fidelity = calculate_comparison_fidelity(validation["comparisons"], z=26) | |
| assert fidelity["score"] is not None | |
| assert fidelity["overall_fidelity"] == fidelity["score"] | |
| assert fidelity["details"]["magnetic_moment"] == 10.0 | |
| assert fidelity["core_model_fidelity"] is not None | |
| assert "Electronic" in fidelity["category_scores"] | |
| assert fidelity["proxy_quality"]["ionization_energy"]["level"] == "high" | |
| assert fidelity["score"] >= 4.0 | |
| def test_layered_fidelity_xenon(): | |
| extended = map_z_to_flywheel_extended(54) | |
| validation = build_observables_validation(54, extended) | |
| fidelity = calculate_comparison_fidelity(validation["comparisons"], z=54) | |
| assert fidelity["score"] is not None | |
| assert fidelity["score"] >= 7.5 | |
| assert fidelity["core_model_fidelity"] == 8.7 | |
| assert fidelity["category_scores"]["Structural"] == 10.0 | |
| assert fidelity["category_scores"]["Electronic"] >= 7.0 | |
| assert fidelity["category_scores"]["Magnetic"] is None | |
| en_detail = fidelity["details"]["electronegativity"] | |
| assert en_detail >= 4.0 | |
| assert "EN" in " ".join(fidelity["category_details"]["Electronic"]) | |
| assert fidelity["proxy_quality"]["electronegativity"]["level"] == "low" | |
| assert fidelity["proxy_quality"]["magnetic_moment"]["level"] == "none" | |
| def test_build_key_takeaways_xenon(): | |
| from kingdom.core.experimental_data import build_key_takeaways | |
| extended = map_z_to_flywheel_extended(54) | |
| validation = build_observables_validation(54, extended) | |
| takeaways = build_key_takeaways( | |
| 54, | |
| comparisons=validation["comparisons"], | |
| fidelity_details=validation["fidelity_details"], | |
| category_scores=validation.get("fidelity_category_scores"), | |
| proxy_quality=validation.get("fidelity_proxy_quality"), | |
| core_model_fidelity=validation.get("fidelity_core_score"), | |
| overall_fidelity=validation.get("fidelity_score"), | |
| is_noble_gas=True, | |
| noble_gas_stability_bonus=float(extended.get("noble_gas_stability_bonus") or 0), | |
| ) | |
| assert len(takeaways) >= 3 | |
| texts = " ".join(t["text"] for t in takeaways).lower() | |
| assert any(t["kind"] == "positive" for t in takeaways) | |
| assert any(t["kind"] == "caveat" for t in takeaways) | |
| assert "structural" in texts or "electronic" in texts | |
| assert "electronegativity" in texts or "magnetic" in texts | |
| def test_build_model_insights_xenon(): | |
| from kingdom.core.experimental_data import build_model_insights | |
| extended = map_z_to_flywheel_extended(54) | |
| validation = build_observables_validation(54, extended) | |
| insights = build_model_insights( | |
| 54, | |
| comparisons=validation["comparisons"], | |
| fidelity_details=validation["fidelity_details"], | |
| category_scores=validation.get("fidelity_category_scores"), | |
| proxy_quality=validation.get("fidelity_proxy_quality"), | |
| core_model_fidelity=validation.get("fidelity_core_score"), | |
| overall_fidelity=validation.get("fidelity_score"), | |
| is_noble_gas=True, | |
| noble_gas_stability_bonus=float(extended.get("noble_gas_stability_bonus") or 0), | |
| ) | |
| assert len(insights["strengths"]) >= 2 | |
| assert len(insights["limitations"]) >= 1 | |
| assert any("structural" in s.lower() or "radius" in s.lower() for s in insights["strengths"]) | |
| assert any("electronegativity" in lim.lower() for lim in insights["limitations"]) | |
| def test_compare_ionization_energy_relative_iron(): | |
| result = compare_ionization_energy_relative(26, 5.5) | |
| assert result["available"] is True | |
| assert result["comparison_mode"] == "period_relative" | |
| assert result["experimental_value"] == 7.90 | |
| assert result["score"] is not None | |
| assert result["score"] >= 4.0 | |
| assert abs(result["delta"]) < 2.0 | |
| def test_iron_fidelity_improved_with_relative_ie(): | |
| payload = explore_flux_element_extended(26) | |
| score = payload["flywheel"]["comparison_fidelity_score"] | |
| ie_detail = payload["flywheel"]["comparison_fidelity_details"]["ionization_energy"] | |
| assert score is not None | |
| assert ie_detail >= 4.0 | |
| assert score > 5.0 | |
| def test_build_observables_ie_row_uses_period_relative(): | |
| extended = map_z_to_flywheel_extended(26) | |
| ie_row = build_observables_validation(26, extended)["rows"][1] | |
| assert ie_row["category"] == "Ionization Energy" | |
| assert "stab z" in ie_row["model_spin_only"] | |
| assert "Δz" in ie_row["delta"] | |
| assert "Period-relative" in ie_row["source"] | |
| def test_allen_electronegativity_noble_gas_neon(): | |
| assert allen_electronegativity(10) == 4.787 | |
| assert allen_electronegativity(2) == 4.16 | |
| def test_estimate_model_electronegativity_allen_bounds(): | |
| en = estimate_model_electronegativity_allen(5.5, 26) | |
| assert 0.8 <= en <= 4.8 | |
| xe_en = estimate_model_electronegativity_allen(6.0, 54) | |
| assert 2.4 <= xe_en <= 2.6 | |
| def test_compare_electronegativity_iron(): | |
| result = compare_electronegativity(26, 5.5) | |
| assert result["available"] is True | |
| assert result["comparison_mode"] == "period_relative" | |
| assert result["experimental_value"] == 1.628 | |
| assert result["model_value"] is not None | |
| assert result["score"] is not None | |
| assert result["delta"] is not None | |
| def test_fidelity_data_coverage(): | |
| from kingdom.core.experimental_data import fidelity_data_coverage | |
| extended = map_z_to_flywheel_extended(54) | |
| validation = build_observables_validation(54, extended) | |
| cov = fidelity_data_coverage(validation["comparisons"]) | |
| assert cov["total"] == 5 | |
| assert cov["available"] >= 3 | |
| assert "Magnetic Moment" in cov["missing"] | |
| def test_interpret_comparison_fidelity_xenon(): | |
| from kingdom.core.experimental_data import interpret_comparison_fidelity | |
| extended = map_z_to_flywheel_extended(54) | |
| validation = build_observables_validation(54, extended) | |
| interp = interpret_comparison_fidelity( | |
| 54, | |
| fidelity_score=validation["fidelity_score"], | |
| fidelity_details=validation["fidelity_details"], | |
| comparisons=validation["comparisons"], | |
| stability_score=extended["stability_score"], | |
| is_noble_gas=True, | |
| core_model_fidelity=validation.get("fidelity_core_score"), | |
| category_scores=validation.get("fidelity_category_scores"), | |
| ) | |
| assert interp["coverage"]["label"].startswith("3/") | |
| assert interp["model_limitation"] == "noble_gas" | |
| assert interp["fidelity_tier"] in ("solid", "excellent") | |
| assert "agreement" in interp["summary"].lower() | |
| assert any("Electronegativity" in n for n in interp.get("notes", [])) | |
| assert validation.get("fidelity_core_score") == 8.7 | |
| assert validation["fidelity_category_scores"]["Structural"] == 10.0 | |
| def test_compare_electronegativity_neon_high_allen(): | |
| extended = map_z_to_flywheel_extended(10) | |
| result = compare_electronegativity(10, extended["stability_score"]) | |
| assert result["available"] is True | |
| assert result["experimental_value"] == 4.787 | |
| assert result["score"] is not None |