pino-source-code / tests /test_factory.py
Matthew Ford
Complete catalog recovery and enrichment
83db774
Raw
History Blame Contribute Delete
3.38 kB
from __future__ import annotations
import json
import math
from pathlib import Path
import numpy as np
import pyarrow.parquet as pq
import pytest
PARQUET_PATH = Path(__file__).parent.parent / "data" / "trajectories.parquet"
JSONL_PATH = Path(__file__).parent.parent / "data" / "synthetic_dataset_v2.jsonl"
def verify_drydown(record: dict) -> bool:
"""
Check that a trajectory represents a physically plausible dry-down:
- non-empty trajectory with a finite time span
- final time is near the 8-hour horizon (or film is depleted earlier)
- no negative or NaN mole fractions in the trajectory
"""
traj = record.get("trajectory", [])
if not traj:
return False
if not all(math.isfinite(step["t_s"]) for step in traj):
return False
if traj[0]["t_s"] != pytest.approx(0.0, abs=1.0):
return False
if traj[-1]["t_s"] < 1000.0:
return False
for step in traj:
x_vals = list(step.get("x_liquid", {}).values())
if any(v < -1e-6 or not math.isfinite(v) for v in x_vals):
return False
return True
def verify_stability(record: dict) -> bool:
"""
Check thermodynamic/ODE stability:
- status is 'passed' or 'depleted'
- depletion rates are in [0, 1]
- no NaN/Inf in depletion rates
"""
status = record.get("status", "")
if status not in ("passed", "depleted"):
return False
rates = record.get("depletion_rates", {})
if not rates:
return False
for v in rates.values():
if not math.isfinite(v) or v < -1e-3 or v > 1.0 + 1e-3:
return False
return True
@pytest.fixture(scope="module")
def parquet_records():
if not PARQUET_PATH.exists():
pytest.skip(f"Parquet dataset artifact not found: {PARQUET_PATH}")
table = pq.read_table(PARQUET_PATH)
rows = table.to_pydict()
records = []
for i in range(table.num_rows):
records.append({k: json.loads(rows[k][i]) if k in ("formula", "depletion_rates", "trajectory") else rows[k][i] for k in rows})
return records
def test_parquet_exists_and_has_records():
if not PARQUET_PATH.exists():
pytest.skip(f"Parquet dataset artifact not found: {PARQUET_PATH}")
table = pq.read_table(PARQUET_PATH)
assert table.num_rows >= 5000
def test_parquet_genre_stratification(parquet_records):
strategies = {}
for rec in parquet_records:
strategies[rec["generation_strategy"]] = strategies.get(rec["generation_strategy"], 0) + 1
expected_genres = {"citrus_cologne", "fougere", "floral_woody", "amber_oriental", "wildcard"}
assert expected_genres.issubset(strategies.keys())
for genre in expected_genres:
assert strategies[genre] >= 900, f"Genre {genre} under-represented: {strategies[genre]}"
def test_verify_drydown_all_records(parquet_records):
failures = []
for rec in parquet_records:
if not verify_drydown(rec):
failures.append(rec["formula_id"])
assert not failures, f"verify_drydown failed for {len(failures)} records: {failures[:10]}"
def test_verify_stability_all_records(parquet_records):
failures = []
for rec in parquet_records:
if not verify_stability(rec):
failures.append(rec["formula_id"])
assert not failures, f"verify_stability failed for {len(failures)} records: {failures[:10]}"