pino-source-code / scripts /analyze_formula.py
mattbitzesty's picture
feat(optimizer): masked MSE, strategy seeds, adversarial IFRA guard; add accords/materials/importer
fd5ba83
Raw
History Blame Contribute Delete
2.72 kB
from __future__ import annotations
"""
Analyze a human parts-based formula with Pino.
This is a small utility for the user-supplied Matthew tea/woods formula. It:
1. Imports the parts-based JSON via pino.importer.
2. Runs the physical/IFRA verifier.
3. Runs the PIMT critic (cloud or local fallback).
4. Prints a compact human-readable summary.
"""
import json
import logging
import sys
from pathlib import Path
from pino.importer import import_formula
from pino.inference_cloud import predict_cloud
from pino.verifier import FragrancePipelineVerifier
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s")
logger = logging.getLogger("pino.analyze_formula")
def analyze(path: str | Path) -> None:
imported = import_formula(path)
if imported["unresolved"]:
logger.warning("Unresolved materials: %s", imported["unresolved"])
formula = imported["formula"]
print(f"Imported formula with {len(formula)} ingredients; sum = {sum(i['weight_fraction'] for i in formula):.6f}")
verifier = FragrancePipelineVerifier(
temperature_k=298.15,
ambient_pressure_pa=101325.0,
headspace_volume_m3=1e-3,
liquid_volume_m3=1e-6,
density_g_ml=0.9,
surface_area_m2=1e-4,
mass_transfer_coefficient=1e-4,
)
result = verifier.run_sim(formula, duration_seconds=8 * 3600.0, interval_seconds=600.0)
print(f"Physical/IFRA status: {result['status']}")
print(f"IFRA passed: {result['ifra_report'].get('passed', False)}")
if not result["ifra_report"].get("passed", False):
print("IFRA violations:", json.dumps(result["ifra_report"].get("violations", []), indent=2))
if result["status"] in ("rejected", "depleted"):
logger.error("Formula rejected by verifier: %s", result.get("message"))
return
formula_payload = {
"formula": formula,
"trajectory": result["trajectory"],
"metadata": {"source": str(path), "analysis": True},
}
prediction = predict_cloud(formula_payload)
print("Prediction keys:", list(prediction.keys()))
print("Objective shape:", len(prediction.get("objective", [[]])[0][0]))
print("Subjective vector:", prediction.get("subjective", [[]])[0])
# Save full analysis
output = {
"imported": imported,
"verification": result,
"prediction": prediction,
}
out_path = Path("data/formulas/matthew_tea_woods_analysis.json")
out_path.write_text(json.dumps(output, indent=2, ensure_ascii=False))
print(f"Full analysis written to {out_path}")
if __name__ == "__main__":
analyze(sys.argv[1] if len(sys.argv) > 1 else "data/formulas/matthew_tea_woods.json")